[Java-gnome-developer] Create a custom GTK RoundedFrame in Java Gnome
Brought to you by:
afcowie
|
From: bob <loi...@pa...> - 2010-10-20 14:35:15
|
When I'm reading the banshee source (C# language), I found how to create
a custom component in C#. It's very simple, the developer had to extend
the Gtk.Bin Object.
I search to do the same thing in Java but I don't found any "simple"
solution, we couldn't extends the Bin object.
I think it is possible to create this component in C and create binding
like all object in java-gnome but it's not very simple (add C code and
add Java binding working with java-gnome).
There is a solution to create a custom widget in Java ? Could you update
the java-gnome library to do it ?
//
// The custom GTK widget RoundedFrame
//
namespace Hyena.Widgets
{
public class RoundedFrame : Bin
{
private Theme theme;
protected Theme Theme {
get { return theme; }
}
private Widget child;
private Gdk.Rectangle child_allocation;
private bool fill_color_set;
private Cairo.Color fill_color;
private bool draw_border = true;
private Pattern fill_pattern;
private int frame_width;
// Ugh, this is to avoid the GLib.MissingIntPtrCtorException
seen by some; BGO #552169
protected RoundedFrame (IntPtr ptr) : base (ptr)
{
}
public RoundedFrame ()
{
}
public void SetFillColor (Cairo.Color color)
{
fill_color = color;
fill_color_set = true;
QueueDraw ();
}
public void UnsetFillColor ()
{
fill_color_set = false;
QueueDraw ();
}
public Pattern FillPattern {
get { return fill_pattern; }
set {
fill_pattern = value;
QueueDraw ();
}
}
public bool DrawBorder {
get { return draw_border; }
set { draw_border = value; QueueDraw (); }
}
#region Gtk.Widget Overrides
protected override void OnStyleSet (Style previous_style)
{
base.OnStyleSet (previous_style);
theme = Hyena.Gui.Theming.ThemeEngine.CreateTheme (this);
frame_width = (int)theme.Context.Radius + 1;
}
protected override void OnSizeRequested (ref Requisition
requisition)
{
if (child != null && child.Visible) {
// Add the child's width/height
Requisition child_requisition = child.SizeRequest ();
requisition.Width = Math.Max (0,
child_requisition.Width);
requisition.Height = child_requisition.Height;
} else {
requisition.Width = 0;
requisition.Height = 0;
}
// Add the frame border
requisition.Width += ((int)BorderWidth + frame_width) * 2;
requisition.Height += ((int)BorderWidth + frame_width) * 2;
}
protected override void OnSizeAllocated (Gdk.Rectangle
allocation)
{
base.OnSizeAllocated (allocation);
child_allocation = new Gdk.Rectangle ();
if (child == null || !child.Visible) {
return;
}
child_allocation.X = (int)BorderWidth + frame_width;
child_allocation.Y = (int)BorderWidth + frame_width;
child_allocation.Width = (int)Math.Max (1, Allocation.Width
- child_allocation.X * 2);
child_allocation.Height = (int)Math.Max (1,
Allocation.Height - child_allocation.Y -
(int)BorderWidth - frame_width);
child_allocation.X += Allocation.X;
child_allocation.Y += Allocation.Y;
child.SizeAllocate (child_allocation);
}
protected override void OnSetScrollAdjustments (Adjustment hadj,
Adjustment vadj)
{
// This is to satisfy the gtk_widget_set_scroll_adjustments
// inside of GtkScrolledWindow so it doesn't complain about
// its child not being scrollable.
}
protected override bool OnExposeEvent (Gdk.EventExpose evnt)
{
if (!IsDrawable) {
return false;
}
Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window);
try {
DrawFrame (cr, evnt.Area);
if (child != null) {
PropagateExpose (child, evnt);
}
return false;
} finally {
CairoExtensions.DisposeContext (cr);
}
}
private void DrawFrame (Cairo.Context cr, Gdk.Rectangle clip)
{
int x = child_allocation.X - frame_width;
int y = child_allocation.Y - frame_width;
int width = child_allocation.Width + 2 * frame_width;
int height = child_allocation.Height + 2 * frame_width;
Gdk.Rectangle rect = new Gdk.Rectangle (x, y, width,
height);
theme.Context.ShowStroke = draw_border;
if (fill_color_set) {
theme.DrawFrameBackground (cr, rect, fill_color);
} else if (fill_pattern != null) {
theme.DrawFrameBackground (cr, rect, fill_pattern);
} else {
theme.DrawFrameBackground (cr, rect, true);
theme.DrawFrameBorder (cr, rect);
}
}
#endregion
#region Gtk.Container Overrides
protected override void OnAdded (Widget widget)
{
child = widget;
base.OnAdded (widget);
}
protected override void OnRemoved (Widget widget)
{
if (child == widget) {
child = null;
}
base.OnRemoved (widget);
}
#endregion
}
}
|