]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/window.cpp
Better disabling of toolbars and menubars
[wxWidgets.git] / src / motif / window.cpp
index bdaa663463d590e2cc6802bcfe9a343572c7e883..1d78e7a52afdbbed1ddd0af16e514ce4277b14c2 100644 (file)
@@ -368,8 +368,10 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
 
   m_scrolledWindow = (WXWidget) XtVaCreateManagedWidget ("scrolledWindow",
                                            xmScrolledWindowWidgetClass, m_borderWidget ? (Widget) m_borderWidget : parentWidget,
+                                  XmNresizePolicy, XmRESIZE_NONE,
                                   XmNspacing, 0,
                                  XmNscrollingPolicy, XmAPPLICATION_DEFINED,
+ //                                  XmNscrollBarDisplayPolicy, XmAS_NEEDED,
                                            NULL);
 
   XtTranslations ptr;
@@ -419,8 +421,40 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
   XtAddEventHandler ((Widget) m_drawingArea, PointerMotionHintMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask,
     False, (XtEventHandler) wxCanvasEnterLeave, (XtPointer) this);
 
+  // Scrolled widget needs to have its colour changed or we get
+  // a little blue square where the scrollbars abutt
+  wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
+  DoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE);
+  DoChangeBackgroundColour(m_drawingArea, backgroundColour, TRUE);
+
+  XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) 0, (Widget) 0, (Widget) m_drawingArea);
+
+  /*
+  if (m_hScrollBar)
+       XtRealizeWidget ((Widget) m_hScrollBar);
+  if (m_vScrollBar)
+       XtRealizeWidget ((Widget) m_vScrollBar);
+       */
+
+  // Without this, the cursor may not be restored properly
+  // (e.g. in splitter sample).
+  SetCursor(*wxSTANDARD_CURSOR);
+  SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
+  SetSize(pos.x, pos.y, size.x, size.y);
+
+  return TRUE;
+}
+
+// Helper function
+void wxWindow::CreateScrollbar(int orientation)
+{
+  if (!m_drawingArea)
+    return;
+
+  XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
+
   // Add scrollbars if required
-  if (m_windowStyle & wxHSCROLL)
+  if (orientation == wxHORIZONTAL)
   {
       Widget hScrollBar = XtVaCreateManagedWidget ("hsb",
                                     xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
@@ -441,9 +475,20 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
                     NULL);
 
       m_hScrollBar = (WXWidget) hScrollBar;
+
+      wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
+      DoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE);
+
+      XtRealizeWidget(hScrollBar);
+
+      XtVaSetValues((Widget) m_scrolledWindow,
+             XmNhorizontalScrollBar, (Widget) m_hScrollBar,
+             NULL);
+
       m_hScroll = TRUE;
   }
-  if (m_windowStyle & wxVSCROLL)
+
+  if (orientation == wxVERTICAL)
   {
       Widget vScrollBar = XtVaCreateManagedWidget ("vsb",
                                     xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
@@ -464,23 +509,57 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
                     NULL);
 
       m_vScrollBar = (WXWidget) vScrollBar;
+      wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
+      DoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE);
+
+      XtRealizeWidget(vScrollBar);
+
+      XtVaSetValues((Widget) m_scrolledWindow,
+             XmNverticalScrollBar, (Widget) m_vScrollBar,
+             NULL);
+
       m_vScroll = TRUE;
   }
 
