* NEW: GTK3+ support continues.


git-svn-id: svn://localhost/gambas/trunk@6017 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2013-12-24 00:14:11 +00:00
parent 51e4b5e01a
commit 0665ac21d8
9 changed files with 843 additions and 470 deletions

View file

@ -80,7 +80,115 @@ static void cb_click_check(GtkButton *object, gButton *data)
data->emit(SIGNAL(data->onClick));
}
#ifdef GTK3
static gboolean button_draw(GtkWidget *wid, cairo_t *cr, gButton *data)
{
GdkPixbuf *img;
GdkRectangle rpix={0,0,0,0};
GdkRectangle rect;
GtkCellRendererState state;
gint py, px;
bool rtl, bcenter=false;
gint dx, dy;
rtl = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
gtk_widget_get_allocation(wid, &rect);
px = rect.width;
if (gtk_widget_get_state_flags(data->widget) & GTK_STATE_FLAG_ACTIVE)
{
gtk_widget_style_get (wid,
"child-displacement-x", &dx,
"child-displacement-y", &dy,
(void *)NULL);
rect.x += dx;
rect.y += dy;
}
//g_debug("button_expose: %d %d %d %d", e->area.x, e->area.y, e->area.width, e->area.height);
//g_debug("rect: %d %d %d %d", rect.x, rect.y, rect.width, rect.height);
if (data->rendpix)
{
if (gtk_widget_get_state_flags(data->widget) & GTK_STATE_FLAG_INSENSITIVE)
{
if (!data->rendinc)
data->rendinc = gt_pixbuf_create_disabled(data->rendpix);
img = data->rendinc;
}
else
img = data->rendpix;
rpix.width = gdk_pixbuf_get_width(img);
rpix.height = gdk_pixbuf_get_height(img);
py = (rect.height - rpix.height)/2;
bcenter = !(data->text()) || !(*data->text());
if (bcenter)
{
//fprintf(stderr, "draw pixbuf: %d %d\n", rect.x + (px-rpix.width)/2, rect.y + py);
//gdk_draw_pixbuf(GDK_DRAWABLE(win),gc,img,0,0,rect.x + (px-rpix.width)/2, rect.y + py,
// -1,-1,GDK_RGB_DITHER_MAX,0,0);
gt_cairo_draw_pixbuf(cr, img, rect.x + (px - rpix.width) / 2, rect.y + py, -1, -1, 1.0, NULL);
cairo_destroy(cr);
return false;
}
if (rtl)
gt_cairo_draw_pixbuf(cr, img, rect.x + rect.width - 6, rect.y + py, -1, -1, 1.0, NULL);
else
gt_cairo_draw_pixbuf(cr, img, rect.x + 6, rect.y + py, -1, -1, 1.0, NULL);
rect.width -= rpix.width;
rect.x += rpix.width;
}
gt_set_cell_renderer_text_from_font((GtkCellRendererText *)data->rendtxt, data->font());
g_object_set(G_OBJECT(data->rendtxt), "sensitive", true, (void *)NULL);
switch (gtk_widget_get_state(data->widget))
{
//case GTK_STATE_NORMAL:
//case GTK_STATE_ACTIVE: state=GTK_CELL_RENDERER_PRELIT; break;
//case GTK_STATE_PRELIGHT: state=GTK_CELL_RENDERER_PRELIT; break;
case GTK_STATE_SELECTED:
state = GTK_CELL_RENDERER_SELECTED;
break;
case GTK_STATE_INSENSITIVE:
state = GTK_CELL_RENDERER_INSENSITIVE;
g_object_set(G_OBJECT(data->rendtxt), "sensitive", false, (void *)NULL);
break;
default:
state = (GtkCellRendererState)0;
break;
}
/*rect.width-=12;
rect.x+=6;
if (rtl)
{
rect.width=px-rect.x-6;
rect.x=6;
}*/
if (rect.width >= 1 && rect.height >= 1)
{
gtk_cell_renderer_set_fixed_size(data->rendtxt, rect.width, rect.height);
gtk_cell_renderer_render(data->rendtxt, cr, wid, &rect, &rect, state);
}
return FALSE;
}
#else
static gboolean button_expose(GtkWidget *wid,GdkEventExpose *e,gButton *data)
{
cairo_t *cr;
@ -198,6 +306,7 @@ static gboolean button_expose(GtkWidget *wid,GdkEventExpose *e,gButton *data)
return FALSE;
}
#endif
gButton::gButton(gContainer *par, Type typ) : gControl(par)
{
@ -272,7 +381,7 @@ gButton::gButton(gContainer *par, Type typ) : gControl(par)
g_object_set(G_OBJECT(rendtxt),"xalign",0.5,(void *)NULL);
g_object_set(G_OBJECT(rendtxt),"yalign",0.5,(void *)NULL);
g_signal_connect_after(G_OBJECT(widget),"expose-event",G_CALLBACK(button_expose),(gpointer)this);
ON_DRAW(widget, this, button_expose, button_draw);
}
else
{
@ -493,12 +602,20 @@ void gButton::setDefault(bool vl)
if (vl)
{
win->_default = this;
#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_set_can_default(widget, true);
#else
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
#endif
//gtk_widget_grab_default (widget);
}
else
{
#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_set_can_default(widget, false);
#else
GTK_WIDGET_UNSET_FLAGS(widget, GTK_CAN_DEFAULT);
#endif
if (win->_default == this)
win->_default = NULL;
}

View file

@ -324,7 +324,7 @@ int gContainer::clientX()
if (_client_x >= 0)
return _client_x;
if (cont->window && border->window)
if (gtk_widget_get_window(cont) && gtk_widget_get_window(border))
{
gtk_widget_translate_coordinates(cont, border, 0, 0, &xc, &yc);
xc += containerX();
@ -353,7 +353,7 @@ int gContainer::clientY()
if (_client_y >= 0)
return _client_y;
if (cont->window && border->window)
if (gtk_widget_get_window(cont) && gtk_widget_get_window(border))
{
gtk_widget_translate_coordinates(cont, border, 0, 0, &xc, &yc);
yc += containerY();
@ -405,24 +405,31 @@ int gContainer::clientWidth()
if (_client_w > 0)
return _client_w;
if (cont != widget && cont->window)
if (cont != widget && gtk_widget_get_window(cont))
{
if ((width() != widget->allocation.width || height() != widget->allocation.height)
&& widget->allocation.width > 0 && widget->allocation.height > 0)
GtkAllocation a;
gtk_widget_get_allocation(widget, &a);
if ((width() != a.width || height() != a.height)
&& a.width > 0 && a.height > 0)
{
//g_debug("clientWidth: %s: %d", name(), width());
GtkAllocation a = { x(), y(), width(), height() };
a.x = x(); a.y = y(); a.width = width(); a.height = height();
gt_disable_warnings(true);
gtk_widget_size_allocate(widget, &a);
gt_disable_warnings(false);
}
//g_debug("ClientWidth: %s -> %d", this->name(), cont->allocation.width);
if (cont->allocation.width > 0)
return cont->allocation.width;
gtk_widget_get_allocation(cont, &a);
if (a.width > 0)
return a.width;
}
if (_scroll)
return (int)gtk_scrolled_window_get_hadjustment(_scroll)->page_size;
return (int)gtk_adjustment_get_page_size(gtk_scrolled_window_get_hadjustment(_scroll));
return width() - getFrameWidth() * 2;
}
@ -434,25 +441,31 @@ int gContainer::clientHeight()
if (_client_h > 0)
return _client_h;
if (cont != widget && cont->window)
if (cont != widget && gtk_widget_get_window(cont))
{
if ((width() != widget->allocation.width || height() != widget->allocation.height)
&& widget->allocation.width > 0 && widget->allocation.height > 0)
GtkAllocation a;
gtk_widget_get_allocation(widget, &a);
if ((width() != a.width || height() != a.height)
&& a.width > 0 && a.height > 0)
{
//g_debug("clientHeight: %s: %d", name(), height());
GtkAllocation a = { x(), y(), width(), height() };
a.x = x(); a.y = y(); a.width = width(); a.height = height();
//gt_disable_warnings(true);
gtk_widget_size_allocate(widget, &a);
//gt_disable_warnings(false);
//gtk_container_resize_children(GTK_CONTAINER(widget));
}
//g_debug("ClientHeight: %s -> %d", this->name(), cont->allocation.height);
if (cont->allocation.height > 0)
return cont->allocation.height;
gtk_widget_get_allocation(cont, &a);
if (a.height > 0)
return a.height;
}
if (_scroll)
return (int)gtk_scrolled_window_get_vadjustment(_scroll)->page_size;
return (int)gtk_adjustment_get_page_size(gtk_scrolled_window_get_vadjustment(_scroll));
return height() - getFrameWidth() * 2;
}
@ -577,7 +590,7 @@ gControl *gContainer::findFirstFocus()
}
else
{
if (GTK_WIDGET_CAN_FOCUS(ch->widget) && !((ch->getClass() == Type_gButton) && ((gButton *)ch)->hasShortcut()))
if (gtk_widget_get_can_focus(ch->widget) && !((ch->getClass() == Type_gButton) && ((gButton *)ch)->hasShortcut()))
return ch;
}
}

