libyui-gtk  2.44.9
YGRadioButton.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 "YGUtils.h"
9 #include "YGWidget.h"
10 
11 // Sub-class GtkRadioButton to get a widget that renders like
12 // a radio-button, but behaves like a check/toggle-button.
13 static GType getCheckRadioButtonType()
14 {
15  static GType type = 0;
16 
17  if (type)
18  return type;
19 
20  static const GTypeInfo info = {
21  sizeof (GtkRadioButtonClass), NULL, NULL,
22  NULL, NULL, NULL,
23  sizeof (GtkRadioButton), 0, NULL
24  };
25  type = g_type_register_static (GTK_TYPE_RADIO_BUTTON, "YGRadioButton",
26  &info, GTypeFlags(0));
27  // save a class_init function
28  GtkButtonClass *klass_new = GTK_BUTTON_CLASS (g_type_class_ref (type));
29  GtkButtonClass *klass_sane =
30  GTK_BUTTON_CLASS (g_type_class_ref (GTK_TYPE_TOGGLE_BUTTON));
31  klass_new->clicked = klass_sane->clicked;
32  return type;
33 }
34 
35 #include "YLayoutBox.h"
36 
37 static bool is_horizontal_box (YWidget *widget)
38 {
39  YLayoutBox *box = dynamic_cast <YLayoutBox *> (widget);
40  if (box)
41  return box->primary() == YD_HORIZ;
42  return false;
43 }
44 
45 #include "YRadioButton.h"
46 #include "YRadioButtonGroup.h"
47 
48 class YGRadioButton : public YRadioButton, public YGWidget
49 {
50 public:
51  YGRadioButton (YWidget *parent, const std::string &label, bool isChecked)
52  : YRadioButton (NULL, label),
53  YGWidget (this, parent, getCheckRadioButtonType(), NULL)
54  {
55  if (!is_horizontal_box (parent))
56  setStretchable (YD_HORIZ, true);
57  setLabel (label);
58  gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE);
59  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), FALSE);
60 
61  connect (getWidget(), "toggled", G_CALLBACK (toggled_cb), this);
62  }
63 
64  // YRadioButton
65  virtual void setLabel (const std::string &text)
66  {
67  // NOTE: we can't just set a gtk_widget_modify() at the initialization
68  // because each gtk_button_set_label() creates a new label
69  std::string str = YGUtils::mapKBAccel(text.c_str());
70  gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str());
71  YRadioButton::setLabel (text);
72  }
73 
74  virtual bool value()
75  { return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (getWidget())); }
76 
77  virtual void setValue (bool checked)
78  {
79  BlockEvents block (this);
80  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), checked);
81  if (checked) {
82  YRadioButton *yradio = static_cast <YRadioButton *> (m_ywidget);
83  if (buttonGroup())
84  buttonGroup()->uncheckOtherButtons (yradio);
85  }
86  }
87 
88  YGWIDGET_IMPL_COMMON (YRadioButton)
89  YGWIDGET_IMPL_USE_BOLD (YRadioButton)
90 
91  // callbacks
92  static void toggled_cb (GtkButton *button, YGRadioButton *pThis)
93  {
94  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
95  pThis->emitEvent (YEvent::ValueChanged);
96  pThis->setValue (true);
97  }
98 };
99 
100 YRadioButton *YGWidgetFactory::createRadioButton (YWidget *parent, const std::string &label,
101  bool isChecked)
102 {
103  YRadioButton *button = new YGRadioButton (parent, label, isChecked);
104 
105  // libyui instructs us to do it here due to vfuncs craziness
106  YRadioButtonGroup *group = button->buttonGroup();
107  if (group)
108  group->addRadioButton (button);
109  button->setValue (isChecked);
110  return button;
111 }
112 
113 class YGRadioButtonGroup : public YRadioButtonGroup, public YGWidget
114 {
115 public:
116  YGRadioButtonGroup(YWidget *parent)
117  : YRadioButtonGroup (NULL),
118  YGWidget (this, parent, GTK_TYPE_EVENT_BOX, NULL)
119  {
120  setBorder (0);
121  }
122 
123  YGWIDGET_IMPL_CONTAINER (YRadioButtonGroup)
124 };
125 
126 YRadioButtonGroup *YGWidgetFactory::createRadioButtonGroup (YWidget *parent)
127 {
128  return new YGRadioButtonGroup (parent);
129 }
130 
131 #include "YCheckBox.h"
132 
133 class YGCheckBox : public YCheckBox, public YGWidget
134 {
135  bool m_isBold;
136 
137 public:
138  YGCheckBox(YWidget *parent, const std::string &label, bool isChecked)
139  : YCheckBox (NULL, label),
140  YGWidget (this, parent, GTK_TYPE_CHECK_BUTTON, NULL)
141  {
142  if (!is_horizontal_box (parent))
143  setStretchable (YD_HORIZ, true);
144  setLabel (label);
145  gtk_button_set_use_underline (GTK_BUTTON (getWidget()), TRUE);
146  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (getWidget()), isChecked);
147 
148  connect (getWidget(), "toggled", G_CALLBACK (toggled_cb), this);
149  }
150 
151  // YCheckButton
152  virtual void setLabel (const std::string &text)
153  {
154  std::string str = YGUtils::mapKBAccel(text);
155  gtk_button_set_label (GTK_BUTTON (getWidget()), str.c_str());
156  YCheckBox::setLabel (text);
157  }
158 
159  virtual YCheckBoxState value()
160  {
161  GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget());
162 
163  if (gtk_toggle_button_get_inconsistent (button))
164  return YCheckBox_dont_care;
165  return gtk_toggle_button_get_active (button) ? YCheckBox_on : YCheckBox_off;
166  }
167 
168  virtual void setValue (YCheckBoxState value)
169  {
170  BlockEvents block (this);
171  GtkToggleButton *button = GTK_TOGGLE_BUTTON (getWidget());
172  switch (value) {
173  case YCheckBox_dont_care:
174  gtk_toggle_button_set_inconsistent (button, TRUE);
175  break;
176  case YCheckBox_on:
177  gtk_toggle_button_set_inconsistent (button, FALSE);
178  gtk_toggle_button_set_active (button, TRUE);
179  break;
180  case YCheckBox_off:
181  gtk_toggle_button_set_inconsistent (button, FALSE);
182  gtk_toggle_button_set_active (button, FALSE);
183  break;
184  }
185  }
186 
187  static void toggled_cb (GtkBox *box, YGCheckBox *pThis)
188  {
189  GtkToggleButton *button = GTK_TOGGLE_BUTTON (box);
190  if (gtk_toggle_button_get_inconsistent (button))
191  pThis->setValue (YCheckBox_on);
192  pThis->emitEvent (YEvent::ValueChanged);
193  }
194 
195  YGWIDGET_IMPL_COMMON (YCheckBox)
196  YGWIDGET_IMPL_USE_BOLD (YCheckBox)
197 };
198 
199 YCheckBox *YGWidgetFactory::createCheckBox (YWidget *parent, const std::string &label,
200  bool isChecked)
201 { return new YGCheckBox (parent, label, isChecked); }
202