Use GTK+ internals to make ComboBox Border, Foreground and Background properties work as expected.
[GB.GTK3] * BUG: Use GTK+ internals to make ComboBox Border, Foreground and Background properties work as expected.
This commit is contained in:
parent
215cd6f54a
commit
778feecff6
@ -122,7 +122,7 @@ static gboolean button_expose(GtkWidget *wid, GdkEventExpose *e, gButton *data)
|
||||
if (data->hasText())
|
||||
{
|
||||
gt_set_cell_renderer_text_from_font((GtkCellRendererText *)data->rendtxt, data->font());
|
||||
wt = data->font()->width(data->text(), strlen(data->text()));
|
||||
wt = data->font()->width(data->text(), strlen(data->text())) + 4;
|
||||
}
|
||||
|
||||
if (data->rendpix)
|
||||
|
@ -26,6 +26,72 @@
|
||||
#include "gdesktop.h"
|
||||
#include "gcombobox.h"
|
||||
|
||||
#ifdef GTK3
|
||||
|
||||
struct _GtkComboBoxPrivate
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
|
||||
GtkCellArea *area;
|
||||
|
||||
gint col_column;
|
||||
gint row_column;
|
||||
|
||||
gint wrap_width;
|
||||
|
||||
gint active; /* Only temporary */
|
||||
GtkTreeRowReference *active_row;
|
||||
|
||||
GtkWidget *tree_view;
|
||||
|
||||
GtkWidget *cell_view;
|
||||
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GtkWidget *arrow;
|
||||
|
||||
GtkWidget *popup_widget;
|
||||
GtkWidget *popup_window;
|
||||
GtkWidget *scrolled_window;
|
||||
|
||||
//GtkCssGadget *gadget;
|
||||
void *gadget;
|
||||
|
||||
guint popup_idle_id;
|
||||
GdkEvent *trigger_event;
|
||||
guint scroll_timer;
|
||||
guint resize_idle_id;
|
||||
|
||||
/* For "has-entry" specific behavior we track
|
||||
* an automated cell renderer and text column
|
||||
*/
|
||||
gint text_column;
|
||||
GtkCellRenderer *text_renderer;
|
||||
|
||||
gint id_column;
|
||||
|
||||
guint popup_in_progress : 1;
|
||||
guint popup_shown : 1;
|
||||
guint add_tearoffs : 1;
|
||||
guint has_frame : 1;
|
||||
guint is_cell_renderer : 1;
|
||||
guint editing_canceled : 1;
|
||||
guint auto_scroll : 1;
|
||||
guint button_sensitivity : 2;
|
||||
guint has_entry : 1;
|
||||
guint popup_fixed_width : 1;
|
||||
|
||||
GtkTreeViewRowSeparatorFunc row_separator_func;
|
||||
gpointer row_separator_data;
|
||||
GDestroyNotify row_separator_destroy;
|
||||
|
||||
GdkDevice *grab_pointer;
|
||||
|
||||
gchar *tearoff_title;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
gComboBox
|
||||
@ -158,13 +224,14 @@ void gComboBox::create(bool readOnly)
|
||||
cell = NULL;
|
||||
gtk_widget_destroy(widget);
|
||||
_button = NULL;
|
||||
createWidget();
|
||||
}
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(tree->store));
|
||||
entry = NULL;
|
||||
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
g_object_ref_sink(cell);
|
||||
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), cell, true);
|
||||
@ -237,15 +304,19 @@ void gComboBox::create(bool readOnly)
|
||||
|
||||
updateFocusHandler();
|
||||
|
||||
//gtk_widget_reset_style(border);
|
||||
|
||||
if (!first)
|
||||
{
|
||||
setBackground(bg);
|
||||
setForeground(fg);
|
||||
updateFont();
|
||||
|
||||
setText(save);
|
||||
g_free(save);
|
||||
|
||||
updateDesign();
|
||||
}
|
||||
|
||||
setText(save);
|
||||
g_free(save);
|
||||
|
||||
unlock();
|
||||
}
|
||||
@ -260,7 +331,8 @@ gComboBox::gComboBox(gContainer *parent) : gTextBox(parent, true)
|
||||
_last_key = 0;
|
||||
_model_dirty = false;
|
||||
_model_dirty_timeout = 0;
|
||||
sort = false;
|
||||
_sort = false;
|
||||
_has_border = true;
|
||||
border = widget = NULL;
|
||||
entry = NULL;
|
||||
_button = NULL;
|
||||
@ -293,26 +365,80 @@ void gComboBox::popup()
|
||||
}
|
||||
|
||||
#ifdef GTK3
|
||||
|
||||
GtkWidget *gComboBox::getStyleSheetWidget()
|
||||
{
|
||||
return entry ? entry : border;
|
||||
if (entry)
|
||||
return entry;
|
||||
|
||||
return GTK_COMBO_BOX(widget)->priv->button;
|
||||
}
|
||||
|
||||
const char *gComboBox::getStyleSheetColorNode()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
const char *gComboBox::getStyleSheetFontNode()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void gComboBox::customStyleSheet(GString *css)
|
||||
{
|
||||
if (!_has_border)
|
||||
{
|
||||
setStyleSheetNode(css, "");
|
||||
g_string_append_printf(css, "border:none;box-shadow:none;\n");
|
||||
if (background() == COLOR_DEFAULT)
|
||||
g_string_append_printf(css, "background:none;");
|
||||
|
||||
if (entry)
|
||||
{
|
||||
setStyleSheetNode(css, " + *");
|
||||
g_string_append_printf(css, "border:none;box-shadow:none;");
|
||||
if (background() == COLOR_DEFAULT)
|
||||
g_string_append_printf(css, "background:none;");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gComboBox::setForeground(gColor color)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
gControl::setForeground(color);
|
||||
|
||||
gt_from_color(realForeground(true), &rgba);
|
||||
g_object_set(G_OBJECT(cell), "foreground-rgba", &rgba, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void gComboBox::setRealBackground(gColor color)
|
||||
{
|
||||
gControl::setRealBackground(color);
|
||||
if (entry)
|
||||
set_gdk_base_color(entry, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
void gComboBox::setRealForeground(gColor color)
|
||||
{
|
||||
gControl::setRealForeground(color);
|
||||
if (entry)
|
||||
set_gdk_text_color(entry, color);
|
||||
|
||||
#ifdef GTK3
|
||||
GdkRGBA rgba;
|
||||
gt_from_color(color, &rgba);
|
||||
g_object_set(G_OBJECT(cell), "foreground-rgba", &rgba, NULL);
|
||||
#else
|
||||
GdkColor col;
|
||||
fill_gdk_color(&col, color);
|
||||
g_object_set(G_OBJECT(cell), "foreground-gdk", &col, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int gComboBox::count()
|
||||
{
|
||||
@ -629,20 +755,29 @@ void gComboBox::updateFocusHandler()
|
||||
g_signal_connect(G_OBJECT(button), "focus-out-event", G_CALLBACK(button_focus_out), (gpointer)this);
|
||||
}
|
||||
|
||||
bool gComboBox::hasBorder() const
|
||||
{
|
||||
gboolean v;
|
||||
|
||||
g_object_get(G_OBJECT(widget), "has-frame", &v, (void *)NULL);
|
||||
return v;
|
||||
}
|
||||
|
||||
void gComboBox::setBorder(bool v)
|
||||
{
|
||||
g_object_set(G_OBJECT(widget), "has-frame", v, (void *)NULL);
|
||||
_has_border = v;
|
||||
updateBorder();
|
||||
}
|
||||
|
||||
void gComboBox::updateBorder()
|
||||
{
|
||||
#ifdef GTK3
|
||||
updateStyleSheet();
|
||||
#else
|
||||
g_object_set(G_OBJECT(widget), "has-frame", _has_border, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool gComboBox::canFocus() const
|
||||
{
|
||||
return true;
|
||||
return !_design;
|
||||
}
|
||||
|
||||
void gComboBox::setDesign(bool ignore)
|
||||
{
|
||||
gControl::setDesign(ignore);
|
||||
if (entry)
|
||||
gtk_widget_set_can_focus(entry, false);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
void setSorted(bool vl);
|
||||
virtual void setText(const char *vl);
|
||||
|
||||
bool hasBorder() const;
|
||||
bool hasBorder() const { return _has_border; }
|
||||
void setBorder(bool v);
|
||||
|
||||
//"Methods"
|
||||
@ -61,18 +61,23 @@ public:
|
||||
|
||||
#ifdef GTK3
|
||||
virtual GtkWidget *getStyleSheetWidget();
|
||||
virtual const char *getStyleSheetColorNode();
|
||||
virtual const char *getStyleSheetFontNode();
|
||||
virtual void customStyleSheet(GString *css);
|
||||
virtual void setForeground(gColor color);
|
||||
#else
|
||||
virtual void setRealBackground(gColor vl);
|
||||
#endif
|
||||
virtual void setRealForeground(gColor vl);
|
||||
#endif
|
||||
virtual void setFocus();
|
||||
virtual bool canFocus() const;
|
||||
void updateBorder();
|
||||
virtual void setDesign(bool ignore = false);
|
||||
|
||||
//"Signals"
|
||||
void (*onClick)(gComboBox *sender);
|
||||
|
||||
//"Private"
|
||||
bool sort;
|
||||
GtkCellRenderer *cell;
|
||||
virtual int minimumHeight();
|
||||
gTree *tree;
|
||||
@ -80,6 +85,8 @@ public:
|
||||
int _last_key;
|
||||
GtkWidget *_button;
|
||||
int _model_dirty_timeout;
|
||||
unsigned _sort : 1;
|
||||
unsigned _has_border : 1;
|
||||
|
||||
virtual void updateFont();
|
||||
void updateModel();
|
||||
|
@ -1148,6 +1148,15 @@ void gControl::setDesign(bool ignore)
|
||||
_design_ignore = ignore;
|
||||
}
|
||||
|
||||
void gControl::updateDesign()
|
||||
{
|
||||
if (!_design)
|
||||
return;
|
||||
|
||||
_design = false;
|
||||
setDesign(_design_ignore);
|
||||
}
|
||||
|
||||
gControl *gControl::ignoreDesign()
|
||||
{
|
||||
//fprintf(stderr, "ignoreDesign: %s", name());
|
||||
@ -2041,17 +2050,32 @@ void gControl::customStyleSheet(GString *css)
|
||||
{
|
||||
}
|
||||
|
||||
void gControl::setStyleSheetNode(GString *css, const char *node)
|
||||
{
|
||||
if (node == _css_node)
|
||||
return;
|
||||
|
||||
if (node && _css_node && !::strcmp(node, _css_node))
|
||||
return;
|
||||
|
||||
if (_css_node)
|
||||
g_string_append(css, "}\n");
|
||||
|
||||
_css_node = node;
|
||||
|
||||
if (node)
|
||||
g_string_append_printf(css, "#%s %s {\ntransition:none;\n", gtk_widget_get_name(getStyleSheetWidget()), node);
|
||||
}
|
||||
|
||||
void gControl::updateStyleSheet()
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
GtkWidget *wid;
|
||||
GtkStyleContext *context;
|
||||
GString *css;
|
||||
char *css_str;
|
||||
char buffer[16];
|
||||
int s;
|
||||
gColor fg;
|
||||
char buffer[16];
|
||||
|
||||
wid = getStyleSheetWidget();
|
||||
context = gtk_widget_get_style_context(wid);
|
||||
@ -2067,20 +2091,18 @@ void gControl::updateStyleSheet()
|
||||
{
|
||||
if (!_css)
|
||||
{
|
||||
count++;
|
||||
sprintf(buffer, "g%d", count);
|
||||
gtk_widget_set_name(wid, buffer);
|
||||
|
||||
setWidgetName();
|
||||
_css = GTK_STYLE_PROVIDER(gtk_css_provider_new());
|
||||
}
|
||||
else
|
||||
gtk_style_context_remove_provider(context, _css);
|
||||
|
||||
css = g_string_new(NULL);
|
||||
_css_node = NULL;
|
||||
|
||||
if (_bg != COLOR_DEFAULT || fg != COLOR_DEFAULT)
|
||||
{
|
||||
g_string_append_printf(css, "#%s %s {\ntransition:none;\n", gtk_widget_get_name(wid), getStyleSheetColorNode());
|
||||
setStyleSheetNode(css, getStyleSheetColorNode());
|
||||
|
||||
if (_bg != COLOR_DEFAULT)
|
||||
{
|
||||
@ -2097,13 +2119,11 @@ void gControl::updateStyleSheet()
|
||||
g_string_append(css, buffer);
|
||||
g_string_append(css, ";\n");
|
||||
}
|
||||
|
||||
g_string_append(css, "}\n");
|
||||
}
|
||||
|
||||
if (_font)
|
||||
{
|
||||
g_string_append_printf(css, "#%s %s {\ntransition:none;\n", gtk_widget_get_name(wid), getStyleSheetFontNode());
|
||||
setStyleSheetNode(css, getStyleSheetFontNode());
|
||||
|
||||
if (_font->_name_set)
|
||||
{
|
||||
@ -2150,17 +2170,20 @@ void gControl::updateStyleSheet()
|
||||
{
|
||||
g_string_append(css, "letter-spacing:1px;\n");
|
||||
}
|
||||
|
||||
g_string_append(css, "}\n");
|
||||
}
|
||||
|
||||
customStyleSheet(css);
|
||||
|
||||
//fprintf(stderr, "---- %s\n%s", _name, css);
|
||||
setStyleSheetNode(css, NULL);
|
||||
|
||||
css_str = g_string_free(css, FALSE);
|
||||
gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(_css), css_str, -1, NULL);
|
||||
g_free(css_str);
|
||||
gtk_style_context_add_provider(context, _css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
/*css_str = gtk_css_provider_to_string(GTK_CSS_PROVIDER(_css));
|
||||
fprintf(stderr, "---- %s\n%s", gtk_widget_get_name(wid), css_str);
|
||||
g_free(css_str);*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -2826,6 +2849,17 @@ gControl *gControl::previousFocus()
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
void gControl::createWidget()
|
||||
{
|
||||
#ifdef GTK3
|
||||
if (_css)
|
||||
{
|
||||
g_object_unref(_css);
|
||||
_css = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gControl::createBorder(GtkWidget *new_border, bool keep_widget)
|
||||
{
|
||||
GtkWidget *old = border;
|
||||
@ -2840,5 +2874,19 @@ void gControl::createBorder(GtkWidget *new_border, bool keep_widget)
|
||||
_no_delete = true;
|
||||
gtk_widget_destroy(old);
|
||||
_no_delete = false;
|
||||
createWidget();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GTK3
|
||||
void gControl::setWidgetName()
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
char buffer[16];
|
||||
|
||||
count++;
|
||||
sprintf(buffer, "g%d", count);
|
||||
gtk_widget_set_name(getStyleSheetWidget(), buffer);
|
||||
}
|
||||
#endif
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
|
||||
virtual void setDesign(bool ignore = false);
|
||||
gControl *ignoreDesign();
|
||||
void updateDesign();
|
||||
|
||||
char *tooltip() { return _tooltip; }
|
||||
void setTooltip(char *vl);
|
||||
@ -151,11 +152,13 @@ public:
|
||||
bool hasNativePopup() const { return _has_native_popup; }
|
||||
|
||||
#ifdef GTK3
|
||||
void setWidgetName();
|
||||
virtual GtkWidget *getStyleSheetWidget();
|
||||
virtual const char *getStyleSheetColorNode();
|
||||
virtual const char *getStyleSheetFontNode();
|
||||
void updateStyleSheet();
|
||||
virtual void customStyleSheet(GString *css);
|
||||
void setStyleSheetNode(GString *css, const char *node);
|
||||
virtual void updateColor();
|
||||
void setColorNames(const char *bg_names[], const char *fg_names[]);
|
||||
void setColorBase();
|
||||
@ -213,7 +216,7 @@ public:
|
||||
|
||||
void lock() { _locked++; }
|
||||
void unlock() { _locked--; }
|
||||
bool locked() { return _locked; }
|
||||
bool locked() const { return _locked; }
|
||||
|
||||
void emit(void *signal);
|
||||
void emit(void *signal, intptr_t arg);
|
||||
@ -248,6 +251,7 @@ public:
|
||||
char *_tooltip;
|
||||
#ifdef GTK3
|
||||
GtkStyleProvider *_css;
|
||||
const char *_css_node;
|
||||
const char *_bg_name;
|
||||
const char **_bg_name_list;
|
||||
GdkRGBA _bg_default;
|
||||
@ -335,6 +339,7 @@ public:
|
||||
#endif
|
||||
|
||||
void createBorder(GtkWidget *new_border, bool keep_widget = false);
|
||||
void createWidget();
|
||||
|
||||
virtual int minimumHeight() const;
|
||||
virtual int minimumWidth() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user