Got rid of the GtkScrollable code from GtkDrawingArea for uiArea. Woo! Now we just have to nuke all that from the Cocoa backend and we're good.

This commit is contained in:
Pietro Gagliardi 2015-12-17 14:48:58 -05:00
parent e9247858d4
commit ffe9a2db28
1 changed files with 12 additions and 136 deletions

View File

@ -34,61 +34,14 @@ struct areaPrivate {
uiArea *a;
uiAreaHandler *ah;
GtkAdjustment *ha;
GtkAdjustment *va;
// TODO get rid of the need for these
int clientWidth;
int clientHeight;
// needed for GtkScrollable
GtkScrollablePolicy hpolicy, vpolicy;
clickCounter cc;
};
static void areaWidget_scrollable_init(GtkScrollable *);
G_DEFINE_TYPE_WITH_CODE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA,
G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, areaWidget_scrollable_init))
/*
lower and upper are the bounds of the adjusment, in units
step_increment is the number of units scrolled when using the arrow keys or the buttons on an old-style scrollbar
page_incremenet is the number of page_size units scrolled with the Page Up/Down keys
according to baedert, the other condition is that upper >= page_size, and the effect is that the largest possible value is upper - page_size
unfortunately, everything in GTK+ assumes 1 unit = 1 pixel
let's do the same :/
*/
static void updateScroll(areaWidget *a)
{
struct areaPrivate *ap = a->priv;
uintmax_t count;
// don't call if too early
if (ap->ha == NULL || ap->va == NULL)
return;
count = (*(ap->ah->HScrollMax))(ap->ah, ap->a);
gtk_adjustment_configure(ap->ha,
gtk_adjustment_get_value(ap->ha),
0,
count,
1,
ap->clientWidth,
MIN(count, ap->clientWidth));
count = (*(ap->ah->VScrollMax))(ap->ah, ap->a);
gtk_adjustment_configure(ap->va,
gtk_adjustment_get_value(ap->va),
0,
count,
1,
ap->clientHeight,
MIN(count, ap->clientHeight));
// TODO notify adjustment changes?
// g_object_notify(G_OBJECT(a), "hadjustment");
// g_object_notify(G_OBJECT(a), "vadjustment");
}
G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA)
static void areaWidget_init(areaWidget *a)
{
@ -104,12 +57,15 @@ static void areaWidget_init(areaWidget *a)
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK);
// TODO are these still needed?
/*
// for scrolling
// TODO do we need GDK_TOUCH_MASK?
gtk_widget_add_events(GTK_WIDGET(a),
GDK_SCROLL_MASK |
GDK_TOUCH_MASK |
GDK_SMOOTH_SCROLL_MASK);
*/
gtk_widget_set_can_focus(GTK_WIDGET(a), TRUE);
@ -118,16 +74,6 @@ static void areaWidget_init(areaWidget *a)
static void areaWidget_dispose(GObject *obj)
{
struct areaPrivate *ap = areaWidget(obj)->priv;
if (ap->ha != NULL) {
g_object_unref(ap->ha);
ap->ha = NULL;
}
if (ap->va != NULL) {
g_object_unref(ap->va);
ap->va = NULL;
}
G_OBJECT_CLASS(areaWidget_parent_class)->dispose(obj);
}
@ -145,7 +91,6 @@ static void areaWidget_size_allocate(GtkWidget *w, GtkAllocation *allocation)
GTK_WIDGET_CLASS(areaWidget_parent_class)->size_allocate(w, allocation);
ap->clientWidth = allocation->width;
ap->clientHeight = allocation->height;
updateScroll(areaWidget(w));
// we must redraw everything on resize because Windows requires it
gtk_widget_queue_resize(w);
}
@ -159,11 +104,12 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
dp.Context = newContext(cr);
// TODO set to 0 for scrolling
// these are already in drawing space coordinates
// the size of drawing space has the same value as the widget allocation
// thanks to tristan in irc.gimp.net/#gtk+
dp.ClientWidth = ap->clientWidth;
dp.ClientHeight = ap->clientHeight;
dp.AreaWidth = ap->clientWidth;
dp.AreaHeight = ap->clientHeight;
cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1);
dp.ClipX = clipX0;
@ -171,9 +117,6 @@ static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
dp.ClipWidth = clipX1 - clipX0;
dp.ClipHeight = clipY1 - clipY0;
dp.HScrollPos = gtk_adjustment_get_value(ap->ha);
dp.VScrollPos = gtk_adjustment_get_value(ap->va);
// no need to save or restore the graphics state to reset transformations; GTK+ does that for us
(*(ap->ah->Draw))(ap->ah, ap->a, &dp);
@ -246,10 +189,9 @@ static void finishMouseEvent(struct areaPrivate *ap, uiAreaMouseEvent *me, guint
me->X = x;
me->Y = y;
me->ClientWidth = ap->clientWidth;
me->ClientHeight = ap->clientHeight;
me->HScrollPos = gtk_adjustment_get_value(ap->ha);
me->VScrollPos = gtk_adjustment_get_value(ap->va);
// TODO set to 0 for scrollables
me->AreaWidth = ap->clientWidth;
me->AreaHeight = ap->clientHeight;
(*(ap->ah->MouseEvent))(ap->ah, ap->a, me);
}
@ -316,6 +258,7 @@ static gboolean areaWidget_enterleave_notify_event(GtkWidget *w, GdkEventCrossin
{
struct areaPrivate *ap = areaWidget(w)->priv;
// TODO call MouseCrossed
clickCounterReset(&(ap->cc));
return GDK_EVENT_PROPAGATE;
}
@ -437,57 +380,18 @@ static gboolean areaWidget_key_release_event(GtkWidget *w, GdkEventKey *e)
}
enum {
// normal properties must come before override properties
// thanks gregier in irc.gimp.net/#gtk+
pAreaHandler = 1,
pHAdjustment,
pVAdjustment,
pHScrollPolicy,
pVScrollPolicy,
nProps,
};
static GParamSpec *pspecAreaHandler;
static void onValueChanged(GtkAdjustment *a, gpointer data)
{
// there's no way to scroll the contents of a widget, so we have to redraw the entire thing
gtk_widget_queue_draw(GTK_WIDGET(data));
}
static void replaceAdjustment(areaWidget *a, GtkAdjustment **adj, const GValue *value)
{
if (*adj != NULL) {
g_signal_handlers_disconnect_by_func(*adj, G_CALLBACK(onValueChanged), a);
g_object_unref(*adj);
}
*adj = GTK_ADJUSTMENT(g_value_get_object(value));
if (*adj != NULL)
g_object_ref_sink(*adj);
else
*adj = gtk_adjustment_new(0, 0, 0, 0, 0, 0);
g_signal_connect(*adj, "value-changed", G_CALLBACK(onValueChanged), a);
updateScroll(a);
}
static void areaWidget_set_property(GObject *obj, guint prop, const GValue *value, GParamSpec *pspec)
{
areaWidget *a = areaWidget(obj);
struct areaPrivate *ap = a->priv;
switch (prop) {
case pHAdjustment:
replaceAdjustment(a, &(ap->ha), value);
return;
case pVAdjustment:
replaceAdjustment(a, &(ap->va), value);
return;
case pHScrollPolicy:
ap->hpolicy = g_value_get_enum(value);
return;
case pVScrollPolicy:
ap->vpolicy = g_value_get_enum(value);
return;
case pAreaHandler:
ap->ah = (uiAreaHandler *) g_value_get_pointer(value);
return;
@ -497,23 +401,6 @@ static void areaWidget_set_property(GObject *obj, guint prop, const GValue *valu
static void areaWidget_get_property(GObject *obj, guint prop, GValue *value, GParamSpec *pspec)
{
areaWidget *a = areaWidget(obj);
struct areaPrivate *ap = a->priv;
switch (prop) {
case pHAdjustment:
g_value_set_object(value, ap->ha);
return;
case pVAdjustment:
g_value_set_object(value, ap->va);
return;
case pHScrollPolicy:
g_value_set_enum(value, ap->hpolicy);
return;
case pVScrollPolicy:
g_value_set_enum(value, ap->vpolicy);
return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop, pspec);
}
@ -543,17 +430,6 @@ static void areaWidget_class_init(areaWidgetClass *class)
"Area handler.",
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property(G_OBJECT_CLASS(class), pAreaHandler, pspecAreaHandler);
// this is the actual interface implementation
g_object_class_override_property(G_OBJECT_CLASS(class), pHAdjustment, "hadjustment");
g_object_class_override_property(G_OBJECT_CLASS(class), pVAdjustment, "vadjustment");
g_object_class_override_property(G_OBJECT_CLASS(class), pHScrollPolicy, "hscroll-policy");
g_object_class_override_property(G_OBJECT_CLASS(class), pVScrollPolicy, "vscroll-policy");
}
static void areaWidget_scrollable_init(GtkScrollable *iface)
{
// no need to do anything; the interface only has properties
}
// control implementation