diff --git a/include/wx/ribbon/art.h b/include/wx/ribbon/art.h index 034a48e36c..5c628d92cf 100644 --- a/include/wx/ribbon/art.h +++ b/include/wx/ribbon/art.h @@ -19,6 +19,7 @@ #include "wx/font.h" #include "wx/pen.h" #include "wx/bitmap.h" +#include "wx/bmpbndl.h" #include "wx/ribbon/bar.h" class WXDLLIMPEXP_FWD_CORE wxDC; @@ -638,7 +639,7 @@ protected: void DrawGalleryBackgroundCommon(wxDC& dc, wxRibbonGallery* wnd, const wxRect& rect); virtual void DrawGalleryButton(wxDC& dc, wxRect rect, - wxRibbonGalleryButtonState state, wxBitmap* bitmaps); + wxRibbonGalleryButtonState state, wxBitmapBundle* bundles, wxWindow* wnd); void DrawButtonBarButtonForeground( wxDC& dc, const wxRect& rect, @@ -655,15 +656,15 @@ protected: void CloneTo(wxRibbonMSWArtProvider* copy) const; wxBitmap m_cached_tab_separator; - wxBitmap m_gallery_up_bitmap[4]; - wxBitmap m_gallery_down_bitmap[4]; - wxBitmap m_gallery_extension_bitmap[4]; - wxBitmap m_toolbar_drop_bitmap; - wxBitmap m_panel_extension_bitmap[2]; - wxBitmap m_ribbon_toggle_up_bitmap[2]; - wxBitmap m_ribbon_toggle_down_bitmap[2]; - wxBitmap m_ribbon_toggle_pin_bitmap[2]; - wxBitmap m_ribbon_bar_help_button_bitmap[2]; + wxBitmapBundle m_gallery_up_bundle[4]; + wxBitmapBundle m_gallery_down_bundle[4]; + wxBitmapBundle m_gallery_extension_bundle[4]; + wxBitmapBundle m_toolbar_drop_bundle; + wxBitmapBundle m_panel_extension_bundle[2]; + wxBitmapBundle m_ribbon_toggle_up_bundle[2]; + wxBitmapBundle m_ribbon_toggle_down_bundle[2]; + wxBitmapBundle m_ribbon_toggle_pin_bundle[2]; + wxBitmapBundle m_ribbon_bar_help_button_bundle[2]; wxColour m_primary_scheme_colour; wxColour m_secondary_scheme_colour; @@ -885,7 +886,7 @@ protected: void DrawPartialPageBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect, bool allow_hovered = true); void DrawGalleryButton(wxDC& dc, wxRect rect, - wxRibbonGalleryButtonState state, wxBitmap* bitmaps) override; + wxRibbonGalleryButtonState state, wxBitmapBundle* bundles, wxWindow* wnd) override; void DrawPanelBorder(wxDC& dc, const wxRect& rect, wxPen& primary_colour, wxPen& secondary_colour); void ReallyDrawTabSeparator(wxWindow* wnd, const wxRect& rect, @@ -1029,7 +1030,7 @@ protected: void DrawPartialPanelBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect); void DrawGalleryButton(wxDC& dc, wxRect rect, - wxRibbonGalleryButtonState state, wxBitmap* bitmaps) override; + wxRibbonGalleryButtonState state, wxBitmapBundle* bundles, wxWindow* wnd) override; wxColour m_tab_ctrl_background_colour; wxColour m_tab_ctrl_background_gradient_colour; diff --git a/include/wx/ribbon/bar.h b/include/wx/ribbon/bar.h index 9df7a829b4..e7831d6d99 100644 --- a/include/wx/ribbon/bar.h +++ b/include/wx/ribbon/bar.h @@ -161,8 +161,10 @@ public: void HideIfExpanded(); - // Return the image list containing images of the given size, creating it - // if necessary. + // Deprecated: wxRibbonButtonBar now uses wxBitmapBundle directly for + // DPI-aware bitmap management. This method is maintained for backward + // compatibility but is no longer used by wxRibbonButtonBar. + wxDEPRECATED_MSG("wxRibbonButtonBar now uses wxBitmapBundle for DPI support") wxImageList* GetButtonImageList(wxSize size, int initialCount = 1); protected: @@ -185,6 +187,7 @@ protected: void OnEraseBackground(wxEraseEvent& evt); void DoEraseBackground(wxDC& dc); void OnSize(wxSizeEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnMouseLeftDown(wxMouseEvent& evt); void OnMouseLeftUp(wxMouseEvent& evt); void OnMouseMiddleDown(wxMouseEvent& evt); diff --git a/include/wx/ribbon/buttonbar.h b/include/wx/ribbon/buttonbar.h index 26f3d42a25..64dc942111 100644 --- a/include/wx/ribbon/buttonbar.h +++ b/include/wx/ribbon/buttonbar.h @@ -16,6 +16,7 @@ #include "wx/ribbon/art.h" #include "wx/ribbon/control.h" #include "wx/dynarray.h" +#include "wx/bmpbndl.h" class wxRibbonButtonBar; class wxRibbonButtonBarButtonBase; @@ -47,7 +48,7 @@ public: virtual wxRibbonButtonBarButtonBase* AddButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); // NB: help_string cannot be optional as that would cause the signature @@ -57,28 +58,28 @@ public: virtual wxRibbonButtonBarButtonBase* AddDropdownButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* AddHybridButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* AddToggleButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* AddButton( int button_id, const wxString& label, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small = wxNullBitmap, - const wxBitmap& bitmap_disabled = wxNullBitmap, - const wxBitmap& bitmap_small_disabled = wxNullBitmap, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small = wxBitmapBundle(), + const wxBitmapBundle& bitmap_disabled = wxBitmapBundle(), + const wxBitmapBundle& bitmap_small_disabled = wxBitmapBundle(), wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, const wxString& help_string = wxEmptyString); @@ -86,7 +87,7 @@ public: size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); @@ -94,31 +95,31 @@ public: size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* InsertHybridButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* InsertToggleButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonButtonBarButtonBase* InsertButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small = wxNullBitmap, - const wxBitmap& bitmap_disabled = wxNullBitmap, - const wxBitmap& bitmap_small_disabled = wxNullBitmap, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small = wxBitmapBundle(), + const wxBitmapBundle& bitmap_disabled = wxBitmapBundle(), + const wxBitmapBundle& bitmap_small_disabled = wxBitmapBundle(), wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, const wxString& help_string = wxEmptyString); @@ -142,10 +143,10 @@ public: virtual void SetButtonIcon( int button_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small = wxNullBitmap, - const wxBitmap& bitmap_disabled = wxNullBitmap, - const wxBitmap& bitmap_small_disabled = wxNullBitmap); + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small = wxBitmapBundle(), + const wxBitmapBundle& bitmap_disabled = wxBitmapBundle(), + const wxBitmapBundle& bitmap_small_disabled = wxBitmapBundle()); virtual void SetButtonText(int button_id, const wxString& label); virtual void SetButtonTextMinWidth(int button_id, @@ -167,6 +168,9 @@ public: void SetShowToolTipsForDisabled(bool show); bool GetShowToolTipsForDisabled() const; + // Get bitmap for button (DPI-aware resolution) + wxBitmap GetButtonBitmap(int imageIndex, bool large) const; + protected: friend class wxRibbonButtonBarEvent; virtual wxSize DoGetBestSize() const override; @@ -180,6 +184,7 @@ protected: void OnMouseLeave(wxMouseEvent& evt); void OnMouseDown(wxMouseEvent& evt); void OnMouseUp(wxMouseEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); virtual wxSize DoGetNextSmallerSize(wxOrientation direction, wxSize relative_to) const override; @@ -208,9 +213,15 @@ protected: bool m_lock_active_state; bool m_show_tooltips_for_disabled; + std::vector m_bundlesLarge; // Large button icons + std::vector m_bundlesSmall; // Small button icons + std::vector m_bundlesLargeDisabled; // Disabled large icons + std::vector m_bundlesSmallDisabled; // Disabled small icons + private: wxRibbonBar* m_ribbonBar = nullptr; + #ifndef SWIG wxDECLARE_CLASS(wxRibbonButtonBar); wxDECLARE_EVENT_TABLE(); diff --git a/include/wx/ribbon/gallery.h b/include/wx/ribbon/gallery.h index f525dc50fd..443c8722bd 100644 --- a/include/wx/ribbon/gallery.h +++ b/include/wx/ribbon/gallery.h @@ -15,6 +15,7 @@ #include "wx/ribbon/art.h" #include "wx/ribbon/control.h" +#include "wx/bmpbndl.h" class wxRibbonGalleryItem; @@ -44,9 +45,9 @@ public: bool IsEmpty() const; unsigned int GetCount() const; wxRibbonGalleryItem* GetItem(unsigned int n); - wxRibbonGalleryItem* Append(const wxBitmap& bitmap, int id); - wxRibbonGalleryItem* Append(const wxBitmap& bitmap, int id, void* clientData); - wxRibbonGalleryItem* Append(const wxBitmap& bitmap, int id, wxClientData* clientData); + wxRibbonGalleryItem* Append(const wxBitmapBundle& bitmap, int id); + wxRibbonGalleryItem* Append(const wxBitmapBundle& bitmap, int id, void* clientData); + wxRibbonGalleryItem* Append(const wxBitmapBundle& bitmap, int id, wxClientData* clientData); void SetItemClientObject(wxRibbonGalleryItem* item, wxClientData* data); wxClientData* GetItemClientObject(const wxRibbonGalleryItem* item) const; @@ -86,6 +87,7 @@ protected: void OnMouseDClick(wxMouseEvent& evt); void OnPaint(wxPaintEvent& evt); void OnSize(wxSizeEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); int GetScrollLineSize() const; virtual wxSize DoGetBestSize() const override; diff --git a/include/wx/ribbon/page.h b/include/wx/ribbon/page.h index b7e269d8bb..baa734e53d 100644 --- a/include/wx/ribbon/page.h +++ b/include/wx/ribbon/page.h @@ -16,7 +16,7 @@ #include "wx/ribbon/control.h" #include "wx/ribbon/panel.h" -#include "wx/bitmap.h" +#include "wx/bmpbndl.h" class wxRibbonBar; class wxRibbonPageScrollButton; @@ -29,7 +29,7 @@ public: wxRibbonPage(wxRibbonBar* parent, wxWindowID id = wxID_ANY, const wxString& label = wxEmptyString, - const wxBitmap& icon = wxNullBitmap, + const wxBitmapBundle& icon = wxBitmapBundle(), long style = 0); virtual ~wxRibbonPage(); @@ -37,12 +37,13 @@ public: bool Create(wxRibbonBar* parent, wxWindowID id = wxID_ANY, const wxString& label = wxEmptyString, - const wxBitmap& icon = wxNullBitmap, + const wxBitmapBundle& icon = wxBitmapBundle(), long style = 0); void SetArtProvider(wxRibbonArtProvider* art) override; - wxBitmap& GetIcon() {return m_icon;} + wxBitmap GetIcon() {return m_icon.GetBitmapFor(this);} + const wxBitmapBundle& GetIconBundle() const {return m_icon;} virtual wxSize GetMinSize() const override; void SetSizeWithScrollButtonAdjustment(int x, int y, int width, int height); void AdjustRectToIncludeScrollButtons(wxRect* rect) const; @@ -75,17 +76,18 @@ protected: void OnEraseBackground(wxEraseEvent& evt); void OnPaint(wxPaintEvent& evt); void OnSize(wxSizeEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); bool ExpandPanels(wxOrientation direction, int maximum_amount); bool CollapsePanels(wxOrientation direction, int minimum_amount); bool ShowScrollButtons(); void HideScrollButtons(); - void CommonInit(const wxString& label, const wxBitmap& icon); + void CommonInit(const wxString& label, const wxBitmapBundle& icon); void PopulateSizeCalcArray(wxSize (wxWindow::*get_size)(void) const); wxArrayRibbonControl m_collapse_stack; - wxBitmap m_icon; + wxBitmapBundle m_icon; wxSize m_old_size; // NB: Scroll button windows are siblings rather than children (to get correct clipping of children) wxRibbonPageScrollButton* m_scroll_left_btn = nullptr; diff --git a/include/wx/ribbon/panel.h b/include/wx/ribbon/panel.h index 28ddb5abbe..25780c7f6a 100644 --- a/include/wx/ribbon/panel.h +++ b/include/wx/ribbon/panel.h @@ -13,7 +13,7 @@ #if wxUSE_RIBBON -#include "wx/bitmap.h" +#include "wx/bmpbndl.h" #include "wx/ribbon/control.h" enum wxRibbonPanelOption @@ -35,7 +35,7 @@ public: wxRibbonPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& label = wxEmptyString, - const wxBitmap& minimised_icon = wxNullBitmap, + const wxBitmapBundle& minimised_icon = wxBitmapBundle(), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxRIBBON_PANEL_DEFAULT_STYLE); @@ -45,13 +45,13 @@ public: bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& label = wxEmptyString, - const wxBitmap& icon = wxNullBitmap, + const wxBitmapBundle& icon = wxBitmapBundle(), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxRIBBON_PANEL_DEFAULT_STYLE); - wxBitmap& GetMinimisedIcon() {return m_minimised_icon;} - const wxBitmap& GetMinimisedIcon() const {return m_minimised_icon;} + wxBitmap GetMinimisedIcon() {return m_minimised_icon.GetBitmapFor(this);} + const wxBitmapBundle& GetMinimisedIconBundle() const {return m_minimised_icon;} bool IsMinimised() const; bool IsMinimised(wxSize at_size) const; bool IsHovered() const; @@ -108,17 +108,18 @@ protected: void OnMotion(wxMouseEvent& evt); void OnKillFocus(wxFocusEvent& evt); void OnChildKillFocus(wxFocusEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void TestPositionForHover(const wxPoint& pos); bool ShouldSendEventToDummy(wxEvent& evt); virtual bool TryAfter(wxEvent& evt) override; - void CommonInit(const wxString& label, const wxBitmap& icon, long style); + void CommonInit(const wxString& label, const wxBitmapBundle& icon, long style); static wxRect GetExpandedPosition(wxRect panel, wxSize expanded_size, wxDirection direction); - wxBitmap m_minimised_icon; + wxBitmapBundle m_minimised_icon; wxBitmap m_minimised_icon_resized; wxSize m_smallest_unminimised_size; wxSize m_minimised_size; diff --git a/include/wx/ribbon/toolbar.h b/include/wx/ribbon/toolbar.h index 86c7a449cf..f24ab73082 100644 --- a/include/wx/ribbon/toolbar.h +++ b/include/wx/ribbon/toolbar.h @@ -15,6 +15,7 @@ #include "wx/ribbon/control.h" #include "wx/ribbon/art.h" +#include "wx/bmpbndl.h" class wxRibbonToolBarToolBase; class wxRibbonToolBarToolGroup; @@ -59,29 +60,29 @@ public: virtual wxRibbonToolBarToolBase* AddTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); virtual wxRibbonToolBarToolBase* AddDropdownTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* AddHybridTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* AddToggleTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* AddTool( int tool_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_disabled = wxBitmapBundle(), const wxString& help_string = wxEmptyString, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, wxObject* client_data = nullptr); @@ -91,33 +92,33 @@ public: virtual wxRibbonToolBarToolBase* InsertTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); virtual wxRibbonToolBarToolBase* InsertDropdownTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* InsertHybridTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* InsertToggleTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string = wxEmptyString); virtual wxRibbonToolBarToolBase* InsertTool( size_t pos, int tool_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_disabled = wxBitmapBundle(), const wxString& help_string = wxEmptyString, wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, wxObject* client_data = nullptr); @@ -148,9 +149,9 @@ public: virtual void SetRows(int nMin, int nMax = -1); virtual void SetToolClientData(int tool_id, wxObject* clientData); - virtual void SetToolDisabledBitmap(int tool_id, const wxBitmap &bitmap); + virtual void SetToolDisabledBitmap(int tool_id, const wxBitmapBundle &bitmap); virtual void SetToolHelpString(int tool_id, const wxString& helpString); - virtual void SetToolNormalBitmap(int tool_id, const wxBitmap &bitmap); + virtual void SetToolNormalBitmap(int tool_id, const wxBitmapBundle &bitmap); virtual bool IsSizingContinuous() const override; @@ -173,6 +174,7 @@ protected: void OnMouseUp(wxMouseEvent& evt); void OnPaint(wxPaintEvent& evt); void OnSize(wxSizeEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); virtual wxSize DoGetNextSmallerSize(wxOrientation direction, wxSize relative_to) const override; diff --git a/samples/ribbon/ribbondemo.cpp b/samples/ribbon/ribbondemo.cpp index 3c685aa7f1..ba16885fcc 100644 --- a/samples/ribbon/ribbondemo.cpp +++ b/samples/ribbon/ribbondemo.cpp @@ -23,6 +23,7 @@ #include "wx/dcbuffer.h" #include "wx/colordlg.h" #include "wx/artprov.h" +#include "wx/bmpbndl.h" #include "wx/combobox.h" #include "wx/tglbtn.h" #include "wx/wrapsizer.h" @@ -149,6 +150,7 @@ public: void OnRibbonBarHelpClicked(wxRibbonBarEvent& evt); void OnSizeEvent(wxSizeEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnExtButton(wxRibbonPanelEvent& evt); @@ -260,30 +262,204 @@ EVT_RIBBONBUTTONBAR_CLICKED(ID_CHANGE_LABEL, MyFrame::OnChangeLabel) EVT_RIBBONBAR_TOGGLED(wxID_ANY, MyFrame::OnRibbonBarToggled) EVT_RIBBONBAR_HELP_CLICK(wxID_ANY, MyFrame::OnRibbonBarHelpClicked) EVT_SIZE(MyFrame::OnSizeEvent) +EVT_DPI_CHANGED(MyFrame::OnDPIChanged) wxEND_EVENT_TABLE() -#include "align_center.xpm" -#include "align_left.xpm" -#include "align_right.xpm" -#include "aui_style.xpm" -#include "auto_crop_selection.xpm" -#include "auto_crop_selection_small.xpm" -#include "circle.xpm" -#include "circle_small.xpm" -#include "colours.xpm" -#include "cross.xpm" -#include "empty.xpm" -#include "expand_selection_v.xpm" -#include "expand_selection_h.xpm" -#include "eye.xpm" -#include "hexagon.xpm" -#include "msw_style.xpm" -#include "position_left_small.xpm" -#include "position_top_small.xpm" -#include "ribbon.xpm" -#include "selection_panel.xpm" -#include "square.xpm" -#include "triangle.xpm" +// ---------------------------------------------------------------------------- +// SVG icon data for ribbon-specific icons. +// Each icon uses a 32x32 viewBox for clean scaling at any display size. +// The MakeSvgBundle() helper guarantees a valid (non-empty) bundle is always +// returned, falling back to wxArtProvider when SVG support is unavailable. +// ---------------------------------------------------------------------------- + +namespace +{ + +// -- Shape icons ----------------------------------------------------------- + +static const char circle_svg[] = + "" + "" + ""; + +static const char cross_svg[] = + "" + "" + ""; + +static const char triangle_svg[] = + "" + "" + ""; + +static const char square_svg[] = + "" + "" + ""; + +static const char hexagon_svg[] = + "" + "" + ""; + +// -- Alignment icons ------------------------------------------------------- + +static const char align_left_svg[] = + "" + "" + "" + "" + "" + ""; + +static const char align_center_svg[] = + "" + "" + "" + "" + "" + ""; + +static const char align_right_svg[] = + "" + "" + "" + "" + "" + ""; + +// -- Selection icons ------------------------------------------------------- + +static const char expand_selection_v_svg[] = + "" + "" + ""; + +static const char expand_selection_h_svg[] = + "" + "" + ""; + +static const char auto_crop_selection_svg[] = + "" + "" + "" + "" + "" + "" + ""; + +static const char selection_panel_svg[] = + "" + "" + "" + "" + ""; + +// -- Position icons -------------------------------------------------------- + +static const char position_left_svg[] = + "" + "" + "" + "" + ""; + +static const char position_top_svg[] = + "" + "" + "" + "" + ""; + +// -- Art provider style icons ---------------------------------------------- + +static const char aui_style_svg[] = + "" + "" + "" + "" + "" + ""; + +static const char msw_style_svg[] = + "" + "" + "" + "" + "" + "" + ""; + +static const char msw_flat_style_svg[] = + "" + "" + "" + "" + "" + "" + ""; + +// -- Miscellaneous icons --------------------------------------------------- + +static const char ribbon_svg[] = + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static const char eye_svg[] = + "" + "" + "" + "" + ""; + +static const char empty_svg[] = + "" + "" + "" + ""; + +static const char colours_svg[] = + "" + "" + "" + "" + ""; + +// Helper to create a bitmap bundle from embedded SVG data. When wxHAS_SVG is +// available, the SVG is rasterized at any requested size for DPI-aware display. +// Falls back to wxArtProvider to guarantee the returned bundle is never empty, +// which prevents wxASSERT failures in AddTool/AddButton. +wxBitmapBundle MakeSvgBundle(const char* svg_data, const wxSize& size, + const wxArtID& fallback = wxART_QUESTION) +{ +#ifdef wxHAS_SVG + wxBitmapBundle bundle = wxBitmapBundle::FromSVG(svg_data, size); + if ( bundle.IsOk() ) + return bundle; +#else + (void)svg_data; +#endif // wxHAS_SVG + return wxArtProvider::GetBitmapBundle(fallback, wxART_OTHER, size); +} + +} // anonymous namespace MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "wxRibbon Sample Application", wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE) @@ -295,16 +471,25 @@ MyFrame::MyFrame() | wxRIBBON_BAR_SHOW_HELP_BUTTON ); + // Reusable bitmap bundles for the generic ribbon and empty-page icons. + const wxBitmapBundle ribbon_small = MakeSvgBundle(ribbon_svg, wxSize(16, 16)); + const wxBitmapBundle ribbon_large = MakeSvgBundle(ribbon_svg, wxSize(32, 32)); + const wxBitmapBundle empty_small = MakeSvgBundle(empty_svg, wxSize(16, 16)); + { - wxRibbonPage* home = new wxRibbonPage(m_ribbon, wxID_ANY, "Examples", ribbon_xpm); + wxRibbonPage* home = new wxRibbonPage(m_ribbon, wxID_ANY, "Examples", + ribbon_small); wxRibbonPanel *toolbar_panel = new wxRibbonPanel(home, wxID_ANY, "Toolbar", - wxNullBitmap, wxDefaultPosition, wxDefaultSize, + wxBitmapBundle(), wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE | wxRIBBON_PANEL_EXT_BUTTON); wxRibbonToolBar *toolbar = new wxRibbonToolBar(toolbar_panel, ID_MAIN_TOOLBAR); - toolbar->AddToggleTool(wxID_JUSTIFY_LEFT, align_left_xpm); - toolbar->AddToggleTool(wxID_JUSTIFY_CENTER , align_center_xpm); - toolbar->AddToggleTool(wxID_JUSTIFY_RIGHT, align_right_xpm); + toolbar->AddToggleTool(wxID_JUSTIFY_LEFT, + MakeSvgBundle(align_left_svg, wxSize(16, 16))); + toolbar->AddToggleTool(wxID_JUSTIFY_CENTER, + MakeSvgBundle(align_center_svg, wxSize(16, 16))); + toolbar->AddToggleTool(wxID_JUSTIFY_RIGHT, + MakeSvgBundle(align_right_svg, wxSize(16, 16))); toolbar->AddSeparator(); toolbar->AddHybridTool(wxID_NEW, wxArtProvider::GetBitmap(wxART_NEW, wxART_OTHER, wxSize(16, 15))); toolbar->AddTool(wxID_OPEN, wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_OTHER, wxSize(16, 15)), "Open something"); @@ -320,9 +505,11 @@ MyFrame::MyFrame() toolbar->AddTool(wxID_ANY, wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_OTHER, wxSize(16, 15))); toolbar->AddTool(wxID_ANY, wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_OTHER, wxSize(16, 15))); toolbar->AddSeparator(); - toolbar->AddHybridTool(ID_POSITION_LEFT, position_left_xpm, + toolbar->AddHybridTool(ID_POSITION_LEFT, + MakeSvgBundle(position_left_svg, wxSize(16, 16)), "Align ribbonbar vertically\non the left\nfor demonstration purposes"); - toolbar->AddHybridTool(ID_POSITION_TOP, position_top_xpm, + toolbar->AddHybridTool(ID_POSITION_TOP, + MakeSvgBundle(position_top_svg, wxSize(16, 16)), "Align the ribbonbar horizontally\nat the top\nfor demonstration purposes"); toolbar->AddSeparator(); wxRibbonToolBarToolBase* print_tool; @@ -340,25 +527,36 @@ MyFrame::MyFrame() wxLogError("wxRibbonToolBar::GetToolByPos(size_t) is broken"); } - wxRibbonPanel *selection_panel = new wxRibbonPanel(home, wxID_ANY, "Selection", wxBitmap(selection_panel_xpm)); + wxRibbonPanel *selection_panel = new wxRibbonPanel(home, wxID_ANY, "Selection", + MakeSvgBundle(selection_panel_svg, wxSize(16, 16))); wxRibbonButtonBar *selection = new wxRibbonButtonBar(selection_panel); - selection->AddButton(ID_SELECTION_EXPAND_V, "Expand Vertically", wxBitmap(expand_selection_v_xpm), - "This is a tooltip for Expand Vertically\ndemonstrating a tooltip"); - selection->AddButton(ID_SELECTION_EXPAND_H, "Expand Horizontally", wxBitmap(expand_selection_h_xpm), wxEmptyString); - selection->AddButton(ID_SELECTION_CONTRACT, "Contract", wxBitmap(auto_crop_selection_xpm), wxBitmap(auto_crop_selection_small_xpm)); + selection->AddButton(ID_SELECTION_EXPAND_V, "Expand Vertically", + MakeSvgBundle(expand_selection_v_svg, wxSize(32, 32)), + "This is a tooltip for Expand Vertically\ndemonstrating a tooltip"); + selection->AddButton(ID_SELECTION_EXPAND_H, "Expand Horizontally", + MakeSvgBundle(expand_selection_h_svg, wxSize(32, 32)), wxEmptyString); + wxBitmapBundle crop_bundle = MakeSvgBundle(auto_crop_selection_svg, wxSize(32, 32)); + selection->AddButton(ID_SELECTION_CONTRACT, "Contract", + crop_bundle, crop_bundle); - wxRibbonPanel *shapes_panel = new wxRibbonPanel(home, wxID_ANY, "Shapes", wxBitmap(circle_small_xpm)); + wxRibbonPanel *shapes_panel = new wxRibbonPanel(home, wxID_ANY, "Shapes", + MakeSvgBundle(circle_svg, wxSize(16, 16))); wxRibbonButtonBar *shapes = new wxRibbonButtonBar(shapes_panel); - shapes->AddButton(ID_CIRCLE, "Circle", wxBitmap(circle_xpm), wxBitmap(circle_small_xpm), - wxNullBitmap, wxNullBitmap, wxRIBBON_BUTTON_NORMAL, + wxBitmapBundle circle_bundle = MakeSvgBundle(circle_svg, wxSize(32, 32)); + shapes->AddButton(ID_CIRCLE, "Circle", circle_bundle, circle_bundle, + wxBitmapBundle(), wxBitmapBundle(), wxRIBBON_BUTTON_NORMAL, "This is a tooltip for the circle button\ndemonstrating another tooltip"); - shapes->AddButton(ID_CROSS, "Cross", wxBitmap(cross_xpm), wxEmptyString); - shapes->AddHybridButton(ID_TRIANGLE, "Triangle", wxBitmap(triangle_xpm)); - shapes->AddButton(ID_SQUARE, "Square", wxBitmap(square_xpm), wxEmptyString); - shapes->AddDropdownButton(ID_POLYGON, "Other Polygon", wxBitmap(hexagon_xpm), wxEmptyString); + shapes->AddButton(ID_CROSS, "Cross", + MakeSvgBundle(cross_svg, wxSize(32, 32)), wxEmptyString); + shapes->AddHybridButton(ID_TRIANGLE, "Triangle", + MakeSvgBundle(triangle_svg, wxSize(32, 32))); + shapes->AddButton(ID_SQUARE, "Square", + MakeSvgBundle(square_svg, wxSize(32, 32)), wxEmptyString); + shapes->AddDropdownButton(ID_POLYGON, "Other Polygon", + MakeSvgBundle(hexagon_svg, wxSize(32, 32)), wxEmptyString); wxRibbonPanel *sizer_panel = new wxRibbonPanel(home, wxID_ANY, "Panel with Sizer", - wxNullBitmap, wxDefaultPosition, wxDefaultSize, + wxBitmapBundle(), wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_DEFAULT_STYLE); wxArrayString as; @@ -380,8 +578,8 @@ MyFrame::MyFrame() sizer_panelcombo2->SetMinSize(wxSize(150, -1)); wxRibbonButtonBar* bar = new wxRibbonButtonBar(sizer_panel, wxID_ANY); - bar->AddButton(ID_BUTTON_XX, "xx", ribbon_xpm); - bar->AddButton(ID_BUTTON_XY, "xy", ribbon_xpm); + bar->AddButton(ID_BUTTON_XX, "xx", ribbon_large); + bar->AddButton(ID_BUTTON_XY, "xy", ribbon_large); // This prevents ribbon buttons in panels with sizer from collapsing. bar->SetButtonMinSizeClass(ID_BUTTON_XX, wxRIBBON_BUTTONBAR_BUTTON_LARGE); bar->SetButtonMinSizeClass(ID_BUTTON_XY, wxRIBBON_BUTTONBAR_BUTTON_LARGE); @@ -399,113 +597,126 @@ MyFrame::MyFrame() wxFont label_font(wxFontInfo(8).Light()); m_bitmap_creation_dc.SetFont(label_font); - wxRibbonPage* scheme = new wxRibbonPage(m_ribbon, wxID_ANY, "Appearance", eye_xpm); + wxRibbonPage* scheme = new wxRibbonPage(m_ribbon, wxID_ANY, "Appearance", + MakeSvgBundle(eye_svg, wxSize(16, 16))); m_ribbon->GetArtProvider()->GetColourScheme(&m_default_primary, &m_default_secondary, &m_default_tertiary); wxRibbonPanel *provider_panel = new wxRibbonPanel(scheme, wxID_ANY, - "Art", wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE); + "Art", wxBitmapBundle(), wxDefaultPosition, wxDefaultSize, + wxRIBBON_PANEL_NO_AUTO_MINIMISE); wxRibbonButtonBar *provider_bar = new wxRibbonButtonBar(provider_panel, wxID_ANY); provider_bar->AddButton(ID_DEFAULT_PROVIDER, "Default Provider", wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(32, 32))); - provider_bar->AddButton(ID_AUI_PROVIDER, "AUI Provider", aui_style_xpm); - provider_bar->AddButton(ID_MSW_PROVIDER, "MSW Provider", msw_style_xpm); - provider_bar->AddButton(ID_MSW_FLAT_PROVIDER, "MSW Flat Provider", msw_style_xpm); + provider_bar->AddButton(ID_AUI_PROVIDER, "AUI Provider", + MakeSvgBundle(aui_style_svg, wxSize(32, 32))); + provider_bar->AddButton(ID_MSW_PROVIDER, "MSW Provider", + MakeSvgBundle(msw_style_svg, wxSize(32, 32))); + provider_bar->AddButton(ID_MSW_FLAT_PROVIDER, "MSW Flat Provider", + MakeSvgBundle(msw_flat_style_svg, wxSize(32, 32))); wxRibbonPanel *primary_panel = new wxRibbonPanel(scheme, wxID_ANY, - "Primary Colour", colours_xpm); + "Primary Colour", MakeSvgBundle(colours_svg, wxSize(16, 16))); m_primary_gallery = PopulateColoursPanel(primary_panel, m_default_primary, ID_PRIMARY_COLOUR); wxRibbonPanel *secondary_panel = new wxRibbonPanel(scheme, wxID_ANY, - "Secondary Colour", colours_xpm); + "Secondary Colour", MakeSvgBundle(colours_svg, wxSize(16, 16))); m_secondary_gallery = PopulateColoursPanel(secondary_panel, m_default_secondary, ID_SECONDARY_COLOUR); } { - wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "UI Updated", ribbon_xpm); - wxRibbonPanel *panel = new wxRibbonPanel(page, wxID_ANY, "Enable/Disable", ribbon_xpm); + wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "UI Updated", + ribbon_small); + wxRibbonPanel *panel = new wxRibbonPanel(page, wxID_ANY, "Enable/Disable", + ribbon_small); wxRibbonButtonBar *bar = new wxRibbonButtonBar(panel, wxID_ANY); - bar->AddButton(ID_DISABLED, "Disabled", ribbon_xpm); - bar->AddButton(ID_ENABLE, "Enable", ribbon_xpm); - bar->AddButton(ID_DISABLE, "Disable", ribbon_xpm); - bar->AddButton(ID_UI_ENABLE_UPDATED, "Enable UI updated", ribbon_xpm); + bar->AddButton(ID_DISABLED, "Disabled", ribbon_large); + bar->AddButton(ID_ENABLE, "Enable", ribbon_large); + bar->AddButton(ID_DISABLE, "Disable", ribbon_large); + bar->AddButton(ID_UI_ENABLE_UPDATED, "Enable UI updated", ribbon_large); bar->EnableButton(ID_DISABLED, false); m_bEnabled = true; - panel = new wxRibbonPanel(page, wxID_ANY, "Toggle", ribbon_xpm); + panel = new wxRibbonPanel(page, wxID_ANY, "Toggle", ribbon_small); bar = new wxRibbonButtonBar(panel, wxID_ANY); - bar->AddButton(ID_CHECK, "Toggle", ribbon_xpm); - bar->AddToggleButton(ID_UI_CHECK_UPDATED, "Toggled UI updated", ribbon_xpm); + bar->AddButton(ID_CHECK, "Toggle", ribbon_large); + bar->AddToggleButton(ID_UI_CHECK_UPDATED, "Toggled UI updated", ribbon_large); m_bChecked = true; - panel = new wxRibbonPanel(page, wxID_ANY, "Change text", ribbon_xpm); + panel = new wxRibbonPanel(page, wxID_ANY, "Change text", ribbon_small); bar = new wxRibbonButtonBar(panel, wxID_ANY); - bar->AddButton(ID_CHANGE_TEXT1, "One", ribbon_xpm); - bar->AddButton(ID_CHANGE_TEXT2, "Two", ribbon_xpm); - bar->AddButton(ID_UI_CHANGE_TEXT_UPDATED, "Zero", ribbon_xpm); + bar->AddButton(ID_CHANGE_TEXT1, "One", ribbon_large); + bar->AddButton(ID_CHANGE_TEXT2, "Two", ribbon_large); + bar->AddButton(ID_UI_CHANGE_TEXT_UPDATED, "Zero", ribbon_large); //Also set the general disabled text colour: wxRibbonArtProvider* artProvider = m_ribbon->GetArtProvider(); wxColour tColour = artProvider->GetColor(wxRIBBON_ART_BUTTON_BAR_LABEL_COLOUR); artProvider->SetColor(wxRIBBON_ART_BUTTON_BAR_LABEL_DISABLED_COLOUR, tColour.MakeDisabled()); } - new wxRibbonPage(m_ribbon, wxID_ANY, "Empty Page", empty_xpm); + new wxRibbonPage(m_ribbon, wxID_ANY, "Empty Page", empty_small); { - wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "Another Page", empty_xpm); - wxRibbonPanel *panel = new wxRibbonPanel(page, wxID_ANY, "Page manipulation", ribbon_xpm); + wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "Another Page", + empty_small); + wxRibbonPanel *panel = new wxRibbonPanel(page, wxID_ANY, "Page manipulation", + ribbon_small); wxRibbonButtonBar *bar = new wxRibbonButtonBar(panel, wxID_ANY); bar->AddButton(ID_REMOVE_PAGE, "Remove", wxArtProvider::GetBitmap(wxART_DELETE, wxART_OTHER, wxSize(24, 24))); - bar->AddButton(ID_HIDE_PAGES, "Hide Pages", ribbon_xpm); - bar->AddButton(ID_SHOW_PAGES, "Show Pages", ribbon_xpm); + bar->AddButton(ID_HIDE_PAGES, "Hide Pages", ribbon_large); + bar->AddButton(ID_SHOW_PAGES, "Show Pages", ribbon_large); - panel = new wxRibbonPanel(page, wxID_ANY, "Button bar manipulation", ribbon_xpm); + panel = new wxRibbonPanel(page, wxID_ANY, "Button bar manipulation", + ribbon_small); wxRibbonButtonBar* button_bar = new wxRibbonButtonBar(panel, wxID_ANY); button_bar->AddButton(ID_PLUS_MINUS, "+/-", wxArtProvider::GetBitmap(wxART_PLUS, wxART_OTHER, wxSize(24, 24))); m_plus_minus_state = false; - button_bar->AddButton(ID_CHANGE_LABEL, "short", ribbon_xpm); + button_bar->AddButton(ID_CHANGE_LABEL, "short", ribbon_large); button_bar->SetButtonTextMinWidth(ID_CHANGE_LABEL, "some long text"); m_change_label_state = false; - panel = new wxRibbonPanel(page, wxID_ANY, "Always medium buttons", ribbon_xpm); + panel = new wxRibbonPanel(page, wxID_ANY, "Always medium buttons", + ribbon_small); bar = new wxRibbonButtonBar(panel, wxID_ANY); - bar->AddButton(ID_SMALL_BUTTON_1, "Button 1", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_1, "Button 1", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_1, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_2, "Button 2", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_2, "Button 2", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_2, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_3, "Button 3", ribbon_xpm); - bar->AddButton(ID_SMALL_BUTTON_4, "Button 4", ribbon_xpm); - bar->AddButton(ID_SMALL_BUTTON_5, "Button 5", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_3, "Button 3", ribbon_large); + bar->AddButton(ID_SMALL_BUTTON_4, "Button 4", ribbon_large); + bar->AddButton(ID_SMALL_BUTTON_5, "Button 5", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_5, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_6, "Button 6", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_6, "Button 6", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_6, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); } - new wxRibbonPage(m_ribbon, wxID_ANY, "Highlight Page", empty_xpm); + new wxRibbonPage(m_ribbon, wxID_ANY, "Highlight Page", empty_small); m_ribbon->AddPageHighlight(m_ribbon->GetPageCount()-1); { - wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "Advanced", empty_xpm); - wxRibbonPanel* panel = new wxRibbonPanel(page, wxID_ANY, "Button bar manipulation", ribbon_xpm); + wxRibbonPage* page = new wxRibbonPage(m_ribbon, wxID_ANY, "Advanced", + empty_small); + wxRibbonPanel* panel = new wxRibbonPanel(page, wxID_ANY, "Button bar manipulation", + ribbon_small); wxRibbonButtonBar* button_bar = new wxRibbonButtonBar(panel, wxID_ANY); button_bar->AddButton(ID_PLUS_MINUS, "+/-", wxArtProvider::GetBitmap(wxART_PLUS, wxART_OTHER, wxSize(24, 24))); m_plus_minus_state = false; - button_bar->AddButton(ID_CHANGE_LABEL, "short", ribbon_xpm); + button_bar->AddButton(ID_CHANGE_LABEL, "short", ribbon_large); button_bar->SetButtonTextMinWidth(ID_CHANGE_LABEL, "some long text"); m_change_label_state = false; - panel = new wxRibbonPanel(page, wxID_ANY, "Always medium buttons", ribbon_xpm); + panel = new wxRibbonPanel(page, wxID_ANY, "Always medium buttons", + ribbon_small); wxRibbonButtonBar* bar = new wxRibbonButtonBar(panel, wxID_ANY); - bar->AddButton(ID_SMALL_BUTTON_1, "Button 1", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_1, "Button 1", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_1, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_2, "Button 2", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_2, "Button 2", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_2, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_3, "Button 3", ribbon_xpm); - bar->AddButton(ID_SMALL_BUTTON_4, "Button 4", ribbon_xpm); - bar->AddButton(ID_SMALL_BUTTON_5, "Button 5", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_3, "Button 3", ribbon_large); + bar->AddButton(ID_SMALL_BUTTON_4, "Button 4", ribbon_large); + bar->AddButton(ID_SMALL_BUTTON_5, "Button 5", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_5, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); - bar->AddButton(ID_SMALL_BUTTON_6, "Button 6", ribbon_xpm); + bar->AddButton(ID_SMALL_BUTTON_6, "Button 6", ribbon_large); bar->SetButtonMaxSizeClass(ID_SMALL_BUTTON_6, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM); } - m_ribbon->Realize(); m_logwindow = new wxTextCtrl(this, wxID_ANY, wxEmptyString, @@ -1171,6 +1382,21 @@ void MyFrame::OnRibbonBarHelpClicked(wxRibbonBarEvent& WXUNUSED(evt)) AddText("Ribbon bar help clicked"); } +void MyFrame::OnDPIChanged(wxDPIChangedEvent& evt) +{ + const wxSize oldDPI = evt.GetOldDPI(); + const wxSize newDPI = evt.GetNewDPI(); + + AddText(wxString::Format( + "DPI changed from %d x %d to %d x %d (scale: %.0f%% -> %.0f%%)", + oldDPI.x, oldDPI.y, + newDPI.x, newDPI.y, + oldDPI.x * 100.0 / 96.0, + newDPI.x * 100.0 / 96.0)); + + evt.Skip(); +} + // This shows how to hide ribbon dynamically if there is not enough space. void MyFrame::OnSizeEvent(wxSizeEvent& evt) { diff --git a/src/ribbon/art_aui.cpp b/src/ribbon/art_aui.cpp index 0fdd724f8b..a85e835107 100644 --- a/src/ribbon/art_aui.cpp +++ b/src/ribbon/art_aui.cpp @@ -814,10 +814,10 @@ void wxRibbonAUIArtProvider::DrawPanelBackground( dc.SetPen(m_panel_hover_button_border_pen); dc.SetBrush(m_panel_hover_button_background_brush); dc.DrawRoundedRectangle(label_rect.GetRight() - 13, label_rect.GetBottom() - 13, 13, 13, 1.0); - dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() - 10, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[1].GetBitmapFor(wnd), label_rect.GetRight() - 10, label_rect.GetBottom() - 10, true); } else - dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() - 10, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[0].GetBitmapFor(wnd), label_rect.GetRight() - 10, label_rect.GetBottom() - 10, true); } } @@ -983,7 +983,7 @@ void wxRibbonAUIArtProvider::DrawGalleryBackground( } void wxRibbonAUIArtProvider::DrawGalleryButton(wxDC& dc, wxRect rect, - wxRibbonGalleryButtonState state, wxBitmap* bitmaps) + wxRibbonGalleryButtonState state, wxBitmapBundle* bundles, wxWindow* wnd) { int extra_height = 0; int extra_width = 0; @@ -1007,28 +1007,28 @@ void wxRibbonAUIArtProvider::DrawGalleryButton(wxDC& dc, wxRect rect, dc.GradientFillLinear(reduced_rect, m_gallery_button_background_colour, m_gallery_button_background_gradient_colour, wxSOUTH); - btn_bitmap = bitmaps[0]; + btn_bitmap = bundles[0].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_HOVERED: dc.SetPen(m_gallery_item_border_pen); dc.SetBrush(m_gallery_button_hover_background_brush); dc.DrawRectangle(rect.x, rect.y, rect.width + extra_width, rect.height + extra_height); - btn_bitmap = bitmaps[1]; + btn_bitmap = bundles[1].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_ACTIVE: dc.SetPen(m_gallery_item_border_pen); dc.SetBrush(m_gallery_button_active_background_brush); dc.DrawRectangle(rect.x, rect.y, rect.width + extra_width, rect.height + extra_height); - btn_bitmap = bitmaps[2]; + btn_bitmap = bundles[2].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_DISABLED: dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(m_gallery_button_disabled_background_brush); dc.DrawRectangle(reduced_rect.x, reduced_rect.y, reduced_rect.width, reduced_rect.height); - btn_bitmap = bitmaps[3]; + btn_bitmap = bundles[3].GetBitmapFor(wnd); break; } @@ -1177,7 +1177,7 @@ void wxRibbonAUIArtProvider::DrawToolGroupBackground( void wxRibbonAUIArtProvider::DrawTool( wxDC& dc, - wxWindow* WXUNUSED(wnd), + wxWindow* wnd, const wxRect& rect, const wxBitmap& bitmap, wxRibbonButtonKind kind, @@ -1254,7 +1254,7 @@ void wxRibbonAUIArtProvider::DrawTool( dc.DrawLine(rect.x + avail_width + 1, rect.y, rect.x + avail_width + 1, rect.y + rect.height); } - dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2, + dc.DrawBitmap(m_toolbar_drop_bundle.GetBitmapFor(wnd), bg_rect.x + avail_width + 2, bg_rect.y + (bg_rect.height / 2) - 2, true); } if ( bitmap.IsOk() ) diff --git a/src/ribbon/art_msw.cpp b/src/ribbon/art_msw.cpp index 00c4a4e91d..4188d1e2ac 100644 --- a/src/ribbon/art_msw.cpp +++ b/src/ribbon/art_msw.cpp @@ -515,19 +515,19 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const int i; for(i = 0; i < 4; ++i) { - copy->m_gallery_up_bitmap[i] = m_gallery_up_bitmap[i]; - copy->m_gallery_down_bitmap[i] = m_gallery_down_bitmap[i]; - copy->m_gallery_extension_bitmap[i] = m_gallery_extension_bitmap[i]; + copy->m_gallery_up_bundle[i] = m_gallery_up_bundle[i]; + copy->m_gallery_down_bundle[i] = m_gallery_down_bundle[i]; + copy->m_gallery_extension_bundle[i] = m_gallery_extension_bundle[i]; } for(i = 0; i < 2; ++i) { - copy->m_panel_extension_bitmap[i] = m_panel_extension_bitmap[i]; - copy->m_ribbon_toggle_up_bitmap[i] = m_ribbon_toggle_up_bitmap[i]; - copy->m_ribbon_toggle_down_bitmap[i] = m_ribbon_toggle_down_bitmap[i]; - copy->m_ribbon_toggle_pin_bitmap[i] = m_ribbon_toggle_pin_bitmap[i]; - copy->m_ribbon_bar_help_button_bitmap[i] = m_ribbon_bar_help_button_bitmap[i]; + copy->m_panel_extension_bundle[i] = m_panel_extension_bundle[i]; + copy->m_ribbon_toggle_up_bundle[i] = m_ribbon_toggle_up_bundle[i]; + copy->m_ribbon_toggle_down_bundle[i] = m_ribbon_toggle_down_bundle[i]; + copy->m_ribbon_toggle_pin_bundle[i] = m_ribbon_toggle_pin_bundle[i]; + copy->m_ribbon_bar_help_button_bundle[i] = m_ribbon_bar_help_button_bundle[i]; } - copy->m_toolbar_drop_bitmap = m_toolbar_drop_bitmap; + copy->m_toolbar_drop_bundle = m_toolbar_drop_bundle; copy->m_primary_scheme_colour = m_primary_scheme_colour; copy->m_secondary_scheme_colour = m_secondary_scheme_colour; @@ -1051,15 +1051,15 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) m_gallery_button_face_colour = colour; if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL) { - m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_left_xpm, colour); - m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_right_xpm, colour); + m_gallery_up_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_left_xpm, colour)); + m_gallery_down_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_right_xpm, colour)); } else { - m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_up_xpm, colour); - m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_down_xpm, colour); + m_gallery_up_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_up_xpm, colour)); + m_gallery_down_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_down_xpm, colour)); } - m_gallery_extension_bitmap[0] = wxRibbonLoadPixmap(gallery_extension_xpm, colour); + m_gallery_extension_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_extension_xpm, colour)); break; case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_COLOUR: m_gallery_button_hover_background_colour = colour; @@ -1074,15 +1074,15 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) m_gallery_button_hover_face_colour = colour; if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL) { - m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_left_xpm, colour); - m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_right_xpm, colour); + m_gallery_up_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_left_xpm, colour)); + m_gallery_down_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_right_xpm, colour)); } else { - m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_up_xpm, colour); - m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_down_xpm, colour); + m_gallery_up_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_up_xpm, colour)); + m_gallery_down_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_down_xpm, colour)); } - m_gallery_extension_bitmap[1] = wxRibbonLoadPixmap(gallery_extension_xpm, colour); + m_gallery_extension_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_extension_xpm, colour)); break; case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_COLOUR: m_gallery_button_active_background_colour = colour; @@ -1097,15 +1097,15 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) m_gallery_button_active_face_colour = colour; if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL) { - m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_left_xpm, colour); - m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_right_xpm, colour); + m_gallery_up_bundle[2] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_left_xpm, colour)); + m_gallery_down_bundle[2] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_right_xpm, colour)); } else { - m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_up_xpm, colour); - m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_down_xpm, colour); + m_gallery_up_bundle[2] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_up_xpm, colour)); + m_gallery_down_bundle[2] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_down_xpm, colour)); } - m_gallery_extension_bitmap[2] = wxRibbonLoadPixmap(gallery_extension_xpm, colour); + m_gallery_extension_bundle[2] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_extension_xpm, colour)); break; case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_COLOUR: m_gallery_button_disabled_background_colour = colour; @@ -1120,15 +1120,15 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) m_gallery_button_disabled_face_colour = colour; if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL) { - m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_left_xpm, colour); - m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_right_xpm, colour); + m_gallery_up_bundle[3] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_left_xpm, colour)); + m_gallery_down_bundle[3] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_right_xpm, colour)); } else { - m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_up_xpm, colour); - m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_down_xpm, colour); + m_gallery_up_bundle[3] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_up_xpm, colour)); + m_gallery_down_bundle[3] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_down_xpm, colour)); } - m_gallery_extension_bitmap[3] = wxRibbonLoadPixmap(gallery_extension_xpm, colour); + m_gallery_extension_bundle[3] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_extension_xpm, colour)); break; case wxRIBBON_ART_GALLERY_ITEM_BORDER_COLOUR: m_gallery_item_border_pen.SetColour(colour); @@ -1228,11 +1228,11 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) break; case wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR: m_panel_button_face_colour = colour; - m_panel_extension_bitmap[0] = wxRibbonLoadPixmap(panel_extension_xpm, colour); + m_panel_extension_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_extension_xpm, colour)); break; case wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR: m_panel_button_hover_face_colour = colour; - m_panel_extension_bitmap[1] = wxRibbonLoadPixmap(panel_extension_xpm, colour); + m_panel_extension_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_extension_xpm, colour)); break; case wxRIBBON_ART_PAGE_BORDER_COLOUR: m_page_border_pen.SetColour(colour); @@ -1267,21 +1267,21 @@ void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour) break; case wxRIBBON_ART_TOOLBAR_FACE_COLOUR: m_tool_face_colour = colour; - m_toolbar_drop_bitmap = wxRibbonLoadPixmap(gallery_down_xpm, colour); + m_toolbar_drop_bundle = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(gallery_down_xpm, colour)); break; case wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR: m_page_toggle_face_colour = colour; - m_ribbon_toggle_down_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour); - m_ribbon_toggle_up_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour); - m_ribbon_toggle_pin_bitmap[0] = wxRibbonLoadPixmap(ribbon_toggle_pin_xpm, colour); - m_ribbon_bar_help_button_bitmap[0] = wxRibbonLoadPixmap(ribbon_help_button_xpm, colour); + m_ribbon_toggle_down_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_toggle_down_xpm, colour)); + m_ribbon_toggle_up_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_toggle_up_xpm, colour)); + m_ribbon_toggle_pin_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(ribbon_toggle_pin_xpm, colour)); + m_ribbon_bar_help_button_bundle[0] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(ribbon_help_button_xpm, colour)); break; case wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR: m_page_toggle_hover_face_colour = colour; - m_ribbon_toggle_down_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour); - m_ribbon_toggle_up_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour); - m_ribbon_toggle_pin_bitmap[1] = wxRibbonLoadPixmap(ribbon_toggle_pin_xpm, colour); - m_ribbon_bar_help_button_bitmap[1] = wxRibbonLoadPixmap(ribbon_help_button_xpm, colour); + m_ribbon_toggle_down_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_toggle_down_xpm, colour)); + m_ribbon_toggle_up_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(panel_toggle_up_xpm, colour)); + m_ribbon_toggle_pin_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(ribbon_toggle_pin_xpm, colour)); + m_ribbon_bar_help_button_bundle[1] = wxBitmapBundle::FromBitmap(wxRibbonLoadPixmap(ribbon_help_button_xpm, colour)); break; case wxRIBBON_ART_BUTTON_BAR_LABEL_HIGHLIGHT_TOP_COLOUR: m_tab_highlight_top_colour = colour; @@ -1986,10 +1986,10 @@ void wxRibbonMSWArtProvider::DrawPanelBackground( dc.SetPen(m_panel_hover_button_border_pen); dc.SetBrush(m_panel_hover_button_background_brush); dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0); - dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[1].GetBitmapFor(wnd), label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); } else - dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[0].GetBitmapFor(wnd), label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); } } @@ -2097,17 +2097,18 @@ void wxRibbonMSWArtProvider::DrawGalleryBackgroundCommon(wxDC& dc, } DrawGalleryButton(dc, up_btn, wnd->GetUpButtonState(), - m_gallery_up_bitmap); + m_gallery_up_bundle, wnd); DrawGalleryButton(dc, down_btn, wnd->GetDownButtonState(), - m_gallery_down_bitmap); + m_gallery_down_bundle, wnd); DrawGalleryButton(dc, ext_btn, wnd->GetExtensionButtonState(), - m_gallery_extension_bitmap); + m_gallery_extension_bundle, wnd); } void wxRibbonMSWArtProvider::DrawGalleryButton(wxDC& dc, wxRect rect, wxRibbonGalleryButtonState state, - wxBitmap* bitmaps) + wxBitmapBundle* bundles, + wxWindow* wnd) { wxBitmap btn_bitmap; wxBrush btn_top_brush; @@ -2119,25 +2120,25 @@ void wxRibbonMSWArtProvider::DrawGalleryButton(wxDC& dc, btn_top_brush = m_gallery_button_background_top_brush; btn_colour = m_gallery_button_background_colour; btn_grad_colour = m_gallery_button_background_gradient_colour; - btn_bitmap = bitmaps[0]; + btn_bitmap = bundles[0].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_HOVERED: btn_top_brush = m_gallery_button_hover_background_top_brush; btn_colour = m_gallery_button_hover_background_colour; btn_grad_colour = m_gallery_button_hover_background_gradient_colour; - btn_bitmap = bitmaps[1]; + btn_bitmap = bundles[1].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_ACTIVE: btn_top_brush = m_gallery_button_active_background_top_brush; btn_colour = m_gallery_button_active_background_colour; btn_grad_colour = m_gallery_button_active_background_gradient_colour; - btn_bitmap = bitmaps[2]; + btn_bitmap = bundles[2].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_DISABLED: btn_top_brush = m_gallery_button_disabled_background_top_brush; btn_colour = m_gallery_button_disabled_background_colour; btn_grad_colour = m_gallery_button_disabled_background_gradient_colour; - btn_bitmap = bitmaps[3]; + btn_bitmap = bundles[3].GetBitmapFor(wnd); break; } @@ -2735,7 +2736,7 @@ void wxRibbonMSWArtProvider::DrawToolGroupBackground( void wxRibbonMSWArtProvider::DrawTool( wxDC& dc, - wxWindow* WXUNUSED(wnd), + wxWindow* wnd, const wxRect& rect, const wxBitmap& bitmap, wxRibbonButtonKind kind, @@ -2825,7 +2826,7 @@ void wxRibbonMSWArtProvider::DrawTool( dc.DrawLine(rect.x + avail_width + 1, rect.y, rect.x + avail_width + 1, rect.y + rect.height); } - dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2, + dc.DrawBitmap(m_toolbar_drop_bundle.GetBitmapFor(wnd), bg_rect.x + avail_width + 2, bg_rect.y + (bg_rect.height / 2) - 2, true); } dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetLogicalWidth()) / 2, @@ -2854,13 +2855,13 @@ wxRibbonMSWArtProvider::DrawToggleButton(wxDC& dc, switch(mode) { case wxRIBBON_BAR_PINNED: - dc.DrawBitmap(m_ribbon_toggle_up_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true); + dc.DrawBitmap(m_ribbon_toggle_up_bundle[bindex].GetBitmapFor(wnd), rect.GetX()+7, rect.GetY()+6, true); break; case wxRIBBON_BAR_MINIMIZED: - dc.DrawBitmap(m_ribbon_toggle_down_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true); + dc.DrawBitmap(m_ribbon_toggle_down_bundle[bindex].GetBitmapFor(wnd), rect.GetX()+7, rect.GetY()+6, true); break; case wxRIBBON_BAR_EXPANDED: - dc.DrawBitmap(m_ribbon_toggle_pin_bitmap[bindex], rect.GetX ()+4, rect.GetY ()+5, true); + dc.DrawBitmap(m_ribbon_toggle_pin_bundle[bindex].GetBitmapFor(wnd), rect.GetX ()+4, rect.GetY ()+5, true); break; } } @@ -2879,11 +2880,11 @@ void wxRibbonMSWArtProvider::DrawHelpButton(wxDC& dc, dc.SetPen(m_ribbon_toggle_pen); dc.SetBrush(m_ribbon_toggle_brush); dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0); - dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[1], rect.GetX ()+4, rect.GetY()+5, true); + dc.DrawBitmap(m_ribbon_bar_help_button_bundle[1].GetBitmapFor(wnd), rect.GetX ()+4, rect.GetY()+5, true); } else { - dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[0], rect.GetX ()+4, rect.GetY()+5, true); + dc.DrawBitmap(m_ribbon_bar_help_button_bundle[0].GetBitmapFor(wnd), rect.GetX ()+4, rect.GetY()+5, true); } } diff --git a/src/ribbon/art_msw_flat.cpp b/src/ribbon/art_msw_flat.cpp index ee19b4a701..1683808903 100644 --- a/src/ribbon/art_msw_flat.cpp +++ b/src/ribbon/art_msw_flat.cpp @@ -481,7 +481,8 @@ void wxRibbonMSWFlatArtProvider::DrawScrollButton( void wxRibbonMSWFlatArtProvider::DrawGalleryButton(wxDC& dc, wxRect rect, wxRibbonGalleryButtonState state, - wxBitmap* bitmaps) + wxBitmapBundle* bundles, + wxWindow* wnd) { wxBitmap btn_bitmap; wxColour btn_colour; @@ -489,19 +490,19 @@ void wxRibbonMSWFlatArtProvider::DrawGalleryButton(wxDC& dc, { case wxRIBBON_GALLERY_BUTTON_NORMAL: btn_colour = m_gallery_button_background_colour; - btn_bitmap = bitmaps[0]; + btn_bitmap = bundles[0].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_HOVERED: btn_colour = m_gallery_button_hover_background_colour; - btn_bitmap = bitmaps[1]; + btn_bitmap = bundles[1].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_ACTIVE: btn_colour = m_gallery_button_active_background_colour; - btn_bitmap = bitmaps[2]; + btn_bitmap = bundles[2].GetBitmapFor(wnd); break; case wxRIBBON_GALLERY_BUTTON_DISABLED: btn_colour = m_gallery_button_disabled_background_colour; - btn_bitmap = bitmaps[3]; + btn_bitmap = bundles[3].GetBitmapFor(wnd); break; } @@ -961,10 +962,10 @@ void wxRibbonMSWFlatArtProvider::DrawPanelBackground( dc.SetPen(m_panel_hover_button_border_pen); dc.SetBrush(m_panel_hover_button_background_brush); dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0); - dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[1].GetBitmapFor(wnd), label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); } else - dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); + dc.DrawBitmap(m_panel_extension_bundle[0].GetBitmapFor(wnd), label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true); } } @@ -1058,13 +1059,13 @@ wxRibbonMSWFlatArtProvider::DrawToggleButton(wxDC& dc, switch ( mode ) { case wxRIBBON_BAR_PINNED: - dc.DrawBitmap(m_ribbon_toggle_up_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true); + dc.DrawBitmap(m_ribbon_toggle_up_bundle[bindex].GetBitmapFor(wnd), rect.GetX()+7, rect.GetY()+6, true); break; case wxRIBBON_BAR_MINIMIZED: - dc.DrawBitmap(m_ribbon_toggle_down_bitmap[bindex], rect.GetX()+7, rect.GetY()+6, true); + dc.DrawBitmap(m_ribbon_toggle_down_bundle[bindex].GetBitmapFor(wnd), rect.GetX()+7, rect.GetY()+6, true); break; case wxRIBBON_BAR_EXPANDED: - dc.DrawBitmap(m_ribbon_toggle_pin_bitmap[bindex], rect.GetX()+4, rect.GetY()+5, true); + dc.DrawBitmap(m_ribbon_toggle_pin_bundle[bindex].GetBitmapFor(wnd), rect.GetX()+4, rect.GetY()+5, true); break; } } @@ -1083,17 +1084,17 @@ void wxRibbonMSWFlatArtProvider::DrawHelpButton(wxDC& dc, dc.SetPen(m_ribbon_toggle_pen); dc.SetBrush(m_ribbon_toggle_brush); dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 20, 20, 1.0); - dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[1], rect.GetX()+4, rect.GetY()+5, true); + dc.DrawBitmap(m_ribbon_bar_help_button_bundle[1].GetBitmapFor(wnd), rect.GetX()+4, rect.GetY()+5, true); } else { - dc.DrawBitmap(m_ribbon_bar_help_button_bitmap[0], rect.GetX()+4, rect.GetY()+5, true); + dc.DrawBitmap(m_ribbon_bar_help_button_bundle[0].GetBitmapFor(wnd), rect.GetX()+4, rect.GetY()+5, true); } } void wxRibbonMSWFlatArtProvider::DrawTool( wxDC& dc, - wxWindow* WXUNUSED(wnd), + wxWindow* wnd, const wxRect& rect, const wxBitmap& bitmap, wxRibbonButtonKind kind, @@ -1168,7 +1169,7 @@ void wxRibbonMSWFlatArtProvider::DrawTool( dc.DrawLine(rect.x + avail_width + 1, rect.y, rect.x + avail_width + 1, rect.y + rect.height); } - dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2, + dc.DrawBitmap(m_toolbar_drop_bundle.GetBitmapFor(wnd), bg_rect.x + avail_width + 2, bg_rect.y + (bg_rect.height / 2) - 2, true); } dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetLogicalWidth()) / 2, diff --git a/src/ribbon/bar.cpp b/src/ribbon/bar.cpp index eff400996a..0d61e61b01 100644 --- a/src/ribbon/bar.cpp +++ b/src/ribbon/bar.cpp @@ -54,6 +54,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonBar, wxRibbonControl) EVT_LEFT_DCLICK(wxRibbonBar::OnMouseDoubleClick) EVT_SIZE(wxRibbonBar::OnSize) EVT_KILL_FOCUS(wxRibbonBar::OnKillFocus) + EVT_DPI_CHANGED(wxRibbonBar::OnDPIChanged) wxEND_EVENT_TABLE() void wxRibbonBar::AddPage(wxRibbonPage *page) @@ -964,6 +965,28 @@ void wxRibbonBar::OnSize(wxSizeEvent& evt) evt.Skip(); } +void wxRibbonBar::OnDPIChanged(wxDPIChangedEvent& event) +{ + // Recalculate tab sizes for new DPI + RecalculateTabSizes(); + + // Realize all pages to update their layouts + size_t page_count = m_pages.GetCount(); + for(size_t i = 0; i < page_count; ++i) + { + m_pages.Item(i).page->Realize(); + } + + // Reposition current page + if(m_current_page != wxNOT_FOUND) + { + RepositionPage(m_pages.Item(m_current_page).page); + } + + Refresh(); + event.Skip(); +} + void wxRibbonBar::RepositionPage(wxRibbonPage *page) { int w, h; diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 81ce514fda..c7a70f71eb 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -41,6 +41,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonButtonBar, wxRibbonControl) EVT_LEFT_DOWN(wxRibbonButtonBar::OnMouseDown) EVT_LEFT_DCLICK(wxRibbonButtonBar::OnMouseDown) EVT_LEFT_UP(wxRibbonButtonBar::OnMouseUp) + EVT_DPI_CHANGED(wxRibbonButtonBar::OnDPIChanged) wxEND_EVENT_TABLE() class wxRibbonButtonBarButtonSizeInfo @@ -62,18 +63,6 @@ public: namespace { - -wxBitmap MakeResizedBitmap(const wxBitmap& original, wxSize size) -{ - double scale = original.GetScaleFactor(); - if (scale > 1.0) - scale = 2.0; - - wxImage img(original.ConvertToImage()); - img.Rescale(scale * size, wxIMAGE_QUALITY_HIGH); - return wxBitmap(img, -1, scale); -} - wxBitmap MakeDisabledBitmap(const wxBitmap& original) { wxImage img(original.ConvertToImage()); @@ -87,85 +76,19 @@ class wxRibbonButtonBarButtonBase public: wxRibbonButtonBarButtonBase() { - barButtonImageListPos = - barButtonSmallImageListPos = -1; + imageIndexLarge = -1; + imageIndexSmall = -1; + imageIndexLargeDisabled = -1; + imageIndexSmallDisabled = -1; } - void SetBitmaps(wxRibbonBar* ribbon, - wxSize bitmap_size_large, - wxSize bitmap_size_small, - wxBitmap bitmap_large, - wxBitmap bitmap_large_disabled, - wxBitmap bitmap_small, - wxBitmap bitmap_small_disabled) + // Store bundle indices in parent's bundle vectors + void SetBundleIndices(int largeIdx, int smallIdx, int largeDisabledIdx, int smallDisabledIdx) { - wxCHECK_RET(ribbon, "Ribbon bar not set; can't register button images yet!"); - - if(!bitmap_large.IsOk()) - { - bitmap_large = MakeResizedBitmap(bitmap_small, bitmap_size_large); - } - else if(bitmap_large.GetLogicalSize() != bitmap_size_large) - { - bitmap_large = MakeResizedBitmap(bitmap_large, bitmap_size_large); - } - - if(!bitmap_small.IsOk()) - { - bitmap_small = MakeResizedBitmap(bitmap_large, bitmap_size_small); - } - else if(bitmap_small.GetLogicalSize() != bitmap_size_small) - { - bitmap_small = MakeResizedBitmap(bitmap_small, bitmap_size_small); - } - - if(!bitmap_large_disabled.IsOk()) - { - bitmap_large_disabled = MakeDisabledBitmap(bitmap_large); - } - - if(!bitmap_small_disabled.IsOk()) - { - bitmap_small_disabled = MakeDisabledBitmap(bitmap_small); - } - - if ( bitmap_large.IsOk() ) - { - wxImageList* const - buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); - - barButtonImageListPos = buttonImageList->Add(bitmap_large); - buttonImageList->Add(bitmap_large_disabled); - } - - wxImageList* const - buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); - - barButtonSmallImageListPos = buttonSmallImageList->Add(bitmap_small); - buttonSmallImageList->Add(bitmap_small_disabled); - } - - void GetBitmaps(wxRibbonBar* ribbon, - wxSize bitmap_size_large, - wxSize bitmap_size_small, - wxBitmap& bitmap, - wxBitmap& bitmap_small) const - { - wxImageList* buttonImageList = ribbon->GetButtonImageList(bitmap_size_large); - wxImageList* buttonSmallImageList = ribbon->GetButtonImageList(bitmap_size_small); - - int pos = barButtonImageListPos; - int pos_small = barButtonSmallImageListPos; - - if (state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) - { - // Disabled buttons are stored after the normal ones. - pos++; - pos_small++; - } - - bitmap = buttonImageList->GetBitmap(pos); - bitmap_small = buttonSmallImageList->GetBitmap(pos_small); + imageIndexLarge = largeIdx; + imageIndexSmall = smallIdx; + imageIndexLargeDisabled = largeDisabledIdx; + imageIndexSmallDisabled = smallDisabledIdx; } wxRibbonButtonBarButtonInstance NewInstance() @@ -226,12 +149,11 @@ public: wxString help_string; wxCoord text_min_width[3]; - // Index of the bitmap in the wxRibbonBar normal image list. Notice that - // the disabled bitmap is in the next position, so this one is always even. - int barButtonImageListPos; - - // Same thing for the small bitmap index in the small image list. - int barButtonSmallImageListPos; + // Indices into parent wxRibbonButtonBar's wxWithImages collections + int imageIndexLarge; + int imageIndexSmall; + int imageIndexLargeDisabled; + int imageIndexSmallDisabled; wxRibbonButtonBarButtonSizeInfo sizes[3]; wxRibbonButtonBarButtonState min_size_class; @@ -341,18 +263,18 @@ bool wxRibbonButtonBar::Create(wxWindow* parent, wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind) { - return AddButton(button_id, label, bitmap, wxNullBitmap, wxNullBitmap, - wxNullBitmap, kind, help_string); + return AddButton(button_id, label, bitmap, wxBitmapBundle(), wxBitmapBundle(), + wxBitmapBundle(), kind, help_string); } wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddDropdownButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return AddButton(button_id, label, bitmap, help_string, @@ -362,7 +284,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddDropdownButton( wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddToggleButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return AddButton(button_id, label, bitmap, help_string, @@ -372,7 +294,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddToggleButton( wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddHybridButton( int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return AddButton(button_id, label, bitmap, help_string, @@ -382,10 +304,10 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddHybridButton( wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( int button_id, const wxString& label, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small, - const wxBitmap& bitmap_disabled, - const wxBitmap& bitmap_small_disabled, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small, + const wxBitmapBundle& bitmap_disabled, + const wxBitmapBundle& bitmap_small_disabled, wxRibbonButtonKind kind, const wxString& help_string) { @@ -397,19 +319,22 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small, - const wxBitmap& bitmap_disabled, - const wxBitmap& bitmap_small_disabled, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small, + const wxBitmapBundle& bitmap_disabled, + const wxBitmapBundle& bitmap_small_disabled, wxRibbonButtonKind kind, const wxString& help_string) { wxASSERT(bitmap.IsOk() || bitmap_small.IsOk()); + + // Determine base bitmap sizes on first button (at 100% scale) + // These are scaled by DPI when used for layout and drawing if(m_buttons.IsEmpty()) { if(bitmap.IsOk()) { - m_bitmap_size_large = bitmap.GetLogicalSize(); + m_bitmap_size_large = bitmap.GetDefaultSize(); if(!bitmap_small.IsOk()) { m_bitmap_size_small = m_bitmap_size_large; @@ -418,7 +343,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( } if(bitmap_small.IsOk()) { - m_bitmap_size_small = bitmap_small.GetLogicalSize(); + m_bitmap_size_small = bitmap_small.GetDefaultSize(); if(!bitmap.IsOk()) { m_bitmap_size_large = m_bitmap_size_small; @@ -427,11 +352,69 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( } } + // Add bundles to our vectors and remember indices + int idxLarge = -1; + int idxSmall = -1; + int idxLargeDisabled = -1; + int idxSmallDisabled = -1; + + if(bitmap.IsOk()) + { + idxLarge = m_bundlesLarge.size(); + m_bundlesLarge.push_back(bitmap); + + idxLargeDisabled = m_bundlesLargeDisabled.size(); + if(bitmap_disabled.IsOk()) + { + m_bundlesLargeDisabled.push_back(bitmap_disabled); + } + else + { + // Generate disabled bitmap from normal one + wxBitmap bmp = bitmap.GetBitmap(m_bitmap_size_large); + m_bundlesLargeDisabled.push_back(wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp))); + } + } + + if(bitmap_small.IsOk()) + { + idxSmall = m_bundlesSmall.size(); + m_bundlesSmall.push_back(bitmap_small); + + idxSmallDisabled = m_bundlesSmallDisabled.size(); + if(bitmap_small_disabled.IsOk()) + { + m_bundlesSmallDisabled.push_back(bitmap_small_disabled); + } + else + { + // Generate disabled bitmap from normal one + wxBitmap bmp = bitmap_small.GetBitmap(m_bitmap_size_small); + m_bundlesSmallDisabled.push_back(wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp))); + } + } + else if(bitmap.IsOk()) + { + // Use large bitmap scaled down for small + idxSmall = m_bundlesSmall.size(); + m_bundlesSmall.push_back(bitmap); + + idxSmallDisabled = m_bundlesSmallDisabled.size(); + if(bitmap_disabled.IsOk()) + { + m_bundlesSmallDisabled.push_back(bitmap_disabled); + } + else + { + wxBitmap bmp = bitmap.GetBitmap(m_bitmap_size_small); + m_bundlesSmallDisabled.push_back(wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp))); + } + } + wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase; base->id = button_id; base->label = label; - base->SetBitmaps(m_ribbonBar, m_bitmap_size_large, m_bitmap_size_small, - bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); + base->SetBundleIndices(idxLarge, idxSmall, idxLargeDisabled, idxSmallDisabled); base->kind = kind; base->help_string = help_string; base->state = 0; @@ -491,19 +474,19 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind) { - return InsertButton(pos, button_id, label, bitmap, wxNullBitmap, - wxNullBitmap, wxNullBitmap, kind, help_string); + return InsertButton(pos, button_id, label, bitmap, wxBitmapBundle(), + wxBitmapBundle(), wxBitmapBundle(), kind, help_string); } wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertDropdownButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return InsertButton(pos, button_id, label, bitmap, help_string, @@ -514,7 +497,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertToggleButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return InsertButton(pos, button_id, label, bitmap, help_string, @@ -525,7 +508,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertHybridButton( size_t pos, int button_id, const wxString& label, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { return InsertButton(pos, button_id, label, bitmap, help_string, @@ -538,9 +521,14 @@ void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, wxRibbonButtonBarButtonSizeInfo& info = button->sizes[size]; if(m_art) { + // Scale base bitmap sizes by current DPI for layout calculation + const double scale = GetDPIScaleFactor(); + wxSize scaledLarge = m_bitmap_size_large * scale; + wxSize scaledSmall = m_bitmap_size_small * scale; + info.is_supported = m_art->GetButtonBarButtonSize(dc, this, button->kind, size, button->label, button->text_min_width[size], - m_bitmap_size_large, m_bitmap_size_small, &info.size, + scaledLarge, scaledSmall, &info.size, &info.normal_region, &info.dropdown_region); } else @@ -662,16 +650,48 @@ void wxRibbonButtonBar::ToggleButton(int button_id, bool checked) void wxRibbonButtonBar::SetButtonIcon( int button_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_small, - const wxBitmap& bitmap_disabled, - const wxBitmap& bitmap_small_disabled) + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_small, + const wxBitmapBundle& bitmap_disabled, + const wxBitmapBundle& bitmap_small_disabled) { wxRibbonButtonBarButtonBase* base = GetItemById(button_id); if(base == nullptr) return; - base->SetBitmaps(m_ribbonBar, m_bitmap_size_large, m_bitmap_size_small, - bitmap, bitmap_disabled, bitmap_small, bitmap_small_disabled); + + // Update the bundles in our vectors + if(bitmap.IsOk() && base->imageIndexLarge >= 0) + { + m_bundlesLarge[base->imageIndexLarge] = bitmap; + + if(bitmap_disabled.IsOk()) + { + m_bundlesLargeDisabled[base->imageIndexLargeDisabled] = bitmap_disabled; + } + else + { + wxBitmap bmp = bitmap.GetBitmap(m_bitmap_size_large); + m_bundlesLargeDisabled[base->imageIndexLargeDisabled] = + wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp)); + } + } + + if(bitmap_small.IsOk() && base->imageIndexSmall >= 0) + { + m_bundlesSmall[base->imageIndexSmall] = bitmap_small; + + if(bitmap_small_disabled.IsOk()) + { + m_bundlesSmallDisabled[base->imageIndexSmallDisabled] = bitmap_small_disabled; + } + else + { + wxBitmap bmp = bitmap_small.GetBitmap(m_bitmap_size_small); + m_bundlesSmallDisabled[base->imageIndexSmallDisabled] = + wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp)); + } + } + Refresh(); } @@ -924,20 +944,62 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout); + // Calculate DPI-scaled bitmap sizes (must match layout calculation) + const double scale = GetDPIScaleFactor(); + const wxSize scaledLarge = m_bitmap_size_large * scale; + const wxSize scaledSmall = m_bitmap_size_small * scale; + for ( auto& button : layout->buttons ) { wxRibbonButtonBarButtonBase* base = button.base; wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); + // Get bitmaps at the DPI-scaled sizes used for layout + // Using explicit sizes ensures bundles are scaled correctly even if + // the small bundle contains a large source image wxBitmap bitmap, bitmap_small; - base->GetBitmaps(m_ribbonBar, - m_bitmap_size_large, m_bitmap_size_small, bitmap, - bitmap_small); + + bool disabled = (base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) != 0; + + if(base->imageIndexLarge >= 0) + { + int idx = disabled ? base->imageIndexLargeDisabled : base->imageIndexLarge; + if(idx >= 0 && idx < (int)m_bundlesLarge.size()) + { + const wxBitmapBundle& bundle = disabled ? + m_bundlesLargeDisabled[idx] : m_bundlesLarge[idx]; + bitmap = bundle.GetBitmap(scaledLarge); + } + } + + if(base->imageIndexSmall >= 0) + { + int idx = disabled ? base->imageIndexSmallDisabled : base->imageIndexSmall; + if(idx >= 0 && idx < (int)m_bundlesSmall.size()) + { + const wxBitmapBundle& bundle = disabled ? + m_bundlesSmallDisabled[idx] : m_bundlesSmall[idx]; + bitmap_small = bundle.GetBitmap(scaledSmall); + } + } + m_art->DrawButtonBarButton(dc, this, rect, base->kind, base->state | button.size, base->label, bitmap, bitmap_small); } } +wxBitmap wxRibbonButtonBar::GetButtonBitmap(int imageIndex, bool large) const +{ + if(imageIndex < 0) + return wxNullBitmap; + + const wxVector& bundles = large ? m_bundlesLarge : m_bundlesSmall; + if(imageIndex >= (int)bundles.size()) + return wxNullBitmap; + + return bundles[imageIndex].GetBitmapFor(this); +} + void wxRibbonButtonBar::OnSize(wxSizeEvent& evt) { wxSize new_size = evt.GetSize(); @@ -1526,4 +1588,23 @@ bool wxRibbonButtonBarEvent::PopupMenu(wxMenu* menu) return m_bar->PopupMenu(menu, pos); } +void wxRibbonButtonBar::OnDPIChanged(wxDPIChangedEvent& event) +{ + // Recalculate all button sizes with new DPI scale, then rebuild layouts + wxInfoDC temp_dc(this); + size_t btn_count = m_buttons.GetCount(); + for(size_t btn_i = 0; btn_i < btn_count; ++btn_i) + { + wxRibbonButtonBarButtonBase* base = m_buttons.Item(btn_i); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); + FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); + } + + m_layouts_valid = false; + Realize(); + Refresh(); + event.Skip(); +} + #endif // wxUSE_RIBBON diff --git a/src/ribbon/gallery.cpp b/src/ribbon/gallery.cpp index 4c5e3d2359..63a766cec3 100644 --- a/src/ribbon/gallery.cpp +++ b/src/ribbon/gallery.cpp @@ -38,8 +38,9 @@ public: wxRibbonGalleryItem() = default; void SetId(int id) {m_id = id;} - void SetBitmap(const wxBitmap& bitmap) {m_bitmap = bitmap;} - const wxBitmap& GetBitmap() const {return m_bitmap;} + void SetBitmap(const wxBitmapBundle& bitmap) {m_bitmap = bitmap;} + const wxBitmapBundle& GetBitmapBundle() const {return m_bitmap;} + wxBitmap GetBitmap(wxWindow* wnd) const {return m_bitmap.GetBitmapFor(wnd);} void SetIsVisible(bool visible) {m_is_visible = visible;} void SetPosition(int x, int y, const wxSize& size) { @@ -54,7 +55,7 @@ public: void *GetClientData() const {return m_client_data.GetClientData();} protected: - wxBitmap m_bitmap; + wxBitmapBundle m_bitmap; wxClientDataContainer m_client_data; wxRect m_position; int m_id = 0; @@ -71,6 +72,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonGallery, wxRibbonControl) EVT_MOTION(wxRibbonGallery::OnMouseMove) EVT_PAINT(wxRibbonGallery::OnPaint) EVT_SIZE(wxRibbonGallery::OnSize) + EVT_DPI_CHANGED(wxRibbonGallery::OnDPIChanged) wxEND_EVENT_TABLE() wxRibbonGallery::wxRibbonGallery() @@ -518,8 +520,10 @@ void wxRibbonGallery::OnPaint(wxPaintEvent& WXUNUSED(evt)) else offset_pos.SetLeft(offset_pos.GetLeft() - m_scroll_amount); m_art->DrawGalleryItemBackground(dc, this, offset_pos, item); - if (item->GetBitmap().IsOk() ) - dc.DrawBitmap(item->GetBitmap(), offset_pos.GetLeft() + padding_left, + // Resolve bitmap bundle for current DPI + wxBitmap bmp = item->GetBitmap(this); + if (bmp.IsOk()) + dc.DrawBitmap(bmp, offset_pos.GetLeft() + padding_left, offset_pos.GetTop() + padding_top); } } @@ -529,17 +533,23 @@ void wxRibbonGallery::OnSize(wxSizeEvent& WXUNUSED(evt)) Layout(); } -wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id) +void wxRibbonGallery::OnDPIChanged(wxDPIChangedEvent& event) +{ + Realize(); + event.Skip(); +} + +wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmapBundle& bitmap, int id) { wxASSERT(bitmap.IsOk()); if(m_items.IsEmpty()) { - m_bitmap_size = bitmap.GetLogicalSize(); + m_bitmap_size = bitmap.GetDefaultSize(); CalculateMinSize(); } else { - wxASSERT(bitmap.GetLogicalSize() == m_bitmap_size); + wxASSERT(bitmap.GetDefaultSize() == m_bitmap_size); } wxRibbonGalleryItem *item = new wxRibbonGalleryItem; @@ -549,7 +559,7 @@ wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id) return item; } -wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id, +wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmapBundle& bitmap, int id, void* clientData) { wxRibbonGalleryItem *item = Append(bitmap, id); @@ -557,7 +567,7 @@ wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id, return item; } -wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id, +wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmapBundle& bitmap, int id, wxClientData* clientData) { wxRibbonGalleryItem *item = Append(bitmap, id); diff --git a/src/ribbon/page.cpp b/src/ribbon/page.cpp index 21f6fd04cb..a3e4756d7e 100644 --- a/src/ribbon/page.cpp +++ b/src/ribbon/page.cpp @@ -148,6 +148,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonPage, wxRibbonControl) EVT_ERASE_BACKGROUND(wxRibbonPage::OnEraseBackground) EVT_PAINT(wxRibbonPage::OnPaint) EVT_SIZE(wxRibbonPage::OnSize) + EVT_DPI_CHANGED(wxRibbonPage::OnDPIChanged) wxEND_EVENT_TABLE() wxRibbonPage::wxRibbonPage() @@ -161,7 +162,7 @@ wxRibbonPage::wxRibbonPage() wxRibbonPage::wxRibbonPage(wxRibbonBar* parent, wxWindowID id, const wxString& label, - const wxBitmap& icon, + const wxBitmapBundle& icon, long WXUNUSED(style)) : wxRibbonControl(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) { @@ -178,7 +179,7 @@ wxRibbonPage::~wxRibbonPage() bool wxRibbonPage::Create(wxRibbonBar* parent, wxWindowID id, const wxString& label, - const wxBitmap& icon, + const wxBitmapBundle& icon, long WXUNUSED(style)) { if(!wxRibbonControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)) @@ -189,7 +190,7 @@ bool wxRibbonPage::Create(wxRibbonBar* parent, return true; } -void wxRibbonPage::CommonInit(const wxString& label, const wxBitmap& icon) +void wxRibbonPage::CommonInit(const wxString& label, const wxBitmapBundle& icon) { SetName(label); @@ -563,6 +564,12 @@ void wxRibbonPage::OnSize(wxSizeEvent& evt) evt.Skip(); } +void wxRibbonPage::OnDPIChanged(wxDPIChangedEvent& event) +{ + Realize(); + event.Skip(); +} + void wxRibbonPage::RemoveChild(wxWindowBase *child) { // Remove all references to the child from the collapse stack diff --git a/src/ribbon/panel.cpp b/src/ribbon/panel.cpp index 52fc66aeed..8fc2c1d899 100644 --- a/src/ribbon/panel.cpp +++ b/src/ribbon/panel.cpp @@ -42,6 +42,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonPanel, wxRibbonControl) EVT_LEFT_DOWN(wxRibbonPanel::OnMouseClick) EVT_PAINT(wxRibbonPanel::OnPaint) EVT_SIZE(wxRibbonPanel::OnSize) + EVT_DPI_CHANGED(wxRibbonPanel::OnDPIChanged) wxEND_EVENT_TABLE() wxRibbonPanel::wxRibbonPanel() : m_expanded_dummy(nullptr), m_expanded_panel(nullptr) @@ -51,7 +52,7 @@ wxRibbonPanel::wxRibbonPanel() : m_expanded_dummy(nullptr), m_expanded_panel(nul wxRibbonPanel::wxRibbonPanel(wxWindow* parent, wxWindowID id, const wxString& label, - const wxBitmap& minimised_icon, + const wxBitmapBundle& minimised_icon, const wxPoint& pos, const wxSize& size, long style) @@ -72,7 +73,7 @@ wxRibbonPanel::~wxRibbonPanel() bool wxRibbonPanel::Create(wxWindow* parent, wxWindowID id, const wxString& label, - const wxBitmap& icon, + const wxBitmapBundle& icon, const wxPoint& pos, const wxSize& size, long style) @@ -105,7 +106,7 @@ void wxRibbonPanel::SetArtProvider(wxRibbonArtProvider* art) m_expanded_panel->SetArtProvider(art); } -void wxRibbonPanel::CommonInit(const wxString& label, const wxBitmap& icon, long style) +void wxRibbonPanel::CommonInit(const wxString& label, const wxBitmapBundle& icon, long style) { SetName(label); SetLabel(label); @@ -252,6 +253,12 @@ void wxRibbonPanel::OnSize(wxSizeEvent& evt) evt.Skip(); } +void wxRibbonPanel::OnDPIChanged(wxDPIChangedEvent& event) +{ + Realize(); + event.Skip(); +} + void wxRibbonPanel::DoSetSize(int x, int y, int width, int height, int sizeFlags) { // At least on MSW, changing the size of a window will cause GetSize() to @@ -700,23 +707,13 @@ bool wxRibbonPanel::Realize() m_smallest_unminimised_size = m_art->GetPanelSize(temp_dc, this, minimum_children_size, nullptr); - wxSize bitmap_size; wxSize panel_min_size = GetMinNotMinimisedSize(); m_minimised_size = m_art->GetMinimisedPanelMinimumSize(temp_dc, this, - &bitmap_size, &m_preferred_expand_direction); - if(m_minimised_icon.IsOk() && m_minimised_icon.GetLogicalSize() != bitmap_size) + nullptr, &m_preferred_expand_direction); + if(m_minimised_icon.IsOk()) { - double scale = m_minimised_icon.GetScaleFactor(); - if (scale > 1.0) - scale = 2.0; - - wxImage img(m_minimised_icon.ConvertToImage()); - img.Rescale(scale * bitmap_size, wxIMAGE_QUALITY_HIGH); - m_minimised_icon_resized = wxBitmap(img, -1, scale); - } - else - { - m_minimised_icon_resized = m_minimised_icon; + m_minimised_icon_resized = m_minimised_icon.GetBitmap( + m_minimised_icon.GetPreferredBitmapSizeFor(this)); } if(m_minimised_size.x > panel_min_size.x && m_minimised_size.y > panel_min_size.y) diff --git a/src/ribbon/toolbar.cpp b/src/ribbon/toolbar.cpp index 00839f13e0..3d0b883749 100644 --- a/src/ribbon/toolbar.cpp +++ b/src/ribbon/toolbar.cpp @@ -30,8 +30,8 @@ class wxRibbonToolBarToolBase { public: wxString help_string; - wxBitmap bitmap; - wxBitmap bitmap_disabled; + wxBitmapBundle bitmap; + wxBitmapBundle bitmap_disabled; wxRect dropdown; wxPoint position; wxSize size; @@ -70,6 +70,7 @@ wxBEGIN_EVENT_TABLE(wxRibbonToolBar, wxRibbonControl) EVT_MOTION(wxRibbonToolBar::OnMouseMove) EVT_PAINT(wxRibbonToolBar::OnPaint) EVT_SIZE(wxRibbonToolBar::OnSize) + EVT_DPI_CHANGED(wxRibbonToolBar::OnDPIChanged) wxEND_EVENT_TABLE() wxRibbonToolBar::wxRibbonToolBar() @@ -133,44 +134,44 @@ wxRibbonToolBar::~wxRibbonToolBar() wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind) { - return AddTool(tool_id, bitmap, wxNullBitmap, help_string, kind, nullptr); + return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string, kind, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::AddDropdownTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return AddTool(tool_id, bitmap, wxNullBitmap, help_string, + return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_DROPDOWN, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::AddHybridTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return AddTool(tool_id, bitmap, wxNullBitmap, help_string, + return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_HYBRID, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::AddToggleTool( int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return AddTool(tool_id, bitmap, wxNullBitmap, help_string, + return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_TOGGLE, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool( int tool_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_disabled, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_disabled, const wxString& help_string, wxRibbonButtonKind kind, wxObject* client_data) @@ -192,49 +193,49 @@ wxRibbonToolBarToolBase* wxRibbonToolBar::AddSeparator() wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string, wxRibbonButtonKind kind) { - return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, kind, + return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string, kind, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::InsertDropdownTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_DROPDOWN, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::InsertHybridTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_HYBRID, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::InsertToggleTool( size_t pos, int tool_id, - const wxBitmap& bitmap, + const wxBitmapBundle& bitmap, const wxString& help_string) { - return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string, wxRIBBON_BUTTON_TOGGLE, nullptr); } wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool( size_t pos, int tool_id, - const wxBitmap& bitmap, - const wxBitmap& bitmap_disabled, + const wxBitmapBundle& bitmap, + const wxBitmapBundle& bitmap_disabled, const wxString& help_string, wxRibbonButtonKind kind, wxObject* client_data) @@ -247,11 +248,15 @@ wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool( tool->bitmap = bitmap; if(bitmap_disabled.IsOk()) { - wxASSERT(bitmap.GetLogicalSize() == bitmap_disabled.GetLogicalSize()); + wxASSERT(bitmap.GetDefaultSize() == bitmap_disabled.GetDefaultSize()); tool->bitmap_disabled = bitmap_disabled; } else - tool->bitmap_disabled = MakeDisabledBitmap(bitmap); + { + // Generate disabled bitmap from normal bitmap + wxBitmap bmp = bitmap.GetBitmap(bitmap.GetDefaultSize()); + tool->bitmap_disabled = wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp)); + } tool->help_string = help_string; tool->kind = kind; tool->client_data = client_data; @@ -580,7 +585,7 @@ void wxRibbonToolBar::SetToolClientData(int tool_id, wxObject* clientData) tool->client_data = clientData; } -void wxRibbonToolBar::SetToolDisabledBitmap(int tool_id, const wxBitmap &bitmap) +void wxRibbonToolBar::SetToolDisabledBitmap(int tool_id, const wxBitmapBundle &bitmap) { wxRibbonToolBarToolBase* tool = FindById(tool_id); wxCHECK_RET(tool != nullptr , "Invalid tool id"); @@ -594,7 +599,7 @@ void wxRibbonToolBar::SetToolHelpString(int tool_id, const wxString& helpString) tool->help_string = helpString; } -void wxRibbonToolBar::SetToolNormalBitmap(int tool_id, const wxBitmap &bitmap) +void wxRibbonToolBar::SetToolNormalBitmap(int tool_id, const wxBitmapBundle &bitmap) { wxRibbonToolBarToolBase* tool = FindById(tool_id); wxCHECK_RET(tool != nullptr , "Invalid tool id"); @@ -784,7 +789,7 @@ bool wxRibbonToolBar::Realize() { wxRibbonToolBarToolBase* tool = group->tools.Item(t); tool->size = m_art->GetToolSize(temp_dc, this, - tool->bitmap.GetLogicalSize(), tool->kind, t == 0, + tool->bitmap.GetPreferredLogicalSizeFor(this), tool->kind, t == 0, t == (tool_count - 1), &tool->dropdown); if(t == 0) tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST; @@ -975,6 +980,12 @@ void wxRibbonToolBar::OnSize(wxSizeEvent& evt) delete[] row_sizes; } +void wxRibbonToolBar::OnDPIChanged(wxDPIChangedEvent& event) +{ + Realize(); + event.Skip(); +} + // Finds the best width and height given the parents' width and height wxSize wxRibbonToolBar::GetBestSizeForParentSize(const wxSize& parentSize) const { @@ -1038,12 +1049,13 @@ void wxRibbonToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) { wxRibbonToolBarToolBase* tool = group->tools.Item(t); wxRect rect(group->position + tool->position, tool->size); + // Resolve bitmap bundle to actual bitmap for current DPI + wxBitmap bmp; if(tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) - m_art->DrawTool(dc, this, rect, tool->bitmap_disabled, - tool->kind, tool->state); + bmp = tool->bitmap_disabled.GetBitmapFor(this); else - m_art->DrawTool(dc, this, rect, tool->bitmap, tool->kind, - tool->state); + bmp = tool->bitmap.GetBitmapFor(this); + m_art->DrawTool(dc, this, rect, bmp, tool->kind, tool->state); } } }