1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     GTK toolbar 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "tbargtk.h" 
  14 #include "wx/toolbar.h" 
  21 //----------------------------------------------------------------------------- 
  23 //----------------------------------------------------------------------------- 
  25 extern void wxapp_install_idle_handler(); 
  28 //----------------------------------------------------------------------------- 
  30 //----------------------------------------------------------------------------- 
  32 extern bool   g_blockEventsOnDrag
; 
  34 //----------------------------------------------------------------------------- 
  35 // "clicked" (internal from gtk_toolbar) 
  36 //----------------------------------------------------------------------------- 
  38 static void gtk_toolbar_callback( GtkWidget 
*WXUNUSED(widget
), wxToolBarTool 
*tool 
) 
  40     if (g_isIdle
) wxapp_install_idle_handler(); 
  42     if (g_blockEventsOnDrag
) return; 
  43     if (!tool
->m_enabled
) return; 
  45     if (tool
->m_isToggle
) tool
->m_toggleState 
= !tool
->m_toggleState
; 
  47     tool
->m_owner
->OnLeftClick( tool
->m_index
, tool
->m_toggleState 
); 
  50 //----------------------------------------------------------------------------- 
  51 // "enter_notify_event" 
  52 //----------------------------------------------------------------------------- 
  54 static gint 
gtk_toolbar_enter_callback( GtkWidget 
*WXUNUSED(widget
),  
  55   GdkEventCrossing 
*WXUNUSED(gdk_event
), wxToolBarTool 
*tool 
) 
  57     if (g_isIdle
) wxapp_install_idle_handler(); 
  59     if (g_blockEventsOnDrag
) return TRUE
; 
  61     /* we grey-out the tip text of disabled tool */ 
  63     wxToolBar 
*tb 
= tool
->m_owner
; 
  67         if (tb
->m_fg
->red 
!= 0) 
  72             gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb
->m_toolbar
) ), tb
->m_fg 
); 
  74 #if (GTK_MINOR_VERSION > 0) 
  78                    GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
->tip_window 
) ); 
  80             g_style
->fg
[GTK_STATE_NORMAL
] = *tb
->m_fg
; 
  81             gtk_widget_set_style( GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
->tip_window
, g_style 
); 
  83             gtk_tooltips_set_colors( GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
, tb
->m_bg
, tb
->m_fg 
); 
  89         if (tb
->m_fg
->red 
== 0) 
  91             tb
->m_fg
->red 
= 33000; 
  92             tb
->m_fg
->green 
= 33000; 
  93             tb
->m_fg
->blue 
= 33000; 
  94             gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb
->m_toolbar
) ), tb
->m_fg 
); 
  95 #if (GTK_MINOR_VERSION > 0) 
  99                    GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
->tip_window 
) ); 
 101             g_style
->fg
[GTK_STATE_NORMAL
] = *tb
->m_fg
; 
 102             gtk_widget_set_style( GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
->tip_window
, g_style 
); 
 104             gtk_tooltips_set_colors( GTK_TOOLBAR(tb
->m_toolbar
)->tooltips
, tb
->m_bg
, tb
->m_fg 
); 
 111     tb
->OnMouseEnter( tool
->m_index 
); 
 116 //----------------------------------------------------------------------------- 
 118 //----------------------------------------------------------------------------- 
 120 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
,wxControl
) 
 122 BEGIN_EVENT_TABLE(wxToolBar
, wxControl
) 
 123   EVT_IDLE(wxToolBar::OnIdle
) 
 126 wxToolBar::wxToolBar() 
 130 wxToolBar::wxToolBar( wxWindow 
*parent
, wxWindowID id
, 
 131   const wxPoint
& pos
, const wxSize
& size
, 
 132   long style
, const wxString
& name 
) 
 134     Create( parent
, id
, pos
, size
, style
, name 
); 
 137 wxToolBar::~wxToolBar() 
 143 bool wxToolBar::Create( wxWindow 
*parent
, wxWindowID id
, 
 144   const wxPoint
& pos
, const wxSize
& size
, 
 145   long style
, const wxString
& name 
) 
 149     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 151     m_tools
