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