]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/frame.cpp
Thread fixes (but they still don't work at all...)
[wxWidgets.git] / src / motif / frame.cpp
index e83b831ebcfca7b4a496df9fb95b65f168b9eb05..d018baa2a250d7d1de6c90d74546d25559732deb 100644 (file)
@@ -51,7 +51,7 @@
 #include "wx/motif/private.h"
 
 void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
-static void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
+void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
                       XmAnyCallbackStruct *cbs);
 static void wxFrameMapProc(Widget frameShell, XtPointer clientData, 
                           XCrossingEvent * event);
@@ -126,7 +126,9 @@ bool wxFrame::Create(wxWindow *parent,
   m_visibleStatus = TRUE;
   m_title = "";
 
-  SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
+  m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
+  m_foregroundColour = *wxBLACK;
+  m_windowFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
 
   if ( id > -1 )
     m_windowId = id;
@@ -221,6 +223,8 @@ bool wxFrame::Create(wxWindow *parent,
 
   m_mainWidget = m_frameWidget;
 
+  ChangeFont(FALSE);
+
   // This patch comes from Torsten Liermann lier@lier1.muc.de
   if (XmIsMotifWMRunning( (Widget) m_frameShell ))
   {
@@ -264,6 +268,8 @@ bool wxFrame::Create(wxWindow *parent,
 #endif
 #endif
 
+  ChangeBackgroundColour();
+
   PreResize();
 
   wxSizeEvent sizeEvent(wxSize(width, height), GetId());
@@ -281,6 +287,8 @@ wxFrame::~wxFrame()
 
   if (m_frameMenuBar)
   {
+    m_frameMenuBar->DestroyMenuBar();
+
 // Hack to stop core dump on Ultrix, OSF, for some strange reason.
 #if MOTIF_MENUBAR_DELETE_FIX
     GetMenuBar()->SetMainWidget((WXWidget) NULL);
@@ -310,14 +318,21 @@ wxFrame::~wxFrame()
     XtDestroyWidget (statusLineWidget);
  */
 
-  wxDeleteWindowFromTable((Widget) m_workArea);
+  if (m_workArea)
+  {
+      wxDeleteWindowFromTable((Widget) m_workArea);
 
-  XtDestroyWidget ((Widget) m_workArea);
-  XtDestroyWidget ((Widget) m_frameWidget);
+      XtDestroyWidget ((Widget) m_workArea);
+  }
 
-  wxDeleteWindowFromTable((Widget) m_frameWidget);
+  if (m_frameWidget)
+  {
+      wxDeleteWindowFromTable((Widget) m_frameWidget);
+      XtDestroyWidget ((Widget) m_frameWidget);
+  }
 
-  XtDestroyWidget ((Widget) m_frameShell);
+  if (m_frameShell)
+      XtDestroyWidget ((Widget) m_frameShell);
 
   SetMainWidget((WXWidget) NULL);
 
@@ -342,21 +357,28 @@ void wxFrame::GetClientSize(int *x, int *y) const
   Dimension xx, yy;
   XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
 
-  /* TODO
-  if (status_line_exists)
+  if (m_frameStatusBar)
   {
-    Dimension ys;
-    XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
-    yy -= ys;
+    int sbw, sbh;
+    m_frameStatusBar->GetSize(& sbw, & sbh);
+    yy -= sbh;
   }
-  */
-
+  if (m_frameToolBar)
+  {
+    int tbw, tbh;
+    m_frameToolBar->GetSize(& tbw, & tbh);
+    if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
+      xx -= tbw;
+    else
+      yy -= tbh;
+  }
+/*
   if (GetMenuBar() != (wxMenuBar*) NULL)
   {
     // it seems that if a frame holds a panel, the menu bar size
     // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95
     bool hasSubPanel = FALSE;
-    for(wxNode* node = GetChildren()->First(); node; node = node->Next())
+    for(wxNode* node = GetChildren().First(); node; node = node->Next())
     {
      wxWindow *win = (wxWindow *)node->Data();
      hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog)));
@@ -370,6 +392,7 @@ void wxFrame::GetClientSize(int *x, int *y) const
       yy -= ys;
     }
   }
+ */
 
   *x = xx; *y = yy;
 }
@@ -386,14 +409,22 @@ void wxFrame::SetClientSize(int width, int height)
 
   if (height > -1)
   {
-    /* TODO
-    if (status_line_exists)
+    if (m_frameStatusBar)
     {
-      Dimension ys;
-      XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
-      height += ys;
+      int sbw, sbh;
+      m_frameStatusBar->GetSize(& sbw, & sbh);
+      height += sbh;
+    }
+    if (m_frameToolBar)
+    {
+      int tbw, tbh;
+      m_frameToolBar->GetSize(& tbw, & tbh);
+      if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
+        width += tbw;
+      else
+        height += tbh;
     }
-    */
+
     XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL);
   }
   PreResize();
@@ -448,15 +479,20 @@ void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
   if (!(height == -1 && width == -1))
   {
     PreResize();
+ /* JACS: not sure if this is necessary
     wxSizeEvent sizeEvent(wxSize(width, height), GetId());
     sizeEvent.SetEventObject(this);
 
     GetEventHandler()->ProcessEvent(sizeEvent);
+  */
   }
 }
 
 bool wxFrame::Show(bool show)
 {
+  if (!m_frameShell)
+    return wxWindow::Show(show);
+
   m_visibleStatus = show; /* show-&-hide fix */
 
   m_isShown = show;
@@ -475,7 +511,8 @@ void wxFrame::Iconize(bool iconize)
   if (!iconize)
     Show(TRUE);
 
-  XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
+  if (m_frameShell)
+    XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
 }
 
 // Equivalent to maximize/restore in Windows
@@ -483,17 +520,27 @@ void wxFrame::Maximize(bool maximize)
 {
   Show(TRUE);
 
-  if (maximize)
+  if (maximize && m_frameShell)
     XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL);
 }
 
 bool wxFrame::IsIconized() const
 {
+  if (!m_frameShell)
+    return FALSE;
+
   Boolean iconic;
   XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL);
   return iconic;
 }
 
