PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/Extras/wxWidgets-2.9.0/src/gtk/frame.cpp

https://bitbucket.org/erwincoumans/dynamicaopencl
C++ | 412 lines | 303 code | 61 blank | 48 comment | 59 complexity | 6e94438b3635d02d0c93e70fc86a2d5b MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/gtk/frame.cpp
  3. // Purpose:
  4. // Author: Robert Roebling
  5. // Id: $Id: frame.cpp 58246 2009-01-20 18:33:33Z VZ $
  6. // Copyright: (c) 1998 Robert Roebling
  7. // Licence: wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9. // For compilers that support precompilation, includes "wx.h".
  10. #include "wx/wxprec.h"
  11. #include "wx/frame.h"
  12. #ifndef WX_PRECOMP
  13. #include "wx/menu.h"
  14. #include "wx/toolbar.h"
  15. #include "wx/statusbr.h"
  16. #endif // WX_PRECOMP
  17. #include <gtk/gtk.h>
  18. #if wxUSE_LIBHILDON
  19. #include <hildon-widgets/hildon-window.h>
  20. #endif // wxUSE_LIBHILDON
  21. // ----------------------------------------------------------------------------
  22. // event tables
  23. // ----------------------------------------------------------------------------
  24. IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
  25. // ============================================================================
  26. // implementation
  27. // ============================================================================
  28. // ----------------------------------------------------------------------------
  29. // wxFrame creation
  30. // ----------------------------------------------------------------------------
  31. void wxFrame::Init()
  32. {
  33. m_fsSaveFlag = 0;
  34. }
  35. bool wxFrame::Create( wxWindow *parent,
  36. wxWindowID id,
  37. const wxString& title,
  38. const wxPoint& pos,
  39. const wxSize& sizeOrig,
  40. long style,
  41. const wxString &name )
  42. {
  43. return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name);
  44. }
  45. wxFrame::~wxFrame()
  46. {
  47. SendDestroyEvent();
  48. DeleteAllBars();
  49. }
  50. // ----------------------------------------------------------------------------
  51. // overridden wxWindow methods
  52. // ----------------------------------------------------------------------------
  53. void wxFrame::DoGetClientSize( int *width, int *height ) const
  54. {
  55. wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
  56. wxFrameBase::DoGetClientSize(width, height);
  57. if (height)
  58. {
  59. #if wxUSE_MENUS_NATIVE
  60. // menu bar
  61. if (m_frameMenuBar && m_frameMenuBar->IsShown())
  62. {
  63. GtkRequisition req;
  64. gtk_widget_size_request(m_frameMenuBar->m_widget, &req);
  65. *height -= req.height;
  66. }
  67. #endif // wxUSE_MENUS_NATIVE
  68. #if wxUSE_STATUSBAR
  69. // status bar
  70. if (m_frameStatusBar && m_frameStatusBar->IsShown())
  71. *height -= m_frameStatusBar->m_height;
  72. #endif // wxUSE_STATUSBAR
  73. }
  74. #if wxUSE_TOOLBAR
  75. // tool bar
  76. if (m_frameToolBar && m_frameToolBar->IsShown())
  77. {
  78. GtkRequisition req;
  79. gtk_widget_size_request(m_frameToolBar->m_widget, &req);
  80. if (m_frameToolBar->IsVertical())
  81. {
  82. if (width)
  83. *width -= req.width;
  84. }
  85. else
  86. {
  87. if (height)
  88. *height -= req.height;
  89. }
  90. }
  91. #endif // wxUSE_TOOLBAR
  92. if (width != NULL && *width < 0)
  93. *width = 0;
  94. if (height != NULL && *height < 0)
  95. *height = 0;
  96. }
  97. #if wxUSE_MENUS && wxUSE_ACCEL
  98. // Helper for wxCreateAcceleratorTableForMenuBar
  99. static void wxAddAccelerators(wxList& accelEntries, wxMenu* menu)
  100. {
  101. size_t i;
  102. for (i = 0; i < menu->GetMenuItems().GetCount(); i++)
  103. {
  104. wxMenuItem* item = (wxMenuItem*) menu->GetMenuItems().Item(i)->GetData();
  105. if (item->GetSubMenu())
  106. {
  107. wxAddAccelerators(accelEntries, item->GetSubMenu());
  108. }
  109. else if (!item->GetItemLabel().IsEmpty())
  110. {
  111. wxAcceleratorEntry* entry = wxAcceleratorEntry::Create(item->GetItemLabel());
  112. if (entry)
  113. {
  114. entry->Set(entry->GetFlags(), entry->GetKeyCode(), item->GetId());
  115. accelEntries.Append((wxObject*) entry);
  116. }
  117. }
  118. }
  119. }
  120. // Create an accelerator table consisting of all the accelerators
  121. // from the menubar in the given menus
  122. static wxAcceleratorTable wxCreateAcceleratorTableForMenuBar(wxMenuBar* menuBar)
  123. {
  124. wxList accelEntries;
  125. size_t i;
  126. for (i = 0; i < menuBar->GetMenuCount(); i++)
  127. {
  128. wxAddAccelerators(accelEntries, menuBar->GetMenu(i));
  129. }
  130. size_t n = accelEntries.GetCount();
  131. if (n == 0)
  132. return wxAcceleratorTable();
  133. wxAcceleratorEntry* entries = new wxAcceleratorEntry[n];
  134. for (i = 0; i < accelEntries.GetCount(); i++)
  135. {
  136. wxAcceleratorEntry* entry = (wxAcceleratorEntry*) accelEntries.Item(i)->GetData();
  137. entries[i] = (*entry);
  138. delete entry;
  139. }
  140. wxAcceleratorTable table(n, entries);
  141. delete[] entries;
  142. return table;
  143. }
  144. #endif // wxUSE_MENUS && wxUSE_ACCEL
  145. bool wxFrame::ShowFullScreen(bool show, long style)
  146. {
  147. if (!wxFrameBase::ShowFullScreen(show, style))
  148. return false;
  149. #if wxUSE_MENUS && wxUSE_ACCEL
  150. if (show && GetMenuBar())
  151. {
  152. wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
  153. if (table.IsOk())
  154. SetAcceleratorTable(table);
  155. }
  156. #endif // wxUSE_MENUS && wxUSE_ACCEL
  157. wxWindow* const bar[] = {
  158. #if wxUSE_MENUS
  159. m_frameMenuBar,
  160. #else
  161. NULL,
  162. #endif
  163. #if wxUSE_TOOLBAR
  164. m_frameToolBar,
  165. #else
  166. NULL,
  167. #endif
  168. #if wxUSE_STATUSBAR
  169. m_frameStatusBar,
  170. #else
  171. NULL,
  172. #endif
  173. };
  174. const long fsNoBar[] = {
  175. wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR
  176. };
  177. for (int i = 0; i < 3; i++)
  178. {
  179. if (show)
  180. {
  181. if (bar[i] && (style & fsNoBar[i]))
  182. {
  183. if (bar[i]->IsShown())
  184. bar[i]->Show(false);
  185. else
  186. style &= ~fsNoBar[i];
  187. }
  188. }
  189. else
  190. {
  191. if (bar[i] && (m_fsSaveFlag & fsNoBar[i]))
  192. bar[i]->Show(true);
  193. }
  194. }
  195. if (show)
  196. m_fsSaveFlag = style;
  197. return true;
  198. }
  199. void wxFrame::OnInternalIdle()
  200. {
  201. wxFrameBase::OnInternalIdle();
  202. #if wxUSE_MENUS_NATIVE
  203. if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
  204. #endif // wxUSE_MENUS_NATIVE
  205. #if wxUSE_TOOLBAR
  206. if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
  207. #endif
  208. #if wxUSE_STATUSBAR
  209. if (m_frameStatusBar)
  210. {
  211. m_frameStatusBar->OnInternalIdle();
  212. // There may be controls in the status bar that
  213. // need to be updated
  214. for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst();
  215. node;
  216. node = node->GetNext() )
  217. {
  218. wxWindow *child = node->GetData();
  219. child->OnInternalIdle();
  220. }
  221. }
  222. #endif
  223. }
  224. // ----------------------------------------------------------------------------
  225. // menu/tool/status bar stuff
  226. // ----------------------------------------------------------------------------
  227. #if wxUSE_MENUS_NATIVE
  228. void wxFrame::DetachMenuBar()
  229. {
  230. wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
  231. wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
  232. if ( m_frameMenuBar )
  233. {
  234. #if wxUSE_LIBHILDON
  235. hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
  236. #else // !wxUSE_LIBHILDON
  237. m_frameMenuBar->UnsetInvokingWindow( this );
  238. gtk_widget_ref( m_frameMenuBar->m_widget );
  239. gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
  240. #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
  241. }
  242. wxFrameBase::DetachMenuBar();
  243. // make sure next size_allocate causes a wxSizeEvent
  244. m_oldClientWidth = 0;
  245. }
  246. void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
  247. {
  248. wxFrameBase::AttachMenuBar(menuBar);
  249. if (m_frameMenuBar)
  250. {
  251. #if wxUSE_LIBHILDON
  252. hildon_window_set_menu(HILDON_WINDOW(m_widget),
  253. GTK_MENU(m_frameMenuBar->m_menubar));
  254. #else // !wxUSE_LIBHILDON
  255. m_frameMenuBar->SetInvokingWindow( this );
  256. m_frameMenuBar->SetParent(this);
  257. // menubar goes into top of vbox (m_mainWidget)
  258. gtk_box_pack_start(
  259. GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
  260. gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
  261. // disconnect wxWindowGTK "size_request" handler,
  262. // it interferes with sizing of detached GtkHandleBox
  263. gulong handler_id = g_signal_handler_find(
  264. menuBar->m_widget,
  265. GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
  266. g_signal_lookup("size_request", GTK_TYPE_WIDGET),
  267. 0, NULL, NULL, menuBar);
  268. if (handler_id != 0)
  269. g_signal_handler_disconnect(menuBar->m_widget, handler_id);
  270. // reset size request to allow native sizing to work
  271. gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
  272. gtk_widget_show( m_frameMenuBar->m_widget );
  273. #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
  274. }
  275. // make sure next size_allocate causes a wxSizeEvent
  276. m_oldClientWidth = 0;
  277. }
  278. #endif // wxUSE_MENUS_NATIVE
  279. #if wxUSE_TOOLBAR
  280. void wxFrame::SetToolBar(wxToolBar *toolbar)
  281. {
  282. m_frameToolBar = toolbar;
  283. if (toolbar)
  284. {
  285. if (toolbar->IsVertical())
  286. {
  287. // Vertical toolbar and m_wxwindow go into an hbox, inside the
  288. // vbox (m_mainWidget). hbox is created on demand.
  289. GtkWidget* hbox = m_wxwindow->parent;
  290. if (!GTK_IS_HBOX(hbox))
  291. {
  292. hbox = gtk_hbox_new(false, 0);
  293. gtk_widget_show(hbox);
  294. gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox);
  295. gtk_widget_reparent(m_wxwindow, hbox);
  296. }
  297. gtk_widget_reparent(toolbar->m_widget, hbox);
  298. gtk_box_set_child_packing(GTK_BOX(hbox),
  299. toolbar->m_widget, false, false, 0, GTK_PACK_START);
  300. int pos = 0; // left
  301. if (toolbar->HasFlag(wxTB_RIGHT))
  302. pos = 1; // right
  303. gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
  304. }
  305. else
  306. {
  307. // Horizontal toolbar goes into vbox (m_mainWidget)
  308. gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
  309. gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
  310. toolbar->m_widget, false, false, 0, GTK_PACK_START);
  311. int pos = 0; // top
  312. if (m_frameMenuBar)
  313. pos = 1; // below menubar
  314. if (toolbar->HasFlag(wxTB_BOTTOM))
  315. pos += 2; // below client area (m_wxwindow)
  316. gtk_box_reorder_child(
  317. GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
  318. }
  319. // disconnect wxWindowGTK "size_request" handler,
  320. // it interferes with sizing of detached GtkHandleBox
  321. gulong handler_id = g_signal_handler_find(
  322. toolbar->m_widget,
  323. GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
  324. g_signal_lookup("size_request", GTK_TYPE_WIDGET),
  325. 0, NULL, NULL, toolbar);
  326. if (handler_id != 0)
  327. g_signal_handler_disconnect(toolbar->m_widget, handler_id);
  328. // reset size request to allow native sizing to work
  329. gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
  330. }
  331. // make sure next size_allocate causes a wxSizeEvent
  332. m_oldClientWidth = 0;
  333. }
  334. #endif // wxUSE_TOOLBAR
  335. #if wxUSE_STATUSBAR
  336. void wxFrame::SetStatusBar(wxStatusBar *statbar)
  337. {
  338. m_frameStatusBar = statbar;
  339. if (statbar)
  340. {
  341. // statusbar goes into bottom of vbox (m_mainWidget)
  342. gtk_widget_reparent(statbar->m_widget, m_mainWidget);
  343. gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
  344. statbar->m_widget, false, false, 0, GTK_PACK_END);
  345. // make sure next size_allocate on statusbar causes a size event
  346. statbar->m_oldClientWidth = 0;
  347. }
  348. // make sure next size_allocate causes a wxSizeEvent
  349. m_oldClientWidth = 0;
  350. }
  351. #endif // wxUSE_STATUSBAR