-  if (m_hScrollBar || m_vScrollBar)
-    XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
+  XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
+}
+void wxWindow::DestroyScrollbar(int orientation)
+{
+  if (!m_drawingArea)
+    return;
 
-  if (m_hScrollBar)
-       XtRealizeWidget ((Widget) m_hScrollBar);
-  if (m_vScrollBar)
-       XtRealizeWidget ((Widget) m_vScrollBar);
+  XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
+  // Add scrollbars if required
+  if (orientation == wxHORIZONTAL)
+  {
+      if (m_hScrollBar)
+      {
+        XtDestroyWidget((Widget) m_hScrollBar);
+      }
+      m_hScrollBar = (WXWidget) 0;
+      m_hScroll = FALSE;
 
-  // Without this, the cursor may not be restored properly
-  // (e.g. in splitter sample).
-  SetCursor(*wxSTANDARD_CURSOR);
-  SetSize(pos.x, pos.y, size.x, size.y);
+      XtVaSetValues((Widget) m_scrolledWindow,
+             XmNhorizontalScrollBar, (Widget) 0,
+             NULL);
 
-  return TRUE;
+  }
+
+  if (orientation == wxVERTICAL)
+  {
+      if (m_vScrollBar)
+      {
+        XtDestroyWidget((Widget) m_vScrollBar);
+      }
+      m_vScrollBar = (WXWidget) 0;
+      m_vScroll = TRUE;
+
+      XtVaSetValues((Widget) m_scrolledWindow,
+             XmNverticalScrollBar, (Widget) 0,
+             NULL);
+
+  }
+  XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
 }
 
 void wxWindow::SetFocus()
@@ -679,6 +758,11 @@ void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
   else if (width == oldW && height == oldH)
     useOldSize = TRUE;
 
+  if (!wxNoOptimize::CanOptimize())
+  {
+    useOldSize = FALSE; useOldPos = FALSE;
+  }
+
   if (useOldPos && useOldSize)
     return;
 
@@ -929,7 +1013,10 @@ void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
         wxClientDC dc(this);
         wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID);
         dc.SetBackground(backgroundBrush);
-        dc.Clear();
+        if (rect)
+          dc.Clear(*rect);
+        else
+          dc.Clear();
     }
 
     XSendEvent(display, thisWindow, False, ExposureMask, (XEvent *)&dummyEvent);
@@ -938,7 +1025,7 @@ void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
 // Responds to colour changes: passes event on to children.
 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
-    wxNode *node = GetChildren()->First();
+    wxNode *node = GetChildren().First();
     while ( node )
     {
         // Only propagate to non-top-level windows
@@ -1149,16 +1236,60 @@ void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
 void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
     int range, bool WXUNUSED(refresh))
 {
-    Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar );
-    if (!scrollBar)
-        return;
+    int oldW, oldH;
+    GetSize(& oldW, & oldH);
 
     if (range == 0)
       range = 1;
     if (thumbVisible == 0)
       thumbVisible = 1;
 
-    XtVaSetValues(scrollBar,
+    if (thumbVisible > range)
+      thumbVisible = range;
+
+    // Save the old state to see if it changed
+    WXWidget oldScrollBar =  ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar );
+
+    if (orient == wxHORIZONTAL)
+    {
+        if (thumbVisible == range)
+        {
+            if (m_hScrollBar)
+              DestroyScrollbar(wxHORIZONTAL);
+       }
+        else
+        {
+            if (!m_hScrollBar)
+              CreateScrollbar(wxHORIZONTAL);
+        }
+    }
+    if (orient == wxVERTICAL)
+    {
+        if (thumbVisible == range)
+        {
+            if (m_vScrollBar)
+              DestroyScrollbar(wxVERTICAL);
+       }
+        else
+        {
+            if (!m_vScrollBar)
+              CreateScrollbar(wxVERTICAL);
+        }
+    }
+    WXWidget newScrollBar =  ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar );
+
+    if (oldScrollBar != newScrollBar)
+    {
+      // This is important! Without it, scrollbars misbehave
+      // badly.
+      XtUnrealizeWidget((Widget) m_scrolledWindow);
+      XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
+      XtRealizeWidget((Widget) m_scrolledWindow);
+      XtManageChild((Widget) m_scrolledWindow);
+    }
+
+    if (newScrollBar)
+      XtVaSetValues((Widget) newScrollBar,
          XmNvalue, pos,
          XmNminimum, 0,
          XmNmaximum, range,
@@ -1169,6 +1300,13 @@ void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
         m_scrollPosX = pos;
     else
         m_scrollPosY = pos;
+
+    int newW, newH;
+    GetSize(& newW, & newH);
+
+    // Adjusting scrollbars can resize the canvas accidentally
+    if (newW != oldW || newH != oldH)
+        SetSize(-1, -1, oldW, oldH);
 }
 
 // Does a physical scroll