+// Is it maximized?
+bool wxFrame::IsMaximized(void) const
+{
+    // No maximizing in Motif (?)
+    return FALSE;
+}
+
 void wxFrame::SetTitle(const wxString& title)
 {
   if (title == m_title)
@@ -512,13 +559,13 @@ void wxFrame::SetIcon(const wxIcon& icon)
 {
   m_icon = icon;
 
-  // TODO
-  /*
+  if (!m_frameShell)
+    return;
+
   if (!icon.Ok() || !icon.GetPixmap())
     return;
 
-  XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon->.GetPixmap(), NULL);
-  */
+  XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL);
 }
 
 wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
@@ -531,7 +578,7 @@ wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
 
     // Set the height according to the font and the border size
     wxClientDC dc(statusBar);
-    dc.SetFont(statusBar->GetFont());
+    dc.SetFont(statusBar->GetFont());
 
     long x, y;
     dc.GetTextExtent("X", &x, &y);
@@ -589,7 +636,7 @@ void wxFrame::PositionStatusBar()
 
     // Since we wish the status bar to be directly under the client area,
     // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
-    m_frameStatusBar->SetSize(0-sh, h, w, sh);
+    m_frameStatusBar->SetSize(0, h, w, sh);
 }
 
 WXWidget wxFrame::GetMenuBarWidget() const
@@ -609,38 +656,22 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar)
     }
 
     // Currently can't set it twice
-    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
-  
-    m_frameMenuBar = menuBar;
+//    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
 
-  Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0);
-  m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW);
-
-  int i;
-  for (i = 0; i < menuBar->GetMenuCount(); i++)
+    if (m_frameMenuBar)
     {
-      wxMenu *menu = menuBar->GetMenu(i);
-      wxString title(menuBar->m_titles[i]);
-      menu->SetButtonWidget(menu->CreateMenu (menuBar, menuBarW, menu, title, TRUE));
-
-      /*
-       * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
-       */
-      wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
-
-      if (strcmp (wxBuffer, "Help") == 0)
-       XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
+        m_frameMenuBar->DestroyMenuBar();
+        delete m_frameMenuBar;
     }
 
