File indexing completed on 2024-05-05 05:34:56
0001 /* 0002 this file is part of the oxygen gtk engine 0003 SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0004 0005 based on the Null Theme Engine for Gtk+. 0006 SPDX-FileCopyrightText: 2008 Robert Staudinger <robert.staudinger@gmail.com> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "oxygendemodialog.h" 0012 #include "oxygeninputdemowidget.h" 0013 #include "oxygeninfowidget.h" 0014 #include "oxygenbuttondemowidget.h" 0015 #include "oxygenframedemowidget.h" 0016 #include "oxygenlistdemowidget.h" 0017 #include "oxygensliderdemowidget.h" 0018 #include "oxygentabdemowidget.h" 0019 0020 #include <gdk/gdkkeysyms.h> 0021 0022 // Older (such as 2.20.1) GTK versions had different name for this 0023 #ifndef GDK_KEY_Q 0024 #define GDK_KEY_Q GDK_Q 0025 #endif 0026 0027 #include <iostream> 0028 #include <sstream> 0029 0030 namespace Oxygen 0031 { 0032 0033 //_____________________________________________ 0034 DemoDialog::DemoDialog( void ) 0035 { 0036 0037 // create main widget 0038 _mainWidget = gtk_window_new( GTK_WINDOW_TOPLEVEL ); 0039 gtk_window_set_default_size( GTK_WINDOW( _mainWidget ), 630, 500 ); 0040 gtk_window_set_title( GTK_WINDOW( _mainWidget ), "Oxygen-gtk Demo" ); 0041 gtk_container_set_border_width( GTK_CONTAINER( _mainWidget ), 10 ); 0042 0043 // vertical container 0044 GtkWidget* vbox( gtk_vbox_new( false, 5 ) ); 0045 gtk_container_add( GTK_CONTAINER( _mainWidget ), vbox ); 0046 gtk_widget_show( vbox ); 0047 0048 GtkWidget* iconView(0L); 0049 { 0050 // first horizontal container 0051 GtkWidget* hbox( gtk_hbox_new( false, 8 ) ); 0052 gtk_box_pack_start( GTK_BOX( vbox ), hbox, true, true, 0 ); 0053 gtk_widget_show( hbox ); 0054 0055 // iconview model 0056 _model = gtk_list_store_new( 2, GDK_TYPE_PIXBUF, G_TYPE_STRING ); 0057 0058 // inconview 0059 GtkWidget* scrolledWindow( gtk_scrolled_window_new( 0L, 0L ) ); 0060 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_SHADOW_IN ); 0061 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolledWindow ), GTK_POLICY_NEVER, GTK_POLICY_NEVER ); 0062 gtk_box_pack_start( GTK_BOX( hbox ), scrolledWindow, false, true, 0 ); 0063 gtk_widget_show( scrolledWindow ); 0064 0065 iconView = gtk_icon_view_new_with_model( GTK_TREE_MODEL( _model ) ); 0066 gtk_icon_view_set_pixbuf_column( GTK_ICON_VIEW( iconView ), 0 ); 0067 gtk_icon_view_set_text_column( GTK_ICON_VIEW( iconView ), 1 ); 0068 gtk_icon_view_set_columns( GTK_ICON_VIEW( iconView ), 1 ); 0069 0070 gtk_icon_view_set_item_width( GTK_ICON_VIEW( iconView ), 108 ); 0071 gtk_icon_view_set_spacing( GTK_ICON_VIEW( iconView ), 0 ); 0072 gtk_icon_view_set_margin( GTK_ICON_VIEW( iconView ), 0 ); 0073 gtk_icon_view_set_column_spacing( GTK_ICON_VIEW( iconView ), 0 ); 0074 gtk_icon_view_set_row_spacing( GTK_ICON_VIEW( iconView ), 0 ); 0075 gtk_icon_view_set_selection_mode( GTK_ICON_VIEW( iconView ), GTK_SELECTION_BROWSE ); 0076 0077 // get list of renderers, find text renderer and make font format bold 0078 GList* cells( gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( iconView ) ) ); 0079 for( GList *cell = g_list_first( cells ); cell; cell = g_list_next( cell ) ) 0080 { 0081 if( !GTK_IS_CELL_RENDERER_TEXT( cell->data ) ) continue; 0082 0083 // create pango attributes list 0084 PangoAttrList* attributes( pango_attr_list_new() ); 0085 pango_attr_list_insert( attributes, pango_attr_weight_new( PANGO_WEIGHT_BOLD ) ); 0086 0087 GValue val = { 0, }; 0088 g_value_init(&val, PANGO_TYPE_ATTR_LIST ); 0089 g_value_set_boxed( &val, attributes ); 0090 g_object_set_property( G_OBJECT( cell->data ), "attributes", &val ); 0091 0092 pango_attr_list_unref( attributes ); 0093 0094 } 0095 0096 if( cells ) g_list_free( cells ); 0097 0098 // connect signals 0099 connect( G_OBJECT(iconView), "selection-changed", G_CALLBACK( selectionChanged ), this ); 0100 0101 gtk_container_add( GTK_CONTAINER( scrolledWindow ), iconView ); 0102 gtk_widget_show( iconView ); 0103 0104 // notebook 0105 _notebook = gtk_notebook_new(); 0106 gtk_notebook_set_show_tabs( GTK_NOTEBOOK( _notebook ), false ); 0107 gtk_box_pack_start( GTK_BOX( hbox ), _notebook, true, true, 0 ); 0108 gtk_widget_show( _notebook ); 0109 0110 } 0111 0112 { 0113 // statusbar 0114 GtkWidget* statusBar( gtk_hbox_new( false, 2 ) ); 0115 gtk_box_pack_start( GTK_BOX( vbox ), statusBar, false, true, 0 ); 0116 gtk_widget_show( statusBar ); 0117 0118 // enable checkbox 0119 _stateButton = gtk_check_button_new_with_label( "Enabled" ); 0120 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _stateButton ), true ); 0121 gtk_box_pack_start( GTK_BOX( statusBar ), _stateButton, false, false, 0 ); 0122 gtk_widget_show( _stateButton ); 0123 0124 connect( G_OBJECT(_stateButton), "toggled", G_CALLBACK( toggleEnableState ), this ); 0125 0126 // widget direction checkbox 0127 GtkWidget* button( gtk_check_button_new_with_label( "Right to left layout" ) ); 0128 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( button ), false ); 0129 gtk_box_pack_start( GTK_BOX( statusBar ), button, false, false, 0 ); 0130 gtk_widget_show( button ); 0131 0132 connect( G_OBJECT(button), "toggled", G_CALLBACK( toggleWidgetDirection ), 0L ); 0133 0134 // button box 0135 #if GTK_CHECK_VERSION( 3, 0, 0 ) 0136 GtkWidget* buttonBox( gtk_button_box_new( GTK_ORIENTATION_HORIZONTAL) ); 0137 #else 0138 GtkWidget* buttonBox( gtk_hbutton_box_new() ); 0139 #endif 0140 0141 gtk_button_box_set_layout( GTK_BUTTON_BOX( buttonBox ), GTK_BUTTONBOX_END ); 0142 gtk_box_pack_end( GTK_BOX( statusBar ), buttonBox, true, true, 0 ); 0143 gtk_widget_show( buttonBox ); 0144 0145 // close button 0146 button = gtk_button_new_from_stock( GTK_STOCK_OK ); 0147 gtk_box_pack_end( GTK_BOX( buttonBox ), button, false, true, 0 ); 0148 gtk_widget_show( button ); 0149 0150 connect( G_OBJECT(button), "clicked", G_CALLBACK( gtk_main_quit ), 0L ); 0151 0152 } 0153 0154 addPage( new InputDemoWidget() ); 0155 addPage( new TabDemoWidget() ); 0156 addPage( new ButtonDemoWidget() ); 0157 addPage( new ListDemoWidget() ); 0158 addPage( new FrameDemoWidget() ); 0159 addPage( _sliderDemoWidget = new SliderDemoWidget() ); 0160 addPage( new InfoWidget() ); 0161 0162 // select first raw 0163 GtkTreePath *path( gtk_tree_path_new_from_indices(0, -1 ) ); 0164 gtk_icon_view_select_path( GTK_ICON_VIEW( iconView ), path ); 0165 gtk_tree_path_free( path ); 0166 0167 // keypress signals 0168 connect( G_OBJECT(_mainWidget), "key-press-event", G_CALLBACK( keyPress ), 0L ); 0169 0170 } 0171 0172 //_____________________________________________ 0173 DemoDialog::~DemoDialog( void ) 0174 { 0175 // delete pages 0176 for( PageMap::iterator iter = _pages.begin(); iter != _pages.end(); ++iter ) 0177 { delete iter->second; } 0178 } 0179 0180 //_____________________________________________ 0181 void DemoDialog::addPage( DemoWidget* page ) 0182 { 0183 // get icon 0184 GdkPixbuf* icon( 0L ); 0185 if( !page->iconName().empty() ) 0186 { 0187 0188 // TODO: should get this icon size from options 0189 GtkIconTheme* theme( gtk_icon_theme_get_default() ); 0190 icon = gtk_icon_theme_load_icon( theme, page->iconName().c_str(), 32, (GtkIconLookupFlags) 0, 0L ); 0191 0192 } 0193 0194 // insert in list 0195 GtkTreeIter iter; 0196 gtk_list_store_append( _model, &iter ); 0197 gtk_list_store_set( _model, &iter, 0, icon, 1, page->name().c_str(), -1 ); 0198 0199 // add to notebook 0200 int index( gtk_notebook_append_page( GTK_NOTEBOOK( _notebook ), page->mainWidget(), 0L ) ); 0201 gtk_widget_show( page->mainWidget() ); 0202 0203 _pages.insert( std::make_pair( index, page ) ); 0204 } 0205 0206 //_____________________________________________ 0207 void DemoDialog::selectionChanged( GtkIconView* view, gpointer data ) 0208 { 0209 // get pointer to dialog 0210 DemoDialog& dialog( *static_cast<DemoDialog*>( data ) ); 0211 0212 // get selection 0213 GList* selection = gtk_icon_view_get_selected_items( view ); 0214 if( !selection ) return; 0215 0216 // get first child 0217 GtkTreePath* path( static_cast<GtkTreePath*>( g_list_first( selection )->data ) ); 0218 const int page( gtk_tree_path_get_indices( path )[0] ); 0219 gtk_notebook_set_current_page( GTK_NOTEBOOK( dialog._notebook ), page ); 0220 0221 // explicitly free path contained in list to avoir mem leak, before calling g_list_free 0222 for( GList *child = g_list_first( selection ); child; child = g_list_next( child ) ) 0223 { gtk_tree_path_free( static_cast<GtkTreePath*>( child->data ) ); } 0224 0225 g_list_free( selection ); 0226 0227 // store enable state 0228 const bool enabled( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dialog._stateButton ) ) ); 0229 0230 // get matching page 0231 DemoWidget* widget( dialog._pages[page] ); 0232 widget->setEnabled( enabled ); 0233 if( widget == dialog._sliderDemoWidget ) dialog._sliderDemoWidget->startPulse(); 0234 else dialog._sliderDemoWidget->stopPulse(); 0235 0236 // update window title 0237 std::ostringstream what; 0238 what << widget->name() << " - Oxygen-gtk Demo"; 0239 gtk_window_set_title( GTK_WINDOW( dialog._mainWidget ), what.str().c_str() ); 0240 } 0241 0242 //_____________________________________________ 0243 void DemoDialog::toggleEnableState( GtkToggleButton* button, gpointer data ) 0244 { 0245 0246 // get pointer to dialog 0247 DemoDialog& dialog( *static_cast<DemoDialog*>( data ) ); 0248 0249 // store enable state 0250 const bool enabled( gtk_toggle_button_get_active( button ) ); 0251 0252 // get current page 0253 const int page( gtk_notebook_get_current_page( GTK_NOTEBOOK( dialog._notebook ) ) ); 0254 0255 // get matching page 0256 DemoWidget* widget( dialog._pages[page] ); 0257 0258 // set state 0259 widget->setEnabled( enabled ); 0260 0261 // trigger repaint 0262 gtk_widget_queue_draw( widget->mainWidget() ); 0263 0264 } 0265 0266 //_____________________________________________ 0267 void DemoDialog::toggleWidgetDirection( GtkToggleButton* button, gpointer data ) 0268 { gtk_widget_set_default_direction( gtk_toggle_button_get_active( button ) ? GTK_TEXT_DIR_RTL:GTK_TEXT_DIR_LTR ); } 0269 0270 //_____________________________________________ 0271 gboolean DemoDialog::keyPress( GtkWidget* widget, GdkEventKey* event, gpointer ) 0272 { 0273 guint modifiers( gtk_accelerator_get_default_mod_mask() ); 0274 if( gdk_keyval_to_upper( event->keyval ) == GDK_KEY_Q && (event->state&modifiers) == GDK_CONTROL_MASK ) 0275 { 0276 gtk_main_quit(); 0277 return TRUE; 0278 } 0279 0280 return FALSE; 0281 } 0282 0283 }