X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ca275c039c9e53bd37c008a19e30c382fbb65895..c4dae34da879d7d69165beb599e675c083cdd0b5:/src/ribbon/bar.cpp diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index 625324fa7d..e64b381778 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -20,6 +20,7 @@ #include "wx/ribbon/bar.h" #include "wx/ribbon/art.h" #include "wx/dcbuffer.h" +#include "wx/app.h" #ifndef WX_PRECOMP #endif @@ -39,6 +40,7 @@ wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONBAR_TAB_MIDDLE_UP, wxRibbonBarEvent); wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONBAR_TAB_RIGHT_DOWN, wxRibbonBarEvent); wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONBAR_TAB_RIGHT_UP, wxRibbonBarEvent); wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONBAR_TAB_LEFT_DCLICK, wxRibbonBarEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONBAR_TOGGLED, wxRibbonBarEvent); IMPLEMENT_CLASS(wxRibbonBar, wxRibbonControl) IMPLEMENT_DYNAMIC_CLASS(wxRibbonBarEvent, wxNotifyEvent) @@ -65,6 +67,8 @@ void wxRibbonBar::AddPage(wxRibbonPage *page) info.page = page; info.active = false; info.hovered = false; + info.highlight = false; + info.shown = true; // info.rect not set (intentional) wxClientDC dcTemp(this); @@ -140,6 +144,8 @@ bool wxRibbonBar::Realize() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; RepositionPage(info.page); if(!info.page->Realize()) { @@ -239,6 +245,7 @@ void wxRibbonBar::OnMouseMove(wxMouseEvent& evt) { RefreshTabBar(); } + HitTestToggleButton(evt.GetPosition()); } void wxRibbonBar::OnMouseLeave(wxMouseEvent& WXUNUSED(evt)) @@ -266,6 +273,12 @@ void wxRibbonBar::OnMouseLeave(wxMouseEvent& WXUNUSED(evt)) { RefreshTabBar(); } + if(m_toggle_button_hovered) + { + m_bar_hovered = false; + m_toggle_button_hovered = false; + Refresh(false); + } } wxRibbonPage* wxRibbonBar::GetPage(int n) @@ -275,6 +288,100 @@ wxRibbonPage* wxRibbonBar::GetPage(int n) return m_pages.Item(n).page; } +size_t wxRibbonBar::GetPageCount() const +{ + return m_pages.GetCount(); +} + +bool wxRibbonBar::IsPageShown(size_t page) const +{ + if (page >= m_pages.GetCount()) + return false; + return m_pages.Item(page).shown; +} + +void wxRibbonBar::ShowPage(size_t page, bool show) +{ + if(page >= m_pages.GetCount()) + return; + m_pages.Item(page).shown = show; +} + +bool wxRibbonBar::IsPageHighlighted(size_t page) const +{ + if (page >= m_pages.GetCount()) + return false; + return m_pages.Item(page).highlight; +} + +void wxRibbonBar::AddPageHighlight(size_t page, bool highlight) +{ + if(page >= m_pages.GetCount()) + return; + m_pages.Item(page).highlight = highlight; +} + +void wxRibbonBar::DeletePage(size_t n) +{ + if(n < m_pages.GetCount()) + { + wxRibbonPage *page = m_pages.Item(n).page; + + // Schedule page object for destruction and not destroying directly + // as this function can be called in an event handler and page functions + // can be called afeter removing. + // Like in wxRibbonButtonBar::OnMouseUp + if(!wxTheApp->IsScheduledForDestruction(page)) + { + wxTheApp->ScheduleForDestruction(page); + } + + m_pages.RemoveAt(n); + + if(m_current_page == static_cast(n)) + { + m_current_page = -1; + + if(m_pages.GetCount() > 0) + { + if(n >= m_pages.GetCount()) + { + SetActivePage(m_pages.GetCount() - 1); + } + else + { + SetActivePage(n - 1); + } + } + } + else if(m_current_page > static_cast(n)) + { + m_current_page--; + } + } +} + +void wxRibbonBar::ClearPages() +{ + size_t i; + for(i=0; iIsScheduledForDestruction(page)) + { + wxTheApp->ScheduleForDestruction(page); + } + } + m_pages.Empty(); + Realize(); + m_current_page = -1; + Refresh(); +} + bool wxRibbonBar::SetActivePage(size_t page) { if(m_current_page == (int)page) @@ -294,6 +401,7 @@ bool wxRibbonBar::SetActivePage(size_t page) } m_current_page = (int)page; m_pages.Item(page).active = true; + m_pages.Item(page).shown = true; { wxRibbonPage* wnd = m_pages.Item(page).page; RepositionPage(wnd); @@ -319,6 +427,20 @@ bool wxRibbonBar::SetActivePage(wxRibbonPage* page) return false; } +int wxRibbonBar::GetPageNumber(wxRibbonPage* page) const +{ + size_t numpages = m_pages.GetCount(); + for(size_t i = 0; i < numpages; ++i) + { + if(m_pages.Item(i).page == page) + { + return i; + } + } + return wxNOT_FOUND; +} + + int wxRibbonBar::GetActivePage() const { return m_current_page; @@ -356,6 +478,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; info.rect.x = x; info.rect.y = y; info.rect.width = info.ideal_width; @@ -373,6 +497,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; info.rect.x = x; info.rect.y = y; info.rect.width = info.minimum_width; @@ -409,6 +535,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; info.rect.x -= m_tab_scroll_amount; } } @@ -430,6 +558,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; if(info.small_must_have_separator_width < smallest_tab_width) { smallest_tab_width = info.small_must_have_separator_width; @@ -445,6 +575,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; int delta = info.ideal_width - info.small_must_have_separator_width; info.rect.x = x; info.rect.y = y; @@ -463,6 +595,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; if(info.minimum_width < smallest_tab_width) { total_small_width += smallest_tab_width; @@ -479,6 +613,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { // Sneaky obj array trickery to not copy the tab descriptors + if (!m_pages.Item(i).shown) + continue; sorted_pages.Add(&m_pages.Item(i)); } sorted_pages.Sort(OrderPageTabInfoBySmallWidthAsc); @@ -486,6 +622,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = sorted_pages.Item(i); + if (!info.shown) + continue; if(info.small_must_have_separator_width * (int)(numtabs - i) <= width) { info.rect.width = info.small_must_have_separator_width;; @@ -499,6 +637,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; info.rect.x = x; info.rect.y = y; info.rect.height = m_tab_height; @@ -516,6 +656,8 @@ void wxRibbonBar::RecalculateTabSizes() for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; int delta = smallest_tab_width - info.minimum_width; info.rect.x = x; info.rect.y = y; @@ -601,6 +743,9 @@ void wxRibbonBar::CommonInit(long style) SetArtProvider(new wxRibbonDefaultArtProvider); } SetBackgroundStyle(wxBG_STYLE_CUSTOM); + + m_toggle_button_hovered = false; + m_bar_hovered = false; } void wxRibbonBar::SetArtProvider(wxRibbonArtProvider* art) @@ -638,6 +783,8 @@ void wxRibbonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) DoEraseBackground(dc); + m_toggle_button_rect = m_art->GetBarToggleButtonArea(dc, this, GetSize()); + size_t numtabs = m_pages.GetCount(); double sep_visibility = 0.0; bool draw_sep = false; @@ -651,6 +798,8 @@ void wxRibbonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; dc.DestroyClippingRegion(); if(m_tab_scroll_buttons_shown) @@ -683,6 +832,8 @@ void wxRibbonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) for(i = 0; i < numtabs - 1; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; rect.x = info.rect.x + info.rect.width; if(m_tab_scroll_buttons_shown && !tabs_rect.Intersects(rect)) @@ -707,6 +858,9 @@ void wxRibbonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) m_art->DrawScrollButton(dc, this, m_tab_scroll_right_button_rect, wxRIBBON_SCROLL_BTN_RIGHT | m_tab_scroll_right_button_state | wxRIBBON_SCROLL_BTN_FOR_TABS); } } + wxRect rect(GetClientSize().GetWidth() - 30, 6, 12, 12); + if ( m_flags & wxRIBBON_BAR_SHOW_TOGGLE_BUTTON ) + m_art->DrawToggleButton(dc, this, rect, ArePanelsShown()); } void wxRibbonBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) @@ -755,6 +909,8 @@ wxRibbonPageTabInfo* wxRibbonBar::HitTestTabs(wxPoint position, int* index) for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; if(info.rect.Contains(position)) { if(index != NULL) @@ -802,6 +958,23 @@ void wxRibbonBar::OnMouseLeftDown(wxMouseEvent& evt) RefreshTabBar(); } } + + wxPoint position = evt.GetPosition(); + + if(position.x >= 0 && position.y >= 0) + { + wxSize size = GetSize(); + if(position.x < size.GetWidth() && position.y < size.GetHeight()) + { + if(m_toggle_button_rect.Contains(position)) + { + ShowPanels(!ArePanelsShown()); + wxRibbonBarEvent event(wxEVT_COMMAND_RIBBONBAR_TOGGLED, GetId()); + event.SetEventObject(this); + ProcessWindowEvent(event); + } + } + } } void wxRibbonBar::OnMouseLeftUp(wxMouseEvent& WXUNUSED(evt)) @@ -852,6 +1025,8 @@ void wxRibbonBar::ScrollTabBar(int amount) for(i = 0; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; info.rect.SetX(info.rect.GetX() - amount); } if(show_right != (m_tab_scroll_right_button_rect.GetWidth() != 0) || @@ -942,6 +1117,8 @@ void wxRibbonBar::RecalculateMinSize() for(i = 1; i < numtabs; ++i) { wxRibbonPageTabInfo& info = m_pages.Item(i); + if (!info.shown) + continue; wxSize page_min = info.page->GetMinSize(); min_size.x = wxMax(min_size.x, page_min.x); @@ -981,4 +1158,29 @@ wxSize wxRibbonBar::DoGetBestSize() const return best; } +void wxRibbonBar::HitTestToggleButton(wxPoint position) +{ + bool hovered = false, toggle_button_hovered = false; + if(position.x >= 0 && position.y >= 0) + { + wxSize size = GetSize(); + if(position.x < size.GetWidth() && position.y < size.GetHeight()) + { + hovered = true; + } + } + if(hovered) + { + toggle_button_hovered = (m_flags & wxRIBBON_BAR_SHOW_TOGGLE_BUTTON) && + m_toggle_button_rect.Contains(position); + + if(hovered != m_bar_hovered || toggle_button_hovered != m_toggle_button_hovered) + { + m_bar_hovered = hovered; + m_toggle_button_hovered = toggle_button_hovered; + Refresh(false); + } + } +} + #endif // wxUSE_RIBBON