.DeleteContents( TRUE 
); 
 153     m_toolbar 
= GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL
, 
 154                                               GTK_TOOLBAR_ICONS 
) ); 
 157     gtk_toolbar_set_space_size( m_toolbar
, m_separation 
); 
 158     m_hasToolAlready 
= FALSE
; 
 160     if (style 
& wxTB_DOCKABLE
) 
 162         m_widget 
= gtk_handle_box_new(); 
 163         gtk_container_add( GTK_CONTAINER(m_widget
), GTK_WIDGET(m_toolbar
) ); 
 164         gtk_widget_show( GTK_WIDGET(m_toolbar
) ); 
 166         if (style 
& wxTB_FLAT
) 
 167             gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget
), GTK_SHADOW_NONE 
); 
 171         m_widget 
= GTK_WIDGET(m_toolbar
); 
 174     gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar
), TRUE 
); 
 176 #if (GTK_MINOR_VERSION > 0) 
 177     if (style 
& wxTB_FLAT
) 
 178         gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar
), GTK_RELIEF_NONE 
); 
 185     gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar
) ), m_fg 
); 
 191     gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar
) ), m_bg 
); 
 193 #if (GTK_MINOR_VERSION > 0) 
 194     gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar
)->tooltips 
); 
 198          gtk_widget_get_style(  
 199             GTK_TOOLBAR(m_toolbar
)->tooltips
->tip_window 
) ); 
 201     g_style
->bg
[GTK_STATE_NORMAL
] = *m_bg
; 
 202     gtk_widget_set_style( GTK_TOOLBAR(m_toolbar
)->tooltips
->tip_window
, g_style 
); 
 204     gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar
)->tooltips
, m_bg
, m_fg 
); 
 210     m_parent
->AddChild( this ); 
 212     (m_parent
->m_insertCallback
)( m_parent
, this ); 
 221 bool wxToolBar::OnLeftClick( int toolIndex
, bool toggleDown 
) 
 223     wxCommandEvent 
event( wxEVT_COMMAND_TOOL_CLICKED
, toolIndex 
); 
 224     event
.SetEventObject(this); 
 225     event
.SetInt( toolIndex 
); 
 226     event
.SetExtraLong((long) toggleDown
); 
 228     GetEventHandler()->ProcessEvent(event
); 
 233 void wxToolBar::OnRightClick( int toolIndex
, float WXUNUSED(x
), float WXUNUSED(y
) ) 
 235     wxCommandEvent 
event( wxEVT_COMMAND_TOOL_RCLICKED
, toolIndex 
); 
 236     event
.SetEventObject( this ); 
 237     event
.SetInt( toolIndex 
); 
 239     GetEventHandler()->ProcessEvent(event
); 
 242 void wxToolBar::OnMouseEnter( int toolIndex 
) 
 244     wxCommandEvent 
event( wxEVT_COMMAND_TOOL_ENTER
, GetId() ); 
 245     event
.SetEventObject(this); 
 246     event
.SetInt( toolIndex 
); 
 248     GetEventHandler()->ProcessEvent(event
); 
 251 wxToolBarTool 
*wxToolBar::AddTool( int toolIndex
, const wxBitmap
& bitmap
, 
 252   const wxBitmap
& pushedBitmap
, bool toggle
, 
 253   float WXUNUSED(xPos
), float WXUNUSED(yPos
), wxObject 
*clientData
, 
 254   const wxString
& helpString1
, const wxString
& helpString2 
) 
 256     m_hasToolAlready 
