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 private import gtk.c.functions; 35 public import gtk.c.types; 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(bool transferOwnership = false) 133 { 134 if (transferOwnership) 135 ownedRef = false; 136 return gtkRadioButton; 137 } 138 139 /** the main Gtk struct as a void* */ 140 protected override void* getStruct() 141 { 142 return cast(void*)gtkRadioButton; 143 } 144 145 protected override void setStruct(GObject* obj) 146 { 147 gtkRadioButton = cast(GtkRadioButton*)obj; 148 super.setStruct(obj); 149 } 150 151 /** 152 * Sets our main struct and passes it to the parent class. 153 */ 154 public this (GtkRadioButton* gtkRadioButton, bool ownedRef = false) 155 { 156 this.gtkRadioButton = gtkRadioButton; 157 super(cast(GtkCheckButton*)gtkRadioButton, ownedRef); 158 } 159 160 /** 161 * Creates a new RadioButton with a text label. 162 * Params: 163 * group = an existing radio button group. 164 * label = the text label to display next to the radio button. 165 * mnemonic = if true the label will be created using 166 * gtk_label_new_with_mnemonic(), so underscores in label indicate the 167 * mnemonic for the button. 168 * Throws: ConstructionException GTK+ fails to create the object. 169 */ 170 public this (ListSG group, string label, bool mnemonic=true) 171 { 172 GtkRadioButton* p; 173 174 if ( mnemonic ) 175 { 176 // GtkWidget* gtk_radio_button_new_with_mnemonic (GSList *group, const gchar *label); 177 p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic( 178 group is null ? null : group.getListSGStruct(), 179 Str.toStringz(label)); 180 } 181 else 182 { 183 // GtkWidget* gtk_radio_button_new_with_label (GSList *group, const gchar *label); 184 p = cast(GtkRadioButton*)gtk_radio_button_new_with_label( 185 group is null ? null : group.getListSGStruct(), 186 Str.toStringz(label)); 187 } 188 189 if(p is null) 190 { 191 throw new ConstructionException("null returned by gtk_radio_button_new_"); 192 } 193 194 this(p); 195 } 196 197 /** 198 * Creates a new RadioButton with a text label, adding it to the same group 199 * as group. 200 * Params: 201 * radioButton = an existing RadioButton. 202 * label = a text string to display next to the radio button. 203 * mnemonic = if true the label 204 * will be created using gtk_label_new_with_mnemonic(), so underscores 205 * in label indicate the mnemonic for the button. 206 * Throws: ConstructionException GTK+ fails to create the object. 207 */ 208 public this (RadioButton radioButton, string label, bool mnemonic=true) 209 { 210 GtkRadioButton* p; 211 212 if ( mnemonic ) 213 { 214 // GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *group, const gchar *label); 215 p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic_from_widget( 216 radioButton.getRadioButtonStruct(), 217 Str.toStringz(label)); 218 } 219 else 220 { 221 // GtkWidget* gtk_radio_button_new_with_label_from_widget (GtkRadioButton *group, const gchar *label); 222 p = cast(GtkRadioButton*)gtk_radio_button_new_with_label_from_widget( 223 radioButton.getRadioButtonStruct(), 224 Str.toStringz(label)); 225 } 226 227 if(p is null) 228 { 229 throw new ConstructionException("null returned by gtk_radio_button_new_"); 230 } 231 232 this(p); 233 } 234 235 /** 236 * Creates a new RadioButton with a text label, 237 * and creates a new group. 238 * Params: 239 * label = a text string to display next to the radio button. 240 * mnemonic = if true the label 241 * will be created using gtk_label_new_with_mnemonic(), so underscores 242 * in label indicate the mnemonic for the button. 243 * Throws: ConstructionException GTK+ fails to create the object. 244 */ 245 public this (string label, bool mnemonic=true) 246 { 247 this(cast(ListSG)null, label, mnemonic); 248 } 249 250 /** 251 */ 252 253 /** */ 254 public static GType getType() 255 { 256 return gtk_radio_button_get_type(); 257 } 258 259 /** 260 * Creates a new #GtkRadioButton. To be of any practical value, a widget should 261 * then be packed into the radio button. 262 * 263 * Params: 264 * group = an existing 265 * radio button group, or %NULL if you are creating a new group. 266 * 267 * Returns: a new radio button 268 * 269 * Throws: ConstructionException GTK+ fails to create the object. 270 */ 271 public this(ListSG group) 272 { 273 auto p = gtk_radio_button_new((group is null) ? null : group.getListSGStruct()); 274 275 if(p is null) 276 { 277 throw new ConstructionException("null returned by new"); 278 } 279 280 this(cast(GtkRadioButton*) p); 281 } 282 283 /** 284 * Creates a new #GtkRadioButton, adding it to the same group as 285 * @radio_group_member. As with gtk_radio_button_new(), a widget 286 * should be packed into the radio button. 287 * 288 * Params: 289 * radioGroupMember = an existing #GtkRadioButton. 290 * 291 * Returns: a new radio button. 292 * 293 * Throws: ConstructionException GTK+ fails to create the object. 294 */ 295 public this(RadioButton radioGroupMember) 296 { 297 auto p = gtk_radio_button_new_from_widget((radioGroupMember is null) ? null : radioGroupMember.getRadioButtonStruct()); 298 299 if(p is null) 300 { 301 throw new ConstructionException("null returned by new_from_widget"); 302 } 303 304 this(cast(GtkRadioButton*) p); 305 } 306 307 /** 308 * Retrieves the group assigned to a radio button. 309 * 310 * Returns: a linked list 311 * containing all the radio buttons in the same group 312 * as @radio_button. The returned list is owned by the radio button 313 * and must not be modified or freed. 314 */ 315 public ListSG getGroup() 316 { 317 auto p = gtk_radio_button_get_group(gtkRadioButton); 318 319 if(p is null) 320 { 321 return null; 322 } 323 324 return new ListSG(cast(GSList*) p); 325 } 326 327 /** 328 * Joins a #GtkRadioButton object to the group of another #GtkRadioButton object 329 * 330 * Use this in language bindings instead of the gtk_radio_button_get_group() 331 * and gtk_radio_button_set_group() methods 332 * 333 * A common way to set up a group of radio buttons is the following: 334 * |[<!-- language="C" --> 335 * GtkRadioButton *radio_button; 336 * GtkRadioButton *last_button; 337 * 338 * while ( ...more buttons to add... ) 339 * { 340 * radio_button = gtk_radio_button_new (...); 341 * 342 * gtk_radio_button_join_group (radio_button, last_button); 343 * last_button = radio_button; 344 * } 345 * ]| 346 * 347 * Params: 348 * groupSource = a radio button object whos group we are 349 * joining, or %NULL to remove the radio button from its group 350 * 351 * Since: 3.0 352 */ 353 public void joinGroup(RadioButton groupSource) 354 { 355 gtk_radio_button_join_group(gtkRadioButton, (groupSource is null) ? null : groupSource.getRadioButtonStruct()); 356 } 357 358 /** 359 * Sets a #GtkRadioButton’s group. It should be noted that this does not change 360 * the layout of your interface in any way, so if you are changing the group, 361 * it is likely you will need to re-arrange the user interface to reflect these 362 * changes. 363 * 364 * Params: 365 * group = an existing radio 366 * button group, such as one returned from gtk_radio_button_get_group(), or %NULL. 367 */ 368 public void setGroup(ListSG group) 369 { 370 gtk_radio_button_set_group(gtkRadioButton, (group is null) ? null : group.getListSGStruct()); 371 } 372 373 protected class OnGroupChangedDelegateWrapper 374 { 375 void delegate(RadioButton) dlg; 376 gulong handlerId; 377 378 this(void delegate(RadioButton) dlg) 379 { 380 this.dlg = dlg; 381 onGroupChangedListeners ~= this; 382 } 383 384 void remove(OnGroupChangedDelegateWrapper source) 385 { 386 foreach(index, wrapper; onGroupChangedListeners) 387 { 388 if (wrapper.handlerId == source.handlerId) 389 { 390 onGroupChangedListeners[index] = null; 391 onGroupChangedListeners = std.algorithm.remove(onGroupChangedListeners, index); 392 break; 393 } 394 } 395 } 396 } 397 OnGroupChangedDelegateWrapper[] onGroupChangedListeners; 398 399 /** 400 * Emitted when the group of radio buttons that a radio button belongs 401 * to changes. This is emitted when a radio button switches from 402 * being alone to being part of a group of 2 or more buttons, or 403 * vice-versa, and when a button is moved from one group of 2 or 404 * more buttons to a different one, but not when the composition 405 * of the group that a button belongs to changes. 406 * 407 * Since: 2.4 408 */ 409 gulong addOnGroupChanged(void delegate(RadioButton) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 410 { 411 auto wrapper = new OnGroupChangedDelegateWrapper(dlg); 412 wrapper.handlerId = Signals.connectData( 413 this, 414 "group-changed", 415 cast(GCallback)&callBackGroupChanged, 416 cast(void*)wrapper, 417 cast(GClosureNotify)&callBackGroupChangedDestroy, 418 connectFlags); 419 return wrapper.handlerId; 420 } 421 422 extern(C) static void callBackGroupChanged(GtkRadioButton* radiobuttonStruct, OnGroupChangedDelegateWrapper wrapper) 423 { 424 wrapper.dlg(wrapper.outer); 425 } 426 427 extern(C) static void callBackGroupChangedDestroy(OnGroupChangedDelegateWrapper wrapper, GClosure* closure) 428 { 429 wrapper.remove(wrapper); 430 } 431 }