libyui-gtk  2.49.0
YGFrame.cc
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 
5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
7 #include "YGUI.h"
8 #include "YGWidget.h"
9 #include "YGUtils.h"
10 
11 // Instead of traditional looking frames, we use Gnome convention for the
12 // frame's look. That is: don't draw a frame, use bold header and pad the child.
13 #define CHILD_INDENTATION 8
14 
15 class YGBaseFrame : public YGWidget
16 {
17 protected:
18 // a GtkAlignment to set some indentation on the child
19 GtkWidget *m_containee;
20 
21 public:
22  YGBaseFrame (YWidget *ywidget, YWidget *parent)
23  : YGWidget (ywidget, parent,
24  GTK_TYPE_FRAME, "shadow-type", GTK_SHADOW_NONE, NULL)
25  {
26 # if GTK_CHECK_VERSION (3, 14, 0)
27  m_containee = gtk_widget_new (GTK_TYPE_FRAME, NULL);
28 
29  gtk_widget_set_margin_top (m_containee, 0);
30  gtk_widget_set_margin_bottom (m_containee, 0);
31  gtk_widget_set_margin_start (m_containee, CHILD_INDENTATION);
32  gtk_widget_set_margin_end (m_containee, 0);
33 # else
34  m_containee = gtk_alignment_new (0, 0, 1, 1);
35 
36  gtk_alignment_set_padding (GTK_ALIGNMENT (m_containee),
37  0, 0, CHILD_INDENTATION, 0);
38 # endif
39 
40  gtk_widget_show (m_containee);
41  gtk_container_add (GTK_CONTAINER (getWidget()), m_containee);
42  }
43 
44  virtual GtkWidget *getContainer()
45  { return m_containee; }
46 };
47 
48 #include "YFrame.h"
49 
50 static GtkWidget *findFirstFocusable (GtkContainer *container)
51 {
52  g_return_val_if_fail (container != NULL, NULL);
53 
54  for (GList *l = gtk_container_get_children (container);
55  l; l = l->next) {
56  if (gtk_widget_get_can_focus (GTK_WIDGET(l->data)))
57  return GTK_WIDGET (l->data);
58  else if (GTK_IS_CONTAINER (l->data)) {
59  GtkWidget *ret = findFirstFocusable (GTK_CONTAINER (l->data));
60  if (ret)
61  return ret;
62  }
63  }
64  return NULL;
65 }
66 
67 extern "C" {
68  static gboolean
69  frame_label_mnemonic_activate (GtkWidget *widget,
70  gboolean group_cycling,
71  GtkContainer *frame_container)
72  {
73  GtkWidget *focusable = findFirstFocusable (frame_container);
74  if (focusable == NULL) {
75  g_warning ("no focusable widgets for mnemonic");
76  return FALSE;
77  } else
78  return gtk_widget_mnemonic_activate (focusable, group_cycling);
79  }
80 }
81 
82 class YGFrame : public YFrame, public YGBaseFrame
83 {
84 public:
85  YGFrame (YWidget *parent, const std::string &label)
86  : YFrame (NULL, label),
87  YGBaseFrame (this, parent)
88  {
89  GtkWidget *label_widget = gtk_label_new_with_mnemonic ("");
90  g_signal_connect (G_OBJECT (label_widget), "mnemonic_activate",
91  G_CALLBACK (frame_label_mnemonic_activate),
92  getWidget());
93  YGUtils::setWidgetFont (GTK_WIDGET (label_widget), PANGO_STYLE_NORMAL,
94  PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
95  gtk_widget_show (label_widget);
96  gtk_frame_set_label_widget (GTK_FRAME (getWidget()), label_widget);
97  setLabel (label);
98  }
99 
100  // YFrame
101  virtual void setLabel (const std::string &_str)
102  {
103  GtkWidget *label = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
104  std::string str (YGUtils::mapKBAccel (_str));
105  gtk_label_set_text_with_mnemonic (GTK_LABEL (label), str.c_str());
106  YFrame::setLabel (_str);
107  }
108 
109  YGWIDGET_IMPL_CONTAINER (YFrame)
110 
111  // YGWidget
112  virtual std::string getDebugLabel() const
113  { return label(); }
114 };
115 
116 
117 YFrame *YGWidgetFactory::createFrame (YWidget *parent, const std::string &label)
118 { return new YGFrame (parent, label); }
119 
120 #include "YCheckBoxFrame.h"
121 
122 class YGCheckBoxFrame : public YCheckBoxFrame, public YGBaseFrame
123 {
124 public:
125  YGCheckBoxFrame (YWidget *parent, const std::string &label, bool checked)
126  : YCheckBoxFrame (NULL, label, checked),
127  YGBaseFrame (this, parent)
128  {
129  GtkWidget *button = gtk_check_button_new_with_mnemonic("");
130  YGUtils::setWidgetFont (gtk_bin_get_child (GTK_BIN (button)), PANGO_STYLE_NORMAL,
131  PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
132  gtk_widget_show_all (button);
133  gtk_frame_set_label_widget (GTK_FRAME (getWidget()), button);
134 
135  setLabel (label);
136  setValue (checked);
137  connect (button, "toggled", G_CALLBACK (toggled_cb), this);
138  }
139 
140  // YCheckBoxFrame
141  virtual void setLabel (const std::string &_str)
142  {
143  GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
144  GtkLabel *label = GTK_LABEL (gtk_bin_get_child(GTK_BIN (button)));
145 
146  std::string str (YGUtils::mapKBAccel (_str));
147  gtk_label_set_text_with_mnemonic (label, str.c_str());
148  YCheckBoxFrame::setLabel (_str);
149  }
150 
151  bool value()
152  {
153  GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
154  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
155  }
156 
157  void setValue (bool value)
158  {
159  BlockEvents (this);
160  GtkWidget *button = gtk_frame_get_label_widget (GTK_FRAME (getWidget()));
161  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), value);
162  }
163 
164  // YGWidget
165  virtual void doSetEnabled (bool enabled)
166  {
167  GtkWidget *frame = getWidget();
168  if (enabled) {
169  gtk_widget_set_sensitive (frame, TRUE);
170  handleChildrenEnablement (value());
171  }
172  else {
173  gtk_widget_set_sensitive (frame, FALSE);
174  YWidget::setChildrenEnabled (false);
175  }
176  YWidget::setEnabled (enabled);
177  }
178 
179  YGWIDGET_IMPL_CONTAINER (YCheckBoxFrame)
180 
181 private:
182  static void toggled_cb (GtkWidget *widget, YGCheckBoxFrame *pThis)
183  {
184  pThis->setEnabled (true);
185  if (pThis->notify())
186  YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::ValueChanged));
187  }
188 };
189 
190 YCheckBoxFrame *YGWidgetFactory::createCheckBoxFrame (
191  YWidget *parent, const std::string &label, bool checked)
192 { return new YGCheckBoxFrame (parent, label, checked); }
193