File diff suppressed because it is too large Load diff

View file

@ -129,8 +129,8 @@ public:
void scroll(int x, int y);
void setScrollX(int vl);
void setScrollY(int vl);
virtual int scrollWidth();
virtual int scrollHeight();
//virtual int scrollWidth();
//virtual int scrollHeight();
int scrollBar();
void setScrollBar(int vl);
@ -190,7 +190,7 @@ public:
GtkWidget *frame;
GtkScrolledWindow *_scroll;
short g_typ;
short mous;
short _mouse;
gControl *_proxy, *_proxy_for;
unsigned dsg : 1;
@ -254,8 +254,13 @@ public:
void setFramePadding(int padding);
virtual int getFrameWidth();
virtual gColor getFrameColor();
#ifdef GTK3
void drawBorder(cairo_t *cr);
void drawBackground(GtkWidget *wid, cairo_t *cr);
#else
void drawBorder(GdkEventExpose *e);
void drawBackground(GtkWidget *wid, GdkEventExpose *e);
#endif
virtual int minimumHeight();
void resolveFont(gFont *new_font);

View file

@ -25,21 +25,16 @@
#include "widgets_private.h"
#include "glabel.h"
static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
#ifdef GTK3
static gboolean cb_draw(GtkWidget *draw, cairo_t *cr, gLabel *d)
{
GtkStyle *style = gtk_widget_get_style(draw);
cairo_t *cr;
int vw, vh, lw, lh;
int fw = Max(d->getFramePadding(), d->getFrameWidth());
cr = gdk_cairo_create(draw->window);
gdk_cairo_region(cr, e->region);
cairo_clip(cr);
if (style)
if (style)
gdk_cairo_set_source_color(cr, &style->fg[GTK_STATE_NORMAL]);
switch (d->lay_x)
{
case 0: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
@ -47,11 +42,11 @@ static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
case 2: pango_layout_set_alignment(d->layout, PANGO_ALIGN_RIGHT); break;
case 3: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
}
vw = d->width();
vh = d->height();
pango_layout_get_pixel_size(d->layout, &lw, &lh);
if (!d->markup)
{
switch (d->lay_x)
@ -59,10 +54,10 @@ static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
case 0: vw = fw; break;
case 1: vw = (vw - lw) / 2; break;
case 2: vw = vw - lw - fw; break;
case 3:
if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
case 3:
if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
vw = vw - lw - fw;
else
else
vw = fw;
break;
}
@ -70,28 +65,95 @@ static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
else
vw = fw;
switch (d->lay_y)
{
case 0: vh = fw; break;
case 1: vh = (vh - lh) / 2; break;
case 2: vh = vh - lh - fw; break;
}
if (vh < 0) vh = 0;
vw += draw->allocation.x;
vh += draw->allocation.y;
//vw += draw->allocation.x;
//vh += draw->allocation.y;
cairo_move_to(cr, vw, vh);
pango_cairo_show_layout(cr, d->layout);
//gdk_draw_layout(draw->window, gc, vw, vh, d->layout);
cairo_destroy(cr);
d->drawBorder(e);
//gdk_draw_layout(draw->window, gc, vw, vh, d->layout);
d->drawBorder(cr);
return false;
}
#else
static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
{
GtkStyle *style = gtk_widget_get_style(draw);
cairo_t *cr;
int vw, vh, lw, lh;
int fw = Max(d->getFramePadding(), d->getFrameWidth());
cr = gdk_cairo_create(draw->window);
gdk_cairo_region(cr, e->region);
cairo_clip(cr);
if (style)
gdk_cairo_set_source_color(cr, &style->fg[GTK_STATE_NORMAL]);
switch (d->lay_x)
{
case 0: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
case 1: pango_layout_set_alignment(d->layout, PANGO_ALIGN_CENTER); break;
case 2: pango_layout_set_alignment(d->layout, PANGO_ALIGN_RIGHT); break;
case 3: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
}
vw = d->width();
vh = d->height();
pango_layout_get_pixel_size(d->layout, &lw, &lh);
if (!d->markup)
{
switch (d->lay_x)
{
case 0: vw = fw; break;
case 1: vw = (vw - lw) / 2; break;
case 2: vw = vw - lw - fw; break;
case 3:
if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
vw = vw - lw - fw;
else
vw = fw;
break;
}
}
else
vw = fw;
switch (d->lay_y)
{
case 0: vh = fw; break;
case 1: vh = (vh - lh) / 2; break;
case 2: vh = vh - lh - fw; break;
}
if (vh < 0) vh = 0;
vw += draw->allocation.x;
vh += draw->allocation.y;
cairo_move_to(cr, vw, vh);
pango_cairo_show_layout(cr, d->layout);
//gdk_draw_layout(draw->window, gc, vw, vh, d->layout);
cairo_destroy(cr);
d->drawBorder(e);
return false;
}
#endif
gLabel::gLabel(gContainer *parent) : gControl(parent)
{
@ -110,7 +172,7 @@ gLabel::gLabel(gContainer *parent) : gControl(parent)
realize(false);
g_signal_connect_after(G_OBJECT(widget), "expose-event", G_CALLBACK(cb_expose), (gpointer)this);
ON_DRAW(widget, this, cb_expose, cb_draw);
setAlignment(ALIGN_NORMAL);
updateLayout();

View file

@ -26,7 +26,36 @@
#include "gdesktop.h"
#include "gseparator.h"
gboolean gSeparator_expose(GtkWidget *wid, GdkEventExpose *e, gSeparator *data)
#ifdef GTK3
static gboolean cb_draw(GtkWidget *wid, cairo_t *cr, gSeparator *data)
{
gint x, y, w, h;
gColor color;
x = y = 0;
w = data->width();
h = data->height();
if (w == 1 || h == 1)
{
color = data->foreground();
if (color == COLOR_DEFAULT)
color = gDesktop::lightfgColor();
gt_cairo_set_source_color(cr, color);
cairo_rectangle(cr, x, y, w, h);
cairo_fill(cr);
}
else if (w>=h)
gtk_paint_hline(gtk_widget_get_style(wid), cr, GTK_STATE_NORMAL, wid, NULL, x, x + w, y + h / 2);
else
gtk_paint_vline(gtk_widget_get_style(wid), cr, GTK_STATE_NORMAL, wid, NULL, y, y + h, x + w / 2);
return false;
}
#else
static gboolean cb_expose(GtkWidget *wid, GdkEventExpose *e, gSeparator *data)
{
gint x, y, w, h;
gColor color;
@ -59,6 +88,7 @@ gboolean gSeparator_expose(GtkWidget *wid, GdkEventExpose *e, gSeparator *data)
return false;
}
#endif
gSeparator::gSeparator(gContainer *parent) : gControl(parent)
{
@ -68,7 +98,7 @@ gSeparator::gSeparator(gContainer *parent) : gControl(parent)
realize(false);
g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(gSeparator_expose), (gpointer)this);
ON_DRAW(widget, this, cb_expose, cb_draw);
}

