5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
10 #include "ygtkratiobox.h"
13 #define DEFAULT_BORDER 6
14 #define LABEL_WIDGET_SPACING 4
20 typedef std::pair <GObject *, gulong> Handler;
21 std::list <Handler> m_handlers;
22 void connectSignal (GObject *
object,
const char *name,
23 GCallback callback, gpointer data,
bool after)
27 handler = g_signal_connect_after (
object, name, callback, data);
29 handler = g_signal_connect (
object, name, callback, data);
31 Handler h (
object, handler);
32 m_handlers.push_back (h);
36 for (std::list <Handler>::const_iterator it = m_handlers.begin();
37 it != m_handlers.end(); it++) {
38 const Handler &h = *it;
39 g_signal_handler_block (h.first, h.second);
44 for (std::list <Handler>::const_iterator it = m_handlers.begin();
45 it != m_handlers.end(); it++) {
46 const Handler &h = *it;
47 g_signal_handler_unblock (h.first, h.second);
54 static void min_size_cb (guint *min_width, guint *min_height, gpointer pData);
56 YGWidget::YGWidget(YWidget *ywidget, YWidget *yparent,
57 GType type,
const char *property_name, ...)
61 va_start (args, property_name);
62 construct (ywidget, yparent, type, property_name, args);
66 void YGWidget::construct (YWidget *ywidget, YWidget *yparent,
67 GType type,
const char *property_name, va_list args)
69 m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args));
71 if (type == GTK_TYPE_WINDOW || type == GTK_TYPE_MENU)
72 m_adj_size = m_widget;
74 m_adj_size = ygtk_adj_size_new();
75 g_object_ref_sink (G_OBJECT (m_adj_size));
76 gtk_widget_show (m_adj_size);
77 gtk_container_add (GTK_CONTAINER (m_adj_size), m_widget);
78 ygtk_adj_size_set_min_cb (YGTK_ADJ_SIZE (m_adj_size), min_size_cb,
this);
80 gtk_widget_show (m_widget);
83 setBorder (DEFAULT_BORDER / 2);
85 ywidget->setWidgetRep ((
void *)
this);
87 ywidget->setParent (yparent);
88 yparent->addChild (ywidget);
97 if (YGUI::ui()->eventPendingFor (m_ywidget))
98 YGUI::ui()->m_event_handler.consumePendingEvent();
102 static void foreach_child_cb (GtkWidget *child, GtkContainer *container)
103 { gtk_container_remove (container, child); }
105 if (GTK_IS_CONTAINER (m_widget))
106 gtk_container_foreach (GTK_CONTAINER (m_widget),
107 (GtkCallback) inner::foreach_child_cb, m_widget);
109 gtk_widget_destroy (m_adj_size);
110 g_object_unref (G_OBJECT (m_adj_size));
113 YGWidget *YGWidget::get (YWidget *ywidget)
116 return (
YGWidget *) ywidget->widgetRep();
119 bool YGWidget::doSetKeyboardFocus()
121 gtk_widget_grab_focus (getWidget());
122 return gtk_widget_is_focus (getWidget());
125 void YGWidget::doSetEnabled (
bool enabled)
127 gtk_widget_set_sensitive (getLayout(), enabled);
130 void YGWidget::doSetUseBoldFont (
bool useBold)
132 PangoWeight weight = useBold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL;
133 YGUtils::setWidgetFont (getWidget(), PANGO_STYLE_NORMAL, weight, PANGO_SCALE_MEDIUM);
136 void YGWidget::doAddChild (YWidget *ychild, GtkWidget *container)
138 GtkWidget *child = YGWidget::get (ychild)->getLayout();
139 gtk_container_add (GTK_CONTAINER (container), child);
142 void YGWidget::doRemoveChild (YWidget *ychild, GtkWidget *container)
150 if (!ychild->beingDestroyed()) {
151 GtkWidget *child = YGWidget::get (ychild)->getLayout();
152 gtk_container_remove (GTK_CONTAINER (container), child);
156 int YGWidget::doPreferredSize (YUIDimension dimension)
160 gtk_widget_get_preferred_size (m_adj_size, &req, NULL);
161 return dimension == YD_HORIZ ? req.width : req.height;
164 void min_size_cb (guint *min_width, guint *min_height, gpointer pData)
167 *min_width = pThis->getMinSize (YD_HORIZ);
168 *min_height = pThis->getMinSize (YD_VERT);
171 #include "ygtkfixed.h"
173 void YGWidget::doSetSize (
int width,
int height)
175 GtkWidget *parent = 0;
176 if (m_ywidget->parent())
177 parent = YGWidget::get (m_ywidget->parent())->getWidget();
179 if (parent && YGTK_IS_FIXED (parent))
180 ygtk_fixed_set_child_size (YGTK_FIXED (parent), m_adj_size, width, height);
183 void YGWidget::emitEvent (YEvent::EventReason reason, EventFlags flags)
187 static gboolean dispatchEvent (gpointer data)
189 YWidgetEvent *
event = (YWidgetEvent *) data;
190 if (!YGUI::ui()->eventPendingFor (event->widget()))
191 YGUI::ui()->sendEvent (event);
196 if (reason == YEvent::ContextMenuActivated && !m_ywidget->notifyContextMenu())
198 if (flags & IGNORE_NOTIFY_EVENT || m_ywidget->notify()) {
199 YWidgetEvent *
event =
new YWidgetEvent (m_ywidget, reason);
200 if (flags & DELAY_EVENT)
201 g_timeout_add (250, inner::dispatchEvent, event);
202 else if (!(flags & IF_NOT_PENDING_EVENT) || !YGUI::ui()->eventPendingFor (m_ywidget))
203 YGUI::ui()->sendEvent (event);
207 void YGWidget::connect (gpointer
object,
const char *name, GCallback callback, gpointer data,
212 m_signals->connectSignal (G_OBJECT (
object), name, callback, data, after);
215 void YGWidget::blockSignals()
216 {
if (m_signals) m_signals->block(); }
217 void YGWidget::unblockSignals()
218 {
if (m_signals) m_signals->unblock(); }
220 void YGWidget::setBorder (
unsigned int border)
221 { gtk_container_set_border_width (GTK_CONTAINER (m_adj_size), border); }
225 YGLabeledWidget::YGLabeledWidget (YWidget *ywidget, YWidget *parent,
226 const std::string &label_text, YUIDimension label_ori,
227 GType type,
const char *property_name, ...)
230 GTK_TYPE_VBOX,
"spacing", LABEL_WIDGET_SPACING, NULL)
234 va_start (args, property_name);
235 m_field = GTK_WIDGET (g_object_new_valist (type, property_name, args));
239 m_label = gtk_label_new (
"");
240 gtk_misc_set_alignment (GTK_MISC (m_label), 0.0, 0.5);
243 gtk_widget_show (m_label);
244 gtk_widget_show (m_field);
247 doSetLabel (label_text);
250 gtk_box_pack_start (GTK_BOX (m_widget), m_label, FALSE, TRUE, 0);
251 gtk_box_pack_start (GTK_BOX (m_widget), m_field, TRUE, TRUE, 0);
252 m_orientation = label_ori;
255 void YGLabeledWidget::setLabelVisible (
bool show)
258 gtk_widget_show (m_label);
260 gtk_widget_hide (m_label);
263 void YGLabeledWidget::setBuddy (GtkWidget *widget)
265 gtk_label_set_mnemonic_widget (GTK_LABEL (m_label), widget);
268 void YGLabeledWidget::doSetLabel (
const std::string &label)
270 if (!label.empty()) {
271 std::string str (YGUtils::mapKBAccel (label));
275 const gchar *last = g_utf8_find_prev_char (str.c_str(), str.c_str() + str.length());
276 gunichar last_char = g_utf8_get_char (last);
277 if (g_unichar_isalpha (last_char)) {
278 bool reverse =
false;
279 if (gtk_widget_get_direction (m_label) == GTK_TEXT_DIR_RTL &&
280 pango_find_base_dir (str.c_str(), -1) == PANGO_DIRECTION_LTR)
283 int i = reverse ? 0 : str.length();
284 str.insert (i, 1,
':');
288 gtk_label_set_text (GTK_LABEL (m_label), str.c_str());
289 gtk_label_set_use_underline (GTK_LABEL (m_label), TRUE);
291 setLabelVisible (!label.empty());
295 #define MAX_SCROLL_WIDTH 120
297 YGScrolledWidget::YGScrolledWidget (YWidget *ywidget, YWidget *parent,
298 GType type,
const char *property_name, ...)
300 GTK_TYPE_SCROLLED_WINDOW,
"shadow-type", GTK_SHADOW_IN, NULL)
303 va_start (args, property_name);
304 construct(type, property_name, args);
306 setLabelVisible (
false);
309 YGScrolledWidget::YGScrolledWidget (YWidget *ywidget, YWidget *parent,
310 const std::string &label_text, YUIDimension label_ori,
311 GType type,
const char *property_name, ...)
313 GTK_TYPE_SCROLLED_WINDOW,
"shadow-type", GTK_SHADOW_IN, NULL)
316 va_start (args, property_name);
317 construct(type, property_name, args);
321 void YGScrolledWidget::construct (GType type,
const char *property_name,
324 m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args));
327 setPolicy (GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
328 gtk_container_add (GTK_CONTAINER (YGLabeledWidget::getWidget()), m_widget);
329 gtk_widget_show (m_widget);
332 void YGScrolledWidget::setPolicy (GtkPolicyType hpolicy, GtkPolicyType vpolicy)
334 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (YGLabeledWidget::getWidget()),