Marshal arguments into a DrawContext structure
All Draw methods now take a single argument, DrawContext. This structure contains properties for all possible Draw methods. Only properties valid to the current Draw method will be set to non-default values.
This commit is contained in:
Родитель
0cd59b45d0
Коммит
2ba270e4c1
|
@ -40,5 +40,6 @@
|
|||
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
<Reference Include="Mono.Cairo" />
|
||||
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
<Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -31,22 +31,44 @@ using Cairo;
|
|||
|
||||
namespace Maigre
|
||||
{
|
||||
public struct DrawContext
|
||||
{
|
||||
public string Method { get; private set; }
|
||||
public Gtk.Style Style { get; private set; }
|
||||
public Gdk.Window Window { get; private set; }
|
||||
public Gtk.StateType StateType { get; private set; }
|
||||
public Gtk.ShadowType ShadowType { get; private set; }
|
||||
public Gdk.Rectangle Area { get; private set; }
|
||||
public Gtk.Widget Widget { get; private set; }
|
||||
public string Detail { get; private set; }
|
||||
public int X { get; private set; }
|
||||
public int Y { get; private set; }
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
public Gtk.Orientation Orientation { get; private set; }
|
||||
public Gtk.ExpanderStyle ExpanderStyle { get; private set; }
|
||||
public Pango.Layout Layout { get; private set; }
|
||||
public bool UseText { get; private set; }
|
||||
public Gdk.WindowEdge Edge { get; private set; }
|
||||
public int Step { get; private set; }
|
||||
public int X1 { get; private set; }
|
||||
public int X2 { get; private set; }
|
||||
public int Y1 { get; private set; }
|
||||
public int Y2 { get; private set; }
|
||||
public bool Fill { get; private set; }
|
||||
public Gtk.ArrowType ArrowType { get; private set; }
|
||||
}
|
||||
|
||||
public static class Theme
|
||||
{
|
||||
public static void DrawBox (Gtk.Style style, Gdk.Window window,
|
||||
StateType state_type, ShadowType shadow_type, Gdk.Rectangle area, Widget widget,
|
||||
string detail, int x, int y, int width, int height)
|
||||
public static void DrawBox (DrawContext context)
|
||||
{
|
||||
var cr = Gdk.CairoHelper.Create (widget.GdkWindow);
|
||||
switch (detail) {
|
||||
case "hscrollbar":
|
||||
case "vscrollbar": cr.Color = new Cairo.Color (1, 0, 0); break;
|
||||
case "slider": cr.Color = new Cairo.Color (0, 1, 0); break;
|
||||
case "trough": cr.Color = new Cairo.Color (0, 0, 1); break;
|
||||
Console.WriteLine ("{0}:{1} ({2})", context.Method, context.Detail, context.Area);
|
||||
using (var cr = Gdk.CairoHelper.Create (context.Window)) {
|
||||
cr.Color = new Cairo.Color (0, 1, 1);
|
||||
cr.Rectangle (context.X, context.Y, context.Width, context.Height);
|
||||
cr.Fill ();
|
||||
}
|
||||
cr.Rectangle (x, y, width, height);
|
||||
cr.Fill ();
|
||||
((IDisposable)cr).Dispose ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ for word in open ('/usr/include/gtk-2.0/gtk/gtkstyle.h').read ().split ():
|
|||
elif arg_type == 'const':
|
||||
arg_type = 'const %s' % word
|
||||
else:
|
||||
methods[-1].append ((arg_type, word))
|
||||
methods[-1].append ((arg_type, word.replace ('_', '')))
|
||||
arg_type = None
|
||||
if end:
|
||||
vmethod = None
|
||||
|
@ -57,6 +57,11 @@ for method in methods:
|
|||
line_count = 0
|
||||
arg_index = 0
|
||||
arg_count = len (method[1:])
|
||||
args = method[1:]
|
||||
arg_names = []
|
||||
for arg in args:
|
||||
arg_names.append (arg[1])
|
||||
|
||||
out.write ('static void\n')
|
||||
line = 'maigre_style_%s (' % method[0]
|
||||
for arg in method[1:]:
|
||||
|
@ -75,43 +80,66 @@ for method in methods:
|
|||
out.write ('''{
|
||||
MaigreMonoBridge *bridge;
|
||||
MonoMethod *managed_method;
|
||||
gpointer args[1];
|
||||
|
||||
''')
|
||||
|
||||
if 'shadowtype' not in arg_names:
|
||||
out.write (' GtkShadowType shadowtype = GTK_SHADOW_NONE;\n')
|
||||
if 'x' not in arg_names:
|
||||
out.write (' gint x = 0;\n')
|
||||
if 'y' not in arg_names:
|
||||
out.write (' gint y = 0;\n')
|
||||
if 'width' not in arg_names:
|
||||
out.write (' gint width = 0;\n')
|
||||
if 'height' not in arg_names:
|
||||
out.write (' gint height = 0;\n')
|
||||
if 'orientation' not in arg_names:
|
||||
out.write (' GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL;\n')
|
||||
if 'expander_style' not in arg_names:
|
||||
out.write (' GtkExpanderStyle expander_style = GTK_EXPANDER_COLLAPSED;\n')
|
||||
if '*layout' not in arg_names:
|
||||
out.write (' PangoLayout *layout = NULL;\n')
|
||||
if 'use_text' not in arg_names:
|
||||
out.write (' gboolean use_text = FALSE;\n')
|
||||
if 'edge' not in arg_names:
|
||||
out.write (' GdkWindowEdge edge = GDK_WINDOW_EDGE_NORTH_WEST;\n')
|
||||
if 'step' not in arg_names:
|
||||
out.write (' gint step = 0;\n')
|
||||
if 'x1' not in arg_names:
|
||||
out.write (' gint x1 = 0;\n')
|
||||
if 'x2' not in arg_names:
|
||||
out.write (' gint x2 = 0;\n')
|
||||
if 'y1' not in arg_names:
|
||||
out.write (' gint y1 = 0;\n')
|
||||
if 'y2' not in arg_names:
|
||||
out.write (' gint y2 = 0;\n')
|
||||
if 'fill' not in arg_names:
|
||||
out.write (' gboolean fill = FALSE;\n')
|
||||
if 'arrow_type' not in arg_names:
|
||||
out.write (' GtkArrowType arrow_type = GTK_ARROW_UP;\n')
|
||||
|
||||
out.write ('''
|
||||
bridge = maigre_mono_bridge ();
|
||||
|
||||
if (!bridge->assemblies_loaded ||
|
||||
(managed_method = maigre_style_method_map[%d].managed_method) == NULL) {
|
||||
return;
|
||||
}
|
||||
''' % method_index)
|
||||
|
||||
{
|
||||
gpointer args[%d] = {
|
||||
''' \
|
||||
% (method_index, len (method[1:])))
|
||||
arg_index = 0
|
||||
for arg in method[1:]:
|
||||
assign = ''
|
||||
if arg[1][0] == '*':
|
||||
if arg[0] == 'GdkRectangle':
|
||||
assign = 'maigre_gdk_rectangle_new (bridge, %s)' % arg[1][1:]
|
||||
elif arg[0] == 'const gchar':
|
||||
assign = 'mono_string_new (bridge->domain, %s)' % arg[1][1:]
|
||||
else:
|
||||
assign = 'maigre_gobject_new (bridge, %s)' % arg[1][1:]
|
||||
else:
|
||||
assign = '&%s' % arg[1]
|
||||
if arg_index < arg_count - 1:
|
||||
out.write (' %s,\n' % assign)
|
||||
else:
|
||||
out.write (' %s\n' % assign)
|
||||
arg_index += 1
|
||||
method_index += 1
|
||||
out.write (''' };
|
||||
out.write ('''
|
||||
args[0] = maigre_draw_context_new (bridge, "%s",
|
||||
style, window, statetype, shadowtype, area,
|
||||
widget, detail, x, y, width, height, orientation,
|
||||
expander_style, layout, use_text, edge, step,
|
||||
x1, x2, y1, y2, fill, arrow_type);
|
||||
|
||||
mono_runtime_invoke (managed_method, NULL, args, NULL);
|
||||
}
|
||||
mono_runtime_invoke (managed_method, NULL, args, NULL);
|
||||
}
|
||||
|
||||
''')
|
||||
''' % method[0])
|
||||
|
||||
out.write ('''
|
||||
static void
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "maigre-mono-bridge.h"
|
||||
|
||||
|
@ -71,6 +71,61 @@ maigre_mono_bridge_mono_assembly_loaded (MonoAssembly *assembly, MaigreMonoBridg
|
|||
bridge->glib_getobject != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
maigre_mono_bridge_load_draw_context (MaigreMonoBridge *bridge)
|
||||
{
|
||||
// NOTE: these names must be in the same order as their
|
||||
// corresponding members in the MaigreMonoDrawContext struct
|
||||
static const gchar *names [] = {
|
||||
"<Method>k__BackingField",
|
||||
"<Style>k__BackingField",
|
||||
"<Window>k__BackingField",
|
||||
"<StateType>k__BackingField",
|
||||
"<ShadowType>k__BackingField",
|
||||
"<Area>k__BackingField",
|
||||
"<Widget>k__BackingField",
|
||||
"<Detail>k__BackingField",
|
||||
"<X>k__BackingField",
|
||||
"<Y>k__BackingField",
|
||||
"<Width>k__BackingField",
|
||||
"<Height>k__BackingField",
|
||||
"<Orientation>k__BackingField",
|
||||
"<ExpanderStyle>k__BackingField",
|
||||
"<Layout>k__BackingField",
|
||||
"<UseText>k__BackingField",
|
||||
"<Edge>k__BackingField",
|
||||
"<Step>k__BackingField",
|
||||
"<X1>k__BackingField",
|
||||
"<X2>k__BackingField",
|
||||
"<Y1>k__BackingField",
|
||||
"<Y2>k__BackingField",
|
||||
"<Fill>k__BackingField",
|
||||
"<ArrowType>k__BackingField",
|
||||
NULL
|
||||
};
|
||||
|
||||
MonoClass *klass;
|
||||
gint i;
|
||||
|
||||
if ((bridge->draw_context.klass = mono_class_from_name (
|
||||
bridge->image, "Maigre", "DrawContext")) == NULL) {
|
||||
g_warning ("Maigre.dll assembly does not contain Maigre.DrawContext");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
klass = bridge->draw_context.klass;
|
||||
|
||||
for (i = 0; names[i] != NULL; i++) {
|
||||
MonoClassField **slot = G_STRUCT_MEMBER_P (&bridge->draw_context, i * sizeof (gpointer));
|
||||
if ((*slot = mono_class_get_field_from_name (klass, names[i])) == NULL) {
|
||||
g_warning ("Maigre.DrawContext does not have a %s field.", names[i]);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MaigreMonoBridge *
|
||||
maigre_mono_bridge ()
|
||||
{
|
||||
|
@ -106,7 +161,7 @@ maigre_mono_bridge ()
|
|||
return bridge;
|
||||
}
|
||||
|
||||
bridge->init_success = TRUE;
|
||||
bridge->init_success = maigre_mono_bridge_load_draw_context (bridge);
|
||||
|
||||
return bridge;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,36 @@
|
|||
#include <mono/metadata/object.h>
|
||||
#include <mono/metadata/debug-helpers.h>
|
||||
|
||||
// NOTE: this structure must reflect the fields
|
||||
// in the Maigre.DrawContext managed structure
|
||||
typedef struct MaigreMonoDrawContext {
|
||||
MonoClassField *method;
|
||||
MonoClassField *style;
|
||||
MonoClassField *window;
|
||||
MonoClassField *state_type;
|
||||
MonoClassField *shadow_type;
|
||||
MonoClassField *area;
|
||||
MonoClassField *widget;
|
||||
MonoClassField *detail;
|
||||
MonoClassField *x;
|
||||
MonoClassField *y;
|
||||
MonoClassField *width;
|
||||
MonoClassField *height;
|
||||
MonoClassField *orientation;
|
||||
MonoClassField *expander_style;
|
||||
MonoClassField *layout;
|
||||
MonoClassField *use_text;
|
||||
MonoClassField *edge;
|
||||
MonoClassField *step;
|
||||
MonoClassField *x1;
|
||||
MonoClassField *x2;
|
||||
MonoClassField *y1;
|
||||
MonoClassField *y2;
|
||||
MonoClassField *fill;
|
||||
MonoClassField *arrow_type;
|
||||
MonoClass *klass;
|
||||
} MaigreMonoDrawContext;
|
||||
|
||||
typedef struct MaigreMonoBridge {
|
||||
gboolean init_success;
|
||||
gboolean assemblies_loaded;
|
||||
|
@ -48,6 +78,8 @@ typedef struct MaigreMonoBridge {
|
|||
|
||||
MonoMethod *gdk_rectangle_ctor;
|
||||
MonoMethod *glib_getobject;
|
||||
|
||||
MaigreMonoDrawContext draw_context;
|
||||
} MaigreMonoBridge;
|
||||
|
||||
MaigreMonoBridge *maigre_mono_bridge ();
|
||||
|
|
|
@ -27,6 +27,74 @@
|
|||
#include "maigre-style.h"
|
||||
#include "maigre-mono-bridge.h"
|
||||
|
||||
static MonoObject *
|
||||
maigre_draw_context_new (MaigreMonoBridge *bridge, const gchar *method,
|
||||
GtkStyle *style, GdkWindow *window, GtkStateType state_type,
|
||||
GtkShadowType shadow_type, GdkRectangle *area, GtkWidget *widget,
|
||||
const gchar *detail, gint x, gint y, gint width, gint height,
|
||||
GtkOrientation orientation, GtkExpanderStyle expander_style,
|
||||
PangoLayout *layout, gboolean use_text, GdkWindowEdge edge, gint step,
|
||||
gint x1, gint x2, gint y1, gint y2, gboolean fill, GtkArrowType arrow_type)
|
||||
{
|
||||
MonoObject *context = mono_object_new (bridge->domain, bridge->draw_context.klass);
|
||||
|
||||
if (method != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.method,
|
||||
mono_string_new (bridge->domain, method));
|
||||
}
|
||||
|
||||
if (style != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.style,
|
||||
maigre_gobject_new (bridge, style));
|
||||
}
|
||||
|
||||
if (window != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.window,
|
||||
maigre_gobject_new (bridge, window));
|
||||
}
|
||||
|
||||
if (area != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.area,
|
||||
maigre_gdk_rectangle_new (bridge, area));
|
||||
}
|
||||
|
||||
if (widget != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.widget,
|
||||
maigre_gobject_new (bridge, widget));
|
||||
}
|
||||
|
||||
if (detail != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.detail,
|
||||
mono_string_new (bridge->domain, detail));
|
||||
}
|
||||
|
||||
mono_field_set_value (context, bridge->draw_context.state_type, &state_type);
|
||||
mono_field_set_value (context, bridge->draw_context.shadow_type, &shadow_type);
|
||||
mono_field_set_value (context, bridge->draw_context.x, &x);
|
||||
mono_field_set_value (context, bridge->draw_context.y, &y);
|
||||
mono_field_set_value (context, bridge->draw_context.width, &width);
|
||||
mono_field_set_value (context, bridge->draw_context.height, &height);
|
||||
mono_field_set_value (context, bridge->draw_context.orientation, &orientation);
|
||||
mono_field_set_value (context, bridge->draw_context.expander_style, &expander_style);
|
||||
|
||||
if (layout != NULL) {
|
||||
mono_field_set_value (context, bridge->draw_context.layout,
|
||||
maigre_gobject_new (bridge, layout));
|
||||
}
|
||||
|
||||
mono_field_set_value (context, bridge->draw_context.use_text, &use_text);
|
||||
mono_field_set_value (context, bridge->draw_context.edge, &edge);
|
||||
mono_field_set_value (context, bridge->draw_context.step, &step);
|
||||
mono_field_set_value (context, bridge->draw_context.x1, &x1);
|
||||
mono_field_set_value (context, bridge->draw_context.x2, &x2);
|
||||
mono_field_set_value (context, bridge->draw_context.y1, &y1);
|
||||
mono_field_set_value (context, bridge->draw_context.y2, &y2);
|
||||
mono_field_set_value (context, bridge->draw_context.fill, &fill);
|
||||
mono_field_set_value (context, bridge->draw_context.arrow_type, &arrow_type);
|
||||
|
||||
return mono_object_unbox (context);
|
||||
}
|
||||
|
||||
#include "maigre-style-overrides.c"
|
||||
|
||||
typedef void (* DrawFnptr) ();
|
||||
|
@ -70,7 +138,7 @@ maigre_style_class_init (MaigreStyleClass *klass)
|
|||
mono_class_get_method_from_name (
|
||||
bridge->theme_class,
|
||||
maigre_style_method_map[i].name,
|
||||
maigre_style_method_map[i].arg_count);
|
||||
1);
|
||||
if (method != NULL) {
|
||||
DrawFnptr *slot = G_STRUCT_MEMBER_P (
|
||||
GTK_STYLE_CLASS (klass),
|
||||
|
|
Загрузка…
Ссылка в новой задаче