View file

@ -142,7 +142,11 @@ static gboolean sg_drag_motion(GtkWidget *widget, GdkDragContext *context, gint
data->_drop_2 = false;
}*/
#if GTK_CHECK_VERSION(2, 22, 0)
switch (gdk_drag_context_get_suggested_action(context))
#else
switch (context->suggested_action)
#endif
{
case GDK_ACTION_MOVE:
action = gDrag::Move;
@ -203,7 +207,11 @@ static gboolean sg_drag_motion(GtkWidget *widget, GdkDragContext *context, gint
if (retval)
{
//fprintf(stderr, "sg_drag_motion: accept\n");
#if GTK_CHECK_VERSION(2, 22, 0)
gdk_drag_status(context, gdk_drag_context_get_suggested_action(context), time);
#else
gdk_drag_status(context, context->suggested_action, time);
#endif
return true;
}

View file

@ -63,7 +63,9 @@ void gSlider::init()
gtk_adjustment_set_page_size(adj, _page_step);
}
gtk_range_set_value(GTK_RANGE(widget), _value);
#ifndef GTK3
gtk_range_set_update_policy(GTK_RANGE(widget), _tracking ? GTK_UPDATE_CONTINUOUS : GTK_UPDATE_DISCONTINUOUS);
#endif
checkInverted();
}
@ -107,7 +109,9 @@ gScrollBar::gScrollBar(gContainer *par) : gSlider(par, true)
init();
onChange = NULL;
#ifndef GTK3
gtk_range_set_update_policy(GTK_RANGE(widget),GTK_UPDATE_CONTINUOUS);
#endif
g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(cb_change), (gpointer)this);
}
@ -238,7 +242,7 @@ void gSlider::setValue(int vl)
void gSlider::orientation(int w,int h)
{
GtkAdjustment *adj;
GtkType type;
GType type;
type = (w < h) ? GTK_TYPE_VSCALE : GTK_TYPE_HSCALE;
@ -322,7 +326,7 @@ int gSlider::getDefaultSize()
bool gSlider::isVertical() const
{
return (GTK_WIDGET_TYPE(widget) == GTK_TYPE_VSCALE || GTK_WIDGET_TYPE(widget) == GTK_TYPE_VSCROLLBAR);
return (G_OBJECT_TYPE(widget) == GTK_TYPE_VSCALE || G_OBJECT_TYPE(widget) == GTK_TYPE_VSCROLLBAR);
}
void gSlider::checkInverted()

View file

@ -113,4 +113,10 @@ enum
typedef
unsigned char uchar;
#ifdef GTK3
#define ON_DRAW(_widget, _this, _gtk, _gtk3) g_signal_connect_after(G_OBJECT(_widget), "draw", G_CALLBACK(_gtk3), (gpointer)_this)
#else
#define ON_DRAW(_widget, _this, _gtk, _gtk3) g_signal_connect_after(G_OBJECT(_widget), "expose-event", G_CALLBACK(_gtk), (gpointer)_this)
#endif
#endif