@@ -1367,7 +1505,7 @@ bool wxWindow::IsEnabled() const
 // it's an application error (pops up a dialog)
 bool wxWindow::TransferDataToWindow()
 {
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *child = (wxWindow *)node->Data();
@@ -1387,7 +1525,7 @@ bool wxWindow::TransferDataToWindow()
 // validation failed: don't quit
 bool wxWindow::TransferDataFromWindow()
 {
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *child = (wxWindow *)node->Data();
@@ -1403,7 +1541,7 @@ bool wxWindow::TransferDataFromWindow()
 
 bool wxWindow::Validate()
 {
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *child = (wxWindow *)node->Data();
@@ -1426,14 +1564,13 @@ wxWindow *wxWindow::FindFocus()
 
 void wxWindow::AddChild(wxWindow *child)
 {
-    GetChildren()->Append(child);
+    GetChildren().Append(child);
     child->m_windowParent = this;
 }
 
 void wxWindow::RemoveChild(wxWindow *child)
 {
-    if (GetChildren())
-        GetChildren()->DeleteObject(child);
+    GetChildren().DeleteObject(child);
     child->m_windowParent = NULL;
 }
 
@@ -1446,9 +1583,7 @@ bool wxWindow::Reparent(wxWindow* WXUNUSED(parent))
 
 void wxWindow::DestroyChildren()
 {
-  if (GetChildren())
-  {
-    wxNode *node = GetChildren()->First();
+    wxNode *node = GetChildren().First();
     while (node)
     {
       wxNode* next = node->Next();
@@ -1456,19 +1591,18 @@ void wxWindow::DestroyChildren()
       delete child;
       node = next;
     }
-    GetChildren()->Clear();
+    GetChildren().Clear();
 #if 0
     wxNode *node;
-    while ((node = GetChildren()->First()) != (wxNode *)NULL) {
+    while ((node = GetChildren().First()) != (wxNode *)NULL) {
       wxWindow *child;
       if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) {
         delete child;
-               if ( GetChildren()->Member(child) )
+               if ( GetChildren().Member(child) )
                        delete node;
       }
     } /* while */
 #endif
-  }
 }
 
 void wxWindow::MakeModal(bool modal)
@@ -1683,7 +1817,7 @@ bool wxWindow::DoPhase(int phase)
   {
     noChanges = 0;
     noFailures = 0;
-    wxNode *node = GetChildren()->First();
+    wxNode *node = GetChildren().First();
     while (node)
     {
       wxWindow *child = (wxWindow *)node->Data();
@@ -1728,7 +1862,7 @@ void wxWindow::ResetConstraints()
     constr->centreX.SetDone(FALSE);
     constr->centreY.SetDone(FALSE);
   }
-  wxNode *node = GetChildren()->First();
+  wxNode *node = GetChildren().First();
   while (node)
   {
     wxWindow *win = (wxWindow *)node->Data();
@@ -1787,7 +1921,7 @@ void wxWindow::SetConstraintSizes(bool recurse)
 
   if (recurse)
   {
-    wxNode *node = GetChildren()->First();
+    wxNode *node = GetChildren().First();
     while (node)
     {
       wxWindow *win = (wxWindow *)node->Data();
@@ -1924,9 +2058,7 @@ bool wxWindow::Close(bool force)
 wxObject* wxWindow::GetChild(int number) const
 {
   // Return a pointer to the Nth object in the window
-  if (!GetChildren())
-    return(NULL) ;
-  wxNode *node = GetChildren()->First();
+  wxNode *node = GetChildren().First();
   int n = number;
   while (node && n--)
     node = node->Next() ;
@@ -1957,7 +2089,7 @@ void wxWindow::Fit()
 {
        int maxX = 0;
        int maxY = 0;
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *win = (wxWindow *)node->Data();
@@ -2011,7 +2143,7 @@ wxWindow *wxWindow::FindWindow(long id)
        if ( GetId() == id)
                return this;
 
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *child = (wxWindow *)node->Data();
@@ -2028,7 +2160,7 @@ wxWindow *wxWindow::FindWindow(const wxString& name)
        if ( GetName() == name)
                return this;
 
-       wxNode *node = GetChildren()->First();
+       wxNode *node = GetChildren().First();
        while ( node )
        {
                wxWindow *child = (wxWindow *)node->Data();
@@ -2127,12 +2259,7 @@ bool wxAddWindowToTable(Widget w, wxWindow *win)
 //  printf("Adding widget %ld, name = %s\n", w, win->GetClassInfo()->GetClassName());
   if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w)))
   {
-    char buf[300];
-    sprintf(buf, "Widget table clash: new widget is %ld, %s", (long)w, win->GetClassInfo()->GetClassName());
-    wxError (buf);
-    fflush(stderr);
-    sprintf(buf, "Old widget was %s", oldItem->GetClassInfo()->GetClassName());
-    wxError (buf);
+    wxLogError("Widget table clash: new widget is %ld, %s", (long)w, win->GetClassInfo()->GetClassName());
     return FALSE;
   }
 
@@ -2570,6 +2697,11 @@ void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
   else if (w == oldW && h == oldH)
     useOldSize = TRUE;
 
+  if (!wxNoOptimize::CanOptimize())
+  {
+    useOldSize = FALSE; useOldPos = FALSE;
+  }
+
   if (useOldPos && useOldSize)
     return;
 
@@ -2630,7 +2762,7 @@ void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
 
       w -= (spacing + wsbar);
 
-      XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
+      //      XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
     }
   if (h > -1)
     {
@@ -2661,7 +2793,8 @@ void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
 
       h -= (spacing + wsbar);
 
-      XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
+      //      XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
+
     }
   }
 
@@ -3128,12 +3261,31 @@ void wxWindow::ChangeBackgroundColour()
 {
     if (GetMainWidget())
         DoChangeBackgroundColour(GetMainWidget(), m_backgroundColour);
+
+    // This not necessary
+#if 0
+
+    if (m_scrolledWindow && (GetMainWidget() != m_scrolledWindow))
+    {
+        DoChangeBackgroundColour(m_scrolledWindow, m_backgroundColour);
+        // Have to set the scrollbar colours back since
+        // the scrolled window seemed to change them
+        wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
+
+        if (m_hScrollBar)
+          DoChangeBackgroundColour(m_hScrollBar, backgroundColour);
+        if (m_vScrollBar)
+          DoChangeBackgroundColour(m_vScrollBar, backgroundColour);
+    }
+#endif
 }
 
 void wxWindow::ChangeForegroundColour()
 {
     if (GetMainWidget())
         DoChangeForegroundColour(GetMainWidget(), m_foregroundColour);
+    if (m_scrolledWindow && (GetMainWidget() != m_scrolledWindow))
+        DoChangeForegroundColour(m_scrolledWindow, m_foregroundColour);
 }
 
 // Change a widget's foreground and background colours.
@@ -3195,9 +3347,12 @@ void wxWindow::ChangeFont(bool keepOriginalSize)
         int width, height, width1, height1;
         GetSize(& width, & height);
 
+// lesstif 0.87 hangs here
+#ifndef LESSTIF_VERSION        
         XtVaSetValues (w,
                   XmNfontList, (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay(w)),
                   NULL);
+#endif
 
         GetSize(& width1, & height1);
         if (keepOriginalSize && (width != width1 || height != height1))
@@ -3293,3 +3448,24 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
     return FALSE;
 }
 
+/*
+ * wxNoOptimize: switch off size optimization
+ */
+
+int wxNoOptimize::m_count = 0;
+
+wxNoOptimize::wxNoOptimize()
+{
+  m_count ++;
+}
+
+wxNoOptimize::~wxNoOptimize()
+{
+  m_count --;
+}
+
+bool wxNoOptimize::CanOptimize()
+{
+  return (m_count == 0);
+}
+