+ combo.show();
+ alignment.add(combo);
+ }
+
+ auto row = DialogRow_new( name, alignment );
+ DialogVBox_packRow( vbox, row );
+}
+
+void Dialog::addCombo( ui::VBox vbox, const char* name, int& data, StringArrayRange values ){
+ addCombo(vbox, name, values, make_property(data));
+}
+
+void Dialog::addSlider( ui::VBox vbox, const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){
+#if 0
+ if ( draw_value == FALSE ) {
+ auto hbox2 = ui::HBox( FALSE, 0 );
+ hbox2.show();
+ vbox.pack_start( hbox2 , FALSE, FALSE, 0 );
+ {
+ ui::Widget label = ui::Label( low );
+ label.show();
+ hbox2.pack_start( label, FALSE, FALSE, 0 );
+ }
+ {
+ ui::Widget label = ui::Label( high );
+ label.show();
+ hbox2.pack_end(label, FALSE, FALSE, 0);
+ }
+ }
+#endif
+
+ // adjustment
+ auto adj = ui::Adjustment( value, lower, upper, step_increment, page_increment, 0 );
+ AddIntAdjustmentData(*GTK_ADJUSTMENT(adj), make_property(data));
+
+ // scale
+ auto alignment = ui::Alignment( 0.0, 0.5, 1.0, 0.0 );
+ alignment.show();
+
+ ui::Widget scale = ui::HScale( adj );
+ gtk_scale_set_value_pos( GTK_SCALE( scale ), GTK_POS_LEFT );
+ scale.show();
+ alignment.add(scale);
+
+ gtk_scale_set_draw_value( GTK_SCALE( scale ), draw_value );
+ gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
+
+ auto row = DialogRow_new( name, alignment );
+ DialogVBox_packRow( vbox, row );
+}
+
+void Dialog::addRadio( ui::VBox vbox, const char* name, StringArrayRange names, Property<int> const &cb ){
+ auto alignment = ui::Alignment( 0.0, 0.5, 0.0, 0.0 );
+ alignment.show();;
+ {
+ RadioHBox radioBox = RadioHBox_new( names );
+ alignment.add(radioBox.m_hbox);
+ AddIntRadioData( *GTK_RADIO_BUTTON( radioBox.m_radio ), cb );
+ }
+
+ auto row = DialogRow_new( name, alignment );
+ DialogVBox_packRow( vbox, row );
+}
+
+void Dialog::addRadio( ui::VBox vbox, const char* name, int& data, StringArrayRange names ){
+ addRadio(vbox, name, names, make_property(data));
+}
+
+void Dialog::addRadioIcons( ui::VBox vbox, const char* name, StringArrayRange icons, Property<int> const &cb ){
+ auto table = ui::Table(2, icons.last - icons.first, FALSE);
+ table.show();
+
+ gtk_table_set_row_spacings(table, 5);
+ gtk_table_set_col_spacings(table, 5);
+
+ GSList* group = 0;
+ ui::RadioButton radio{ui::null};
+ for ( StringArrayRange::Iterator icon = icons.first; icon != icons.last; ++icon )
+ {
+ guint pos = static_cast<guint>( icon - icons.first );
+ auto image = new_local_image( *icon );
+ image.show();
+ table.attach(image, {pos, pos + 1, 0, 1}, {0, 0});
+
+ radio = ui::RadioButton(GTK_RADIO_BUTTON(gtk_radio_button_new( group )));
+ radio.show();
+ table.attach(radio, {pos, pos + 1, 1, 2}, {0, 0});
+
+ group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radio ) );
+ }
+
+ AddIntRadioData( *GTK_RADIO_BUTTON( radio ), cb );
+
+ DialogVBox_packRow( vbox, DialogRow_new( name, table ) );
+}
+
+void Dialog::addRadioIcons( ui::VBox vbox, const char* name, int& data, StringArrayRange icons ){
+ addRadioIcons(vbox, name, icons, make_property(data));
+}
+
+ui::Widget Dialog::addIntEntry( ui::VBox vbox, const char* name, Property<int> const &cb ){
+ DialogEntryRow row( DialogEntryRow_new( name ) );
+ AddIntEntryData( *GTK_ENTRY(row.m_entry), cb );
+ DialogVBox_packRow( vbox, row.m_row );
+ return row.m_row;
+}
+
+ui::Widget Dialog::addSizeEntry( ui::VBox vbox, const char* name, Property<std::size_t> const &cb ){
+ DialogEntryRow row( DialogEntryRow_new( name ) );
+ AddSizeEntryData( *GTK_ENTRY(row.m_entry), cb );
+ DialogVBox_packRow( vbox, row.m_row );
+ return row.m_row;
+}
+
+ui::Widget Dialog::addFloatEntry( ui::VBox vbox, const char* name, Property<float> const &cb ){
+ DialogEntryRow row( DialogEntryRow_new( name ) );
+ AddFloatEntryData( *GTK_ENTRY(row.m_entry), cb );
+ DialogVBox_packRow( vbox, row.m_row );
+ return row.m_row;
+}
+
+ui::Widget Dialog::addPathEntry( ui::VBox vbox, const char* name, bool browse_directory, Property<const char *> const &cb ){
+ PathEntry pathEntry = PathEntry_new();
+ pathEntry.m_button.connect( "clicked", G_CALLBACK( browse_directory ? button_clicked_entry_browse_directory : button_clicked_entry_browse_file ), pathEntry.m_entry );
+
+ AddTextEntryData( *GTK_ENTRY(pathEntry.m_entry), cb );
+
+ auto row = DialogRow_new( name, ui::Widget(pathEntry.m_frame ) );
+ DialogVBox_packRow( vbox, row );
+
+ return row;
+}
+
+ui::Widget Dialog::addPathEntry( ui::VBox vbox, const char* name, CopiedString& data, bool browse_directory ){
+ return addPathEntry(vbox, name, browse_directory, make_property<CopiedString, const char *>(data));
+}
+
+ui::SpinButton Dialog::addSpinner( ui::VBox vbox, const char* name, double value, double lower, double upper, Property<int> const &cb ){
+ DialogSpinnerRow row( DialogSpinnerRow_new( name, value, lower, upper, 1 ) );
+ AddIntSpinnerData( *GTK_SPIN_BUTTON(row.m_spin), cb );
+ DialogVBox_packRow( vbox, row.m_row );
+ return row.m_spin;
+}
+
+ui::SpinButton Dialog::addSpinner( ui::VBox vbox, const char* name, int& data, double value, double lower, double upper ){
+ return addSpinner(vbox, name, value, lower, upper, make_property(data));
+}