1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.RadioButton; 26 27 private import glib.ConstructionException; 28 private import glib.ListSG; 29 private import glib.Str; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.CheckButton; 33 private import gtk.Widget; 34 public import gtkc.gdktypes; 35 private import gtkc.gtk; 36 public import gtkc.gtktypes; 37 private import std.algorithm; 38 39 40 /** 41 * A single radio button performs the same basic function as a #GtkCheckButton, 42 * as its position in the object hierarchy reflects. It is only when multiple 43 * radio buttons are grouped together that they become a different user 44 * interface component in their own right. 45 * 46 * Every radio button is a member of some group of radio buttons. When one is 47 * selected, all other radio buttons in the same group are deselected. A 48 * #GtkRadioButton is one way of giving the user a choice from many options. 49 * 50 * Radio button widgets are created with gtk_radio_button_new(), passing %NULL 51 * as the argument if this is the first radio button in a group. In subsequent 52 * calls, the group you wish to add this button to should be passed as an 53 * argument. Optionally, gtk_radio_button_new_with_label() can be used if you 54 * want a text label on the radio button. 55 * 56 * Alternatively, when adding widgets to an existing group of radio buttons, 57 * use gtk_radio_button_new_from_widget() with a #GtkRadioButton that already 58 * has a group assigned to it. The convenience function 59 * gtk_radio_button_new_with_label_from_widget() is also provided. 60 * 61 * To retrieve the group a #GtkRadioButton is assigned to, use 62 * gtk_radio_button_get_group(). 63 * 64 * To remove a #GtkRadioButton from one group and make it part of a new one, 65 * use gtk_radio_button_set_group(). 66 * 67 * The group list does not need to be freed, as each #GtkRadioButton will remove 68 * itself and its list item when it is destroyed. 69 * 70 * # CSS nodes 71 * 72 * |[<!-- language="plain" --> 73 * radiobutton 74 * ├── radio 75 * ╰── <child> 76 * ]| 77 * 78 * A GtkRadioButton with indicator (see gtk_toggle_button_set_mode()) has a 79 * main CSS node with name radiobutton and a subnode with name radio. 80 * 81 * |[<!-- language="plain" --> 82 * button.radio 83 * ├── radio 84 * ╰── <child> 85 * ]| 86 * 87 * A GtkRadioButton without indicator changes the name of its main node 88 * to button and adds a .radio style class to it. The subnode is invisible 89 * in this case. 90 * 91 * ## How to create a group of two radio buttons. 92 * 93 * |[<!-- language="C" --> 94 * void create_radio_buttons (void) { 95 * 96 * GtkWidget *window, *radio1, *radio2, *box, *entry; 97 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 98 * box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); 99 * gtk_box_set_homogeneous (GTK_BOX (box), TRUE); 100 * 101 * // Create a radio button with a GtkEntry widget 102 * radio1 = gtk_radio_button_new (NULL); 103 * entry = gtk_entry_new (); 104 * gtk_container_add (GTK_CONTAINER (radio1), entry); 105 * 106 * 107 * // Create a radio button with a label 108 * radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1), 109 * "I’m the second radio button."); 110 * 111 * // Pack them into a box, then show all the widgets 112 * gtk_box_pack_start (GTK_BOX (box), radio1, TRUE, TRUE, 2); 113 * gtk_box_pack_start (GTK_BOX (box), radio2, TRUE, TRUE, 2); 114 * gtk_container_add (GTK_CONTAINER (window), box); 115 * gtk_widget_show_all (window); 116 * return; 117 * } 118 * ]| 119 * 120 * When an unselected button in the group is clicked the clicked button 121 * receives the #GtkToggleButton::toggled signal, as does the previously 122 * selected button. 123 * Inside the #GtkToggleButton::toggled handler, gtk_toggle_button_get_active() 124 * can be used to determine if the button has been selected or deselected. 125 */ 126 public class RadioButton : CheckButton 127 { 128 /** the main Gtk struct */ 129 protected GtkRadioButton* gtkRadioButton; 130 131 /** Get the main Gtk struct */ 132 public GtkRadioButton* getRadioButtonStruct() 133 { 134 return gtkRadioButton; 135 } 136 137 /** the main Gtk struct as a void* */ 138 protected override void* getStruct() 139 { 140 return cast(void*)gtkRadioButton; 141 } 142 143 protected override void setStruct(GObject* obj) 144 { 145 gtkRadioButton = cast(GtkRadioButton*)obj; 146 super.setStruct(obj); 147 } 148 149 /** 150 * Sets our main struct and passes it to the parent class. 151 */ 152 public this (GtkRadioButton* gtkRadioButton, bool ownedRef = false) 153 { 154 this.gtkRadioButton = gtkRadioButton; 155 super(cast(GtkCheckButton*)gtkRadioButton, ownedRef); 156 } 157 158 /** 159 * Creates a new RadioButton with a text label. 160 * Params: 161 * group = an existing radio button group. 162 * label = the text label to display next to the radio button. 163 * mnemonic = if true the label will be created using 164 * gtk_label_new_with_mnemonic(), so underscores in label indicate the 165 * mnemonic for the button. 166 * Throws: ConstructionException GTK+ fails to create the object. 167 */ 168 public this (ListSG group, string label, bool mnemonic=true) 169 { 170 GtkRadioButton* p; 171 172 if ( mnemonic ) 173 { 174 // GtkWidget* gtk_radio_button_new_with_mnemonic (GSList *group, const gchar *label); 175 p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic( 176 group is null ? null : group.getListSGStruct(), 177 Str.toStringz(label)); 178 } 179 else 180 { 181 // GtkWidget* gtk_radio_button_new_with_label (GSList *group, const gchar *label); 182 p = cast(GtkRadioButton*)gtk_radio_button_new_with_label( 183 group is null ? null : group.getListSGStruct(), 184 Str.toStringz(label)); 185 } 186 187 if(p is null) 188 { 189 throw new ConstructionException("null returned by gtk_radio_button_new_"); 190 } 191 192 this(p); 193 } 194 195 /** 196 * Creates a new RadioButton with a text label, adding it to the same group 197 * as group. 198 * Params: 199 * radioButton = an existing RadioButton. 200 * label = a text string to display next to the radio button. 201 * mnemonic = if true the label 202 * will be created using gtk_label_new_with_mnemonic(), so underscores 203 * in label indicate the mnemonic for the button. 204 * Throws: ConstructionException GTK+ fails to create the object. 205 */ 206 public this (RadioButton radioButton, string label, bool mnemonic=true) 207 { 208 GtkRadioButton* p; 209 210 if ( mnemonic ) 211 { 212 // GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *group, const gchar *label); 213 p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic_from_widget( 214 radioButton.getRadioButtonStruct(), 215 Str.toStringz(label)); 216 } 217 else 218 { 219 // GtkWidget* gtk_radio_button_new_with_label_from_widget (GtkRadioButton *group, const gchar *label); 220 p = cast(GtkRadioButton*)gtk_radio_button_new_with_label_from_widget( 221 radioButton.getRadioButtonStruct(), 222 Str.toStringz(label)); 223 } 224 225 if(p is null) 226 { 227 throw new ConstructionException("null returned by gtk_radio_button_new_"); 228 } 229 230 this(p); 231 } 232 233 /** 234 * Creates a new RadioButton with a text label, 235 * and creates a new group. 236 * Params: 237 * label = a text string to display next to the radio button. 238 * mnemonic = if true the label 239 * will be created using gtk_label_new_with_mnemonic(), so underscores 240 * in label indicate the mnemonic for the button. 241 * Throws: ConstructionException GTK+ fails to create the object. 242 */ 243 public this (string label, bool mnemonic=true) 244 { 245 this(cast(ListSG)null, label, mnemonic); 246 } 247 248 /** 249 */ 250 251 /** */ 252 public static GType getType() 253 { 254 return gtk_radio_button_get_type(); 255 } 256 257 /** 258 * Creates a new #GtkRadioButton. To be of any practical value, a widget should 259 * then be packed into the radio button. 260 * 261 * Params: 262 * group = an existing 263 * radio button group, or %NULL if you are creating a new group. 264 * 265 * Return: a new radio button 266 * 267 * Throws: ConstructionException GTK+ fails to create the object. 268 */ 269 public this(ListSG group) 270 { 271 auto p = gtk_radio_button_new((group is null) ? null : group.getListSGStruct()); 272 273 if(p is null) 274 { 275 throw new ConstructionException("null returned by new"); 276 } 277 278 this(cast(GtkRadioButton*) p); 279 } 280 281 /** 282 * Creates a new #GtkRadioButton, adding it to the same group as 283 * @radio_group_member. As with gtk_radio_button_new(), a widget 284 * should be packed into the radio button. 285 * 286 * Params: 287 * radioGroupMember = an existing #GtkRadioButton. 288 * 289 * Return: a new radio button. 290 * 291 * Throws: ConstructionException GTK+ fails to create the object. 292 */ 293 public this(RadioButton radioGroupMember) 294 { 295 auto p = gtk_radio_button_new_from_widget((radioGroupMember is null) ? null : radioGroupMember.getRadioButtonStruct()); 296 297 if(p is null) 298 { 299 throw new ConstructionException("null returned by new_from_widget"); 300 } 301 302 this(cast(GtkRadioButton*) p); 303 } 304 305 /** 306 * Retrieves the group assigned to a radio button. 307 * 308 * Return: a linked list 309 * containing all the radio buttons in the same group 310 * as @radio_button. The returned list is owned by the radio button 311 * and must not be modified or freed. 312 */ 313 public ListSG getGroup() 314 { 315 auto p = gtk_radio_button_get_group(gtkRadioButton); 316 317 if(p is null) 318 { 319 return null; 320 } 321 322 return new ListSG(cast(GSList*) p); 323 } 324 325 /** 326 * Joins a #GtkRadioButton object to the group of another #GtkRadioButton object 327 * 328 * Use this in language bindings instead of the gtk_radio_button_get_group() 329 * and gtk_radio_button_set_group() methods 330 * 331 * A common way to set up a group of radio buttons is the following: 332 * |[<!-- language="C" --> 333 * GtkRadioButton *radio_button; 334 * GtkRadioButton *last_button; 335 * 336 * while ( ...more buttons to add... ) 337 * { 338 * radio_button = gtk_radio_button_new (...); 339 * 340 * gtk_radio_button_join_group (radio_button, last_button); 341 * last_button = radio_button; 342 * } 343 * ]| 344 * 345 * Params: 346 * groupSource = a radio button object whos group we are 347 * joining, or %NULL to remove the radio button from its group 348 * 349 * Since: 3.0 350 */ 351 public void joinGroup(RadioButton groupSource) 352 { 353 gtk_radio_button_join_group(gtkRadioButton, (groupSource is null) ? null : groupSource.getRadioButtonStruct()); 354 } 355 356 /** 357 * Sets a #GtkRadioButton’s group. It should be noted that this does not change 358 * the layout of your interface in any way, so if you are changing the group, 359 * it is likely you will need to re-arrange the user interface to reflect these 360 * changes. 361 * 362 * Params: 363 * group = an existing radio 364 * button group, such as one returned from gtk_radio_button_get_group(), or %NULL. 365 */ 366 public void setGroup(ListSG group) 367 { 368 gtk_radio_button_set_group(gtkRadioButton, (group is null) ? null : group.getListSGStruct()); 369 } 370 371 protected class OnGroupChangedDelegateWrapper 372 { 373 void delegate(RadioButton) dlg; 374 gulong handlerId; 375 ConnectFlags flags; 376 this(void delegate(RadioButton) dlg, gulong handlerId, ConnectFlags flags) 377 { 378 this.dlg = dlg; 379 this.handlerId = handlerId; 380 this.flags = flags; 381 } 382 } 383 protected OnGroupChangedDelegateWrapper[] onGroupChangedListeners; 384 385 /** 386 * Emitted when the group of radio buttons that a radio button belongs 387 * to changes. This is emitted when a radio button switches from 388 * being alone to being part of a group of 2 or more buttons, or 389 * vice-versa, and when a button is moved from one group of 2 or 390 * more buttons to a different one, but not when the composition 391 * of the group that a button belongs to changes. 392 * 393 * Since: 2.4 394 */ 395 gulong addOnGroupChanged(void delegate(RadioButton) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 396 { 397 onGroupChangedListeners ~= new OnGroupChangedDelegateWrapper(dlg, 0, connectFlags); 398 onGroupChangedListeners[onGroupChangedListeners.length - 1].handlerId = Signals.connectData( 399 this, 400 "group-changed", 401 cast(GCallback)&callBackGroupChanged, 402 cast(void*)onGroupChangedListeners[onGroupChangedListeners.length - 1], 403 cast(GClosureNotify)&callBackGroupChangedDestroy, 404 connectFlags); 405 return onGroupChangedListeners[onGroupChangedListeners.length - 1].handlerId; 406 } 407 408 extern(C) static void callBackGroupChanged(GtkRadioButton* radiobuttonStruct,OnGroupChangedDelegateWrapper wrapper) 409 { 410 wrapper.dlg(wrapper.outer); 411 } 412 413 extern(C) static void callBackGroupChangedDestroy(OnGroupChangedDelegateWrapper wrapper, GClosure* closure) 414 { 415 wrapper.outer.internalRemoveOnGroupChanged(wrapper); 416 } 417 418 protected void internalRemoveOnGroupChanged(OnGroupChangedDelegateWrapper source) 419 { 420 foreach(index, wrapper; onGroupChangedListeners) 421 { 422 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 423 { 424 onGroupChangedListeners[index] = null; 425 onGroupChangedListeners = std.algorithm.remove(onGroupChangedListeners, index); 426 break; 427 } 428 } 429 } 430 431 }