= TRUE
; 
 258     wxCHECK_MSG( bitmap
.Ok(), (wxToolBarTool 
*)NULL
, 
 259                  _T("invalid bitmap for wxToolBar icon") ); 
 261     wxCHECK_MSG( bitmap
.GetBitmap() == NULL
, (wxToolBarTool 
*)NULL
, 
 262                  _T("wxToolBar doesn't support GdkBitmap") ); 
 264     wxCHECK_MSG( bitmap
.GetPixmap() != NULL
, (wxToolBarTool 
*)NULL
, 
 265                  _T("wxToolBar::Add needs a wxBitmap") ); 
 267     GtkWidget 
*tool_pixmap 
= (GtkWidget 
*)NULL
; 
 269     GdkPixmap 
*pixmap 
= bitmap
.GetPixmap(); 
 271     GdkBitmap 
*mask 
= (GdkBitmap 
*)NULL
; 
 272     if ( bitmap
.GetMask() ) 
 273       mask 
= bitmap
.GetMask()->GetBitmap(); 
 275     tool_pixmap 
= gtk_pixmap_new( pixmap
, mask 
); 
 277     gtk_misc_set_alignment( GTK_MISC(tool_pixmap
), 0.5, 0.5 ); 
 279     wxToolBarTool 
*tool 
= new wxToolBarTool( this, toolIndex
, bitmap
, pushedBitmap
, 
 281                                              helpString1
, helpString2
, 
 284     GtkToolbarChildType ctype 
= toggle 
? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
 
 285                                        : GTK_TOOLBAR_CHILD_BUTTON
; 
 287     GtkWidget 
*item 
= gtk_toolbar_append_element
 
 289                       GTK_TOOLBAR(m_toolbar
), 
 293                       helpString1
.mbc_str(), 
 296                       (GtkSignalFunc
)gtk_toolbar_callback
, 
 302     gtk_signal_connect( GTK_OBJECT(tool
->m_item
), 
 303                         "enter_notify_event",  
 304                         GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback
), 
 307     m_tools
.Append( tool 
); 
 312 void wxToolBar::AddSeparator() 
 314     gtk_toolbar_append_space( m_toolbar 
); 
 317 void wxToolBar::ClearTools() 
 319     wxFAIL_MSG( _T("wxToolBar::ClearTools not implemented") ); 
 322 bool wxToolBar::Realize() 
 329     wxNode 
*node 
= m_tools
.First(); 
 332         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 333         if (tool
->m_bitmap1
.Ok()) 
 335             int tool_height 
= tool
->m_bitmap1
.GetHeight(); 
 336             if (tool_height 
> m_height
) m_height 
= tool_height
; 
 342     m_height 
+= 5 + 2*m_yMargin
; 
 347 void wxToolBar::EnableTool(int toolIndex
, bool enable
) 
 349     wxNode 
*node 
= m_tools
.First(); 
 352         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 353         if (tool
->m_index 
== toolIndex
) 
 355             tool
->m_enabled 
= enable
; 
 357 /*   we don't disable the tools for now as the bitmaps don't get 
 358      greyed anyway and this also disables tooltips 
 361                 gtk_widget_set_sensitive( tool->m_item, enable ); 
 369     wxFAIL_MSG( _T("wrong toolbar index") ); 
 372 void wxToolBar::ToggleTool( int toolIndex
, bool toggle 
)  
 374     wxNode 
*node 
= m_tools
.First(); 
 377         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 378         if (tool
->m_index 
== toolIndex
) 
 380             tool
->m_toggleState 
= toggle
; 
 381             if ((tool
->m_item
) && (GTK_IS_TOGGLE_BUTTON(tool
->m_item
))) 
 382                 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool
->m_item
), toggle 
); 
 388     wxFAIL_MSG( _T("wrong toolbar index") ); 
 391 wxObject 
*wxToolBar::GetToolClientData( int index 
) const 
 393     wxNode 
*node 
= m_tools
.First(); 
 396         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 397         if (tool
->m_index 
== index
) return tool
->m_clientData
;; 
 401     wxFAIL_MSG( _T("wrong toolbar index") ); 
 403     return (wxObject
*)NULL
; 
 406 bool wxToolBar::GetToolState(int toolIndex
) const 
 408     wxNode 
*node 
= m_tools
.First(); 
 411         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 412         if (tool
->m_index 
== toolIndex
) return tool
->m_toggleState
; 
 416     wxFAIL_MSG( _T("wrong toolbar index") ); 
 421 bool wxToolBar::GetToolEnabled(int toolIndex
) const 
 423     wxNode 
*node 
= m_tools
.First(); 
 426         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 427         if (tool
->m_index 
== toolIndex
) return tool
->m_enabled
; 
 431     wxFAIL_MSG( _T("wrong toolbar index") ); 
 436 void wxToolBar::SetMargins( int x
, int y 
) 
 438     wxCHECK_RET( !m_hasToolAlready
, _T("wxToolBar::SetMargins must be called before adding tool.") ); 
 440     if (x 
> 2) gtk_toolbar_append_space( m_toolbar 
);  // oh well 
 446 void wxToolBar::SetToolPacking( int WXUNUSED(packing
) ) 
 448     wxFAIL_MSG( _T("wxToolBar::SetToolPacking not implemented") ); 
 451 void wxToolBar::SetToolSeparation( int separation 
) 
 453     gtk_toolbar_set_space_size( m_toolbar
, separation 
); 
 454     m_separation 
= separation
; 
 457 int wxToolBar::GetToolPacking() 
 462 int wxToolBar::GetToolSeparation() 
 467 wxString 
wxToolBar::GetToolLongHelp(int toolIndex
) 
 469     wxNode 
*node 
= m_tools
.First(); 
 472         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 473         if (tool
->m_index 
== toolIndex
) 
 475             return tool
->m_longHelpString
; 
 480     wxFAIL_MSG( _T("wrong toolbar index") ); 
 485 wxString 
wxToolBar::GetToolShortHelp(int toolIndex
) 
 487     wxNode 
*node 
= m_tools
.First(); 
 490         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 491         if (tool
->m_index 
== toolIndex
) 
 493             return tool
->m_shortHelpString
; 
 498     wxFAIL_MSG( _T("wrong toolbar index") ); 
 503 void wxToolBar::SetToolLongHelp(int toolIndex
, const wxString
& helpString
) 
 505     wxNode 
*node 
= m_tools
.First(); 
 508         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 509         if (tool
->m_index 
== toolIndex
) 
 511             tool
->m_longHelpString 
= helpString
; 
 517     wxFAIL_MSG( _T("wrong toolbar index") ); 
 522 void wxToolBar::SetToolShortHelp(int toolIndex
, const wxString
& helpString
) 
 524     wxNode 
*node 
= m_tools
.First(); 
 527         wxToolBarTool 
*tool 
= (wxToolBarTool
*)node
->Data(); 
 528         if (tool
->m_index 
== toolIndex
) 
 530             tool
->m_shortHelpString 
= helpString
; 
 536     wxFAIL_MSG( _T("wrong toolbar index") ); 
 541 void wxToolBar::OnIdle( wxIdleEvent 
&WXUNUSED(ievent
) ) 
 543     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
 545     wxNode
* node 
= m_tools
.First(); 
 548         wxToolBarTool
* tool 
= (wxToolBarTool
*) node
->Data(); 
 550         wxUpdateUIEvent 
event( tool
->m_index 
); 
 551         event
.SetEventObject(this); 
 553         if (evtHandler
->ProcessEvent( event 
)) 
 555             if (event
.GetSetEnabled()) 
 556                 EnableTool(tool
->m_index
, event
.GetEnabled()); 
 557             if (event
.GetSetChecked()) 
 558                 ToggleTool(tool
->m_index
, event
.GetChecked()); 
 560             if (event.GetSetText())