-  XtRealizeWidget ((Widget) menuBarW);
-  XtManageChild ((Widget) menuBarW);
-  menuBar->SetMenuBarFrame(this);
+    m_frameMenuBar = menuBar;
+    m_frameMenuBar->CreateMenuBar(this);
 }
 
 void wxFrame::Fit()
 {
   // Work out max. size
-  wxNode *node = GetChildren()->First();
+  wxNode *node = GetChildren().First();
   int max_width = 0;
   int max_height = 0;
   while (node)
@@ -697,7 +728,7 @@ void wxFrame::OnSize(wxSizeEvent& event)
 
   // do we have _exactly_ one child?
   wxWindow *child = NULL;
-  for ( wxNode *node = GetChildren()->First(); node; node = node->Next() )
+  for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
   {
     wxWindow *win = (wxWindow *)node->Data();
     if ( !win->IsKindOf(CLASSINFO(wxFrame))  &&
@@ -727,16 +758,13 @@ void wxFrame::OnSize(wxSizeEvent& event)
 // subwindow found.
 void wxFrame::OnActivate(wxActivateEvent& event)
 {
-  for(wxNode *node = GetChildren()->First(); node; node = node->Next())
+  for(wxNode *node = GetChildren().First(); node; node = node->Next())
   {
     // Find a child that's a subwindow, but not a dialog box.
     wxWindow *child = (wxWindow *)node->Data();
     if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
          !child->IsKindOf(CLASSINFO(wxDialog)))
     {
-#if WXDEBUG > 1
-      wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n");
-#endif
       child->SetFocus();
       return;
     }
@@ -857,6 +885,30 @@ wxPoint wxFrame::GetClientAreaOrigin() const
     return pt;
 }
 
+void wxFrame::ScreenToClient(int *x, int *y) const
+{
+    wxWindow::ScreenToClient(x, y);
+
+    // We may be faking the client origin.
+    // So a window that's really at (0, 30) may appear
+    // (to wxWin apps) to be at (0, 0).
+    wxPoint pt(GetClientAreaOrigin());
+    *x -= pt.x;
+    *y -= pt.y;
+}
+
+void wxFrame::ClientToScreen(int *x, int *y) const
+{
+    // We may be faking the client origin.
+    // So a window that's really at (0, 30) may appear
+    // (to wxWin apps) to be at (0, 0).
+    wxPoint pt1(GetClientAreaOrigin());
+    *x += pt1.x;
+    *y += pt1.y;
+
+    wxWindow::ClientToScreen(x, y);
+}
+
 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
 {
     wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
@@ -877,26 +929,15 @@ wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& nam
 
 wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
 {
-    return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
+    return new wxToolBar(this, id, wxPoint(0, 0), wxSize(100, 24), style, name);
 }
 
 void wxFrame::PositionToolBar()
 {
     int cw, ch;
 
-    // TODO: we actually need to use the low-level client size, before
-    // the toolbar/status bar were added.
-    // So DEFINITELY replace the line below with something appropriate.
-
     GetClientSize(& cw, &ch);
 
-    if ( GetStatusBar() )
-    {
-      int statusX, statusY;
-      GetStatusBar()->GetClientSize(&statusX, &statusY);
-      ch -= statusY;
-    }
-
     if (GetToolBar())
     {
         int tw, th;
@@ -907,7 +948,7 @@ void wxFrame::PositionToolBar()
             // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
             // means, pretend we don't have toolbar/status bar, so we
             // have the original client size.
-            GetToolBar()->SetSize(0, 0, tw, ch, wxSIZE_NO_ADJUSTMENTS);
+            GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS);
         }
         else
         {
@@ -977,7 +1018,7 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
 wxToolBar *wxFrame::GetToolBar() const
 { return m_frameToolBar; }
 
-static void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
+void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
                       XmAnyCallbackStruct *cbs)
 {
   wxFrame *frame = (wxFrame *)clientData;
@@ -1015,6 +1056,7 @@ static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
 //// Motif-specific
 bool wxFrame::PreResize()
 {
+  PositionToolBar();
   PositionStatusBar();
   return TRUE;
 }
@@ -1024,6 +1066,23 @@ WXWidget wxFrame::GetClientWidget() const
   return m_clientArea;
 }
 
+void wxFrame::ChangeFont(bool keepOriginalSize)
+{
+    // TODO
+}
+
+void wxFrame::ChangeBackgroundColour()
+{
+    if (GetClientWidget())
+        DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour);
+}
+
+void wxFrame::ChangeForegroundColour()
+{
+    if (GetClientWidget())
+        DoChangeForegroundColour(GetClientWidget(), m_foregroundColour);
+}
+
 void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
 {
   wxFrame *frame = (wxFrame *)client_data;
@@ -1034,3 +1093,4 @@ void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStr
   // May delete the frame (with delayed deletion)
   frame->GetEventHandler()->ProcessEvent(closeEvent);
 }
+