]> git.saurik.com Git - wxWidgets.git/blobdiff - src/ribbon/panel.cpp
Misc validity fixes to samples/xrc/rc/*.xrc.
[wxWidgets.git] / src / ribbon / panel.cpp
index a14bb7336ba000c1395183b1f1aebe1c0a01314d..fd354bf38fcf0f78f422fdeb1b00b45042e36ab2 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Peter Cawley
 // Modified by:
 // Created:     2009-05-25
-// RCS-ID:      $Id$
 // Copyright:   (C) Peter Cawley
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 #include "wx/msw/private.h"
 #endif
 
+wxDEFINE_EVENT(wxEVT_RIBBONPANEL_EXTBUTTON_ACTIVATED, wxRibbonPanelEvent);
+
+IMPLEMENT_DYNAMIC_CLASS(wxRibbonPanelEvent, wxCommandEvent)
+
 IMPLEMENT_CLASS(wxRibbonPanel, wxRibbonControl)
 
 BEGIN_EVENT_TABLE(wxRibbonPanel, wxRibbonControl)
@@ -39,6 +42,7 @@ BEGIN_EVENT_TABLE(wxRibbonPanel, wxRibbonControl)
     EVT_ERASE_BACKGROUND(wxRibbonPanel::OnEraseBackground)
     EVT_KILL_FOCUS(wxRibbonPanel::OnKillFocus)
     EVT_LEAVE_WINDOW(wxRibbonPanel::OnMouseLeave)
+    EVT_MOTION(wxRibbonPanel::OnMotion)
     EVT_LEFT_DOWN(wxRibbonPanel::OnMouseClick)
     EVT_PAINT(wxRibbonPanel::OnPaint)
     EVT_SIZE(wxRibbonPanel::OnSize)
@@ -119,6 +123,7 @@ void wxRibbonPanel::CommonInit(const wxString& label, const wxBitmap& icon, long
     m_minimised_icon = icon;
     m_minimised = false;
     m_hovered = false;
+    m_ext_button_hovered = false;
 
     if(m_art == NULL)
     {
@@ -144,6 +149,11 @@ bool wxRibbonPanel::IsHovered() const
     return m_hovered;
 }
 
+bool wxRibbonPanel::IsExtButtonHovered() const
+{
+    return m_ext_button_hovered;
+}
+
 void wxRibbonPanel::OnMouseEnter(wxMouseEvent& evt)
 {
     TestPositionForHover(evt.GetPosition());
@@ -178,9 +188,14 @@ void wxRibbonPanel::OnMouseLeaveChild(wxMouseEvent& evt)
     evt.Skip();
 }
 
+void wxRibbonPanel::OnMotion(wxMouseEvent& evt)
+{
+    TestPositionForHover(evt.GetPosition());
+}
+
 void wxRibbonPanel::TestPositionForHover(const wxPoint& pos)
 {
-    bool hovered = false;
+    bool hovered = false, ext_button_hovered = false;
     if(pos.x >= 0 && pos.y >= 0)
     {
         wxSize size = GetSize();
@@ -189,9 +204,17 @@ void wxRibbonPanel::TestPositionForHover(const wxPoint& pos)
             hovered = true;
         }
     }
-    if(hovered != m_hovered)
+    if(hovered)
+    {
+        if(HasExtButton())
+            ext_button_hovered = m_ext_button_rect.Contains(pos);
+        else
+            ext_button_hovered = false;
+    }
+    if(hovered != m_hovered || ext_button_hovered != m_ext_button_hovered)
     {
         m_hovered = hovered;
+        m_ext_button_hovered = ext_button_hovered;
         Refresh(false);
     }
 }
@@ -204,18 +227,27 @@ void wxRibbonPanel::AddChild(wxWindowBase *child)
     // for children of the window. The panel wants to be in the hovered state
     // whenever the mouse cursor is within its boundary, so the events need to
     // be attached to children too.
-    child->Connect(wxEVT_ENTER_WINDOW, (wxObjectEventFunction)&wxRibbonPanel::OnMouseEnterChild, NULL, this);
-    child->Connect(wxEVT_LEAVE_WINDOW, (wxObjectEventFunction)&wxRibbonPanel::OnMouseLeaveChild, NULL, this);
+    child->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(wxRibbonPanel::OnMouseEnterChild), NULL, this);
+    child->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(wxRibbonPanel::OnMouseLeaveChild), NULL, this);
 }
 
 void wxRibbonPanel::RemoveChild(wxWindowBase *child)
 {
-    child->Disconnect(wxEVT_ENTER_WINDOW, (wxObjectEventFunction)&wxRibbonPanel::OnMouseEnterChild, NULL, this);
-    child->Disconnect(wxEVT_LEAVE_WINDOW, (wxObjectEventFunction)&wxRibbonPanel::OnMouseLeaveChild, NULL, this);
+    child->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(wxRibbonPanel::OnMouseEnterChild), NULL, this);
+    child->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(wxRibbonPanel::OnMouseLeaveChild), NULL, this);
 
     wxRibbonControl::RemoveChild(child);
 }
 
+bool wxRibbonPanel::HasExtButton()const
+{
+    wxRibbonBar* bar = GetAncestorRibbonBar();
+    if(bar==NULL)
+        return false;
+    return (m_flags & wxRIBBON_PANEL_EXT_BUTTON) &&
+        (bar->GetWindowStyleFlag() & wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS);
+}
+
 void wxRibbonPanel::OnSize(wxSizeEvent& evt)
 {
     if(GetAutoLayout())
@@ -311,6 +343,25 @@ bool wxRibbonPanel::IsSizingContinuous() const
     return (m_flags & wxRIBBON_PANEL_STRETCH) != 0;
 }
 
+// Finds the best width and height given the parent's width and height
+wxSize wxRibbonPanel::GetBestSizeForParentSize(const wxSize& parentSize) const
+{
+    if (GetChildren().GetCount() == 1)
+    {
+        wxWindow* win = GetChildren().GetFirst()->GetData();
+        wxRibbonControl* control = wxDynamicCast(win, wxRibbonControl);
+        if (control)
+        {
+            wxClientDC temp_dc((wxRibbonPanel*) this);
+            wxSize clientParentSize = m_art->GetPanelClientSize(temp_dc, this, parentSize, NULL);
+            wxSize childSize = control->GetBestSizeForParentSize(clientParentSize);
+            wxSize overallSize = m_art->GetPanelSize(temp_dc, this, childSize, NULL);
+            return overallSize;
+        }
+    }
+    return GetSize();
+}
+
 wxSize wxRibbonPanel::DoGetNextSmallerSize(wxOrientation direction,
                                          wxSize relative_to) const
 {
@@ -702,6 +753,10 @@ bool wxRibbonPanel::Layout()
         wxWindow* child = GetChildren().Item(0)->GetData();
         child->SetSize(position.x, position.y, size.GetWidth(), size.GetHeight());
     }
+
+    if(HasExtButton())
+        m_ext_button_rect = m_art->GetPanelExtButtonArea(dc, this, GetSize());
+
     return true;
 }
 
@@ -718,6 +773,13 @@ void wxRibbonPanel::OnMouseClick(wxMouseEvent& WXUNUSED(evt))
             ShowExpanded();
         }
     }
+    else if(IsExtButtonHovered())
+    {
+        wxRibbonPanelEvent notification(wxEVT_RIBBONPANEL_EXTBUTTON_ACTIVATED, GetId());
+        notification.SetEventObject(this);
+        notification.SetPanel(this);
+        ProcessEvent(notification);
+    }
 }
 
 wxRibbonPanel* wxRibbonPanel::GetExpandedDummy()
@@ -742,6 +804,13 @@ bool wxRibbonPanel::ShowExpanded()
     }
 
     wxSize size = GetBestSize();
+
+    // Special case for flexible panel layout, where GetBestSize doesn't work
+    if (GetFlags() & wxRIBBON_PANEL_FLEXIBLE)
+    {
+        size = GetBestSizeForParentSize(wxSize(400, 1000));
+    }
+
     wxPoint pos = GetExpandedPosition(wxRect(GetScreenPosition(), GetSize()),
         size, m_preferred_expand_direction).GetTopLeft();
 
@@ -750,7 +819,7 @@ bool wxRibbonPanel::ShowExpanded()
         pos, size, wxFRAME_NO_TASKBAR | wxBORDER_NONE);
 
     m_expanded_panel = new wxRibbonPanel(container, wxID_ANY,
-        GetLabel(), m_minimised_icon, wxPoint(0, 0), size, m_flags);
+        GetLabel(), m_minimised_icon, wxPoint(0, 0), size, (m_flags /* & ~wxRIBBON_PANEL_FLEXIBLE */));
 
     m_expanded_panel->SetArtProvider(m_art);
     m_expanded_panel->m_expanded_dummy = this;
@@ -866,7 +935,7 @@ void wxRibbonPanel::OnChildKillFocus(wxFocusEvent& evt)
         HideExpanded();
         // Do not skip event, as the panel has been de-expanded, causing the
         // child with focus to be reparented (and hidden). If the event
-        // continues propogation then bad things happen.
+        // continues propagation then bad things happen.
     }
     else
     {
@@ -1029,4 +1098,9 @@ wxRect wxRibbonPanel::GetExpandedPosition(wxRect panel,
     return best;
 }
 
+void wxRibbonPanel::HideIfExpanded()
+{
+    wxStaticCast(m_parent, wxRibbonPage)->HideIfExpanded();
+}
+
 #endif // wxUSE_RIBBON