[Git][wxwidgets/wxwidgets][master] 19 commits: Improve auto-scrolling in wxScrolled

0 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
3:50 PM (4 hours ago) 3:50 PM
to wx-commi...@googlegroups.com


Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets


Commits:
af88a678 by Bill Su at 2026-02-14T22:05:33+01:00
Improve auto-scrolling in wxScrolled

Support auto-scrolling both orientations simultaneously and make
auto-scroll region configurable.

Also allow changing auto-scroll dir without ending drag operation and
starting another one.

Closes #25978.

- - - - -
2fdad1d2 by Vadim Zeitlin at 2026-02-14T22:05:33+01:00
Document wxScrolled::Set{Inner,Outer}ScrollZone()

- - - - -
4ab8c812 by Bill Su at 2026-02-14T23:15:16-05:00
wxScrolled<>: simplify autoscroll configuration API

- - - - -
219b441f by ali kettab at 2026-02-19T23:37:03+01:00
wxQt: Add missing handling of wxBU_NOTEXT flag in wxButton

- - - - -
f7c099e3 by ali kettab at 2026-02-19T23:38:55+01:00
wxQt: Add missing handling of wxBU_EXACTFIT flag in wxBitmapButton

- - - - -
b61c5fad by ali kettab at 2026-02-19T23:55:07+01:00
wxQt: Add native wxArtProvider implementation

- - - - -
526b64f6 by ali kettab at 2026-02-20T00:09:30+01:00
wxQt: Return theme icon if there is no standard icon corresponding to wxArtID

- - - - -
465f0759 by ali kettab at 2026-02-20T00:13:08+01:00
wxQt: Add wxRenderer::DrawTitleBarBitmap() implementation

- - - - -
79f8446d by ali kettab at 2026-02-20T00:28:25+01:00
Update wxRenderer::DrawTitleBarBitmap() documentation

- - - - -
20437b49 by ali kettab at 2026-02-20T08:11:02+01:00
Fix BitmapBundle::ArtProvider test failing in wxQt after recent changes

- - - - -
7a5aeaa1 by Blake-Madden at 2026-02-20T22:00:55+01:00
Prevent wxTextEntryDialog from being resized in unexpected ways

Don't allow shrinking the dialog below its minimum size.

Also don't allow resizing single line entry dialogs vertically at all,
as the extra vertical space would be wasted anyhow and just makes the
dialog look bad.

Closes #25739.

Closes #26213.

- - - - -
aeeae2c0 by Maarten Bent at 2026-02-20T22:30:22+01:00
Update jpeg and zlib submodules

Fix a bug in the last jpeg submodule update, fixes #26197.

And update zlib from v1.3.1 to v1.3.2.

Closes #26199.

- - - - -
4503833f by Vadim Zeitlin at 2026-02-20T22:32:41+01:00
Don't set wxRichToolTip background colour in wxGTK

This makes the tooltip unreadable because using background colours with
alpha channel doesn't work correctly for wxPopupWindow (or, rather,
wxNonOwnedWindow) in wxGTK currently and wxSYS_COLOUR_INFOBK uses alpha
in the default GTK theme.

Closes #26185.

- - - - -
d8263f8d by ali kettab at 2026-02-20T23:47:56+01:00
Ignore BitmapBundle::ArtProvider test failing under xvfb with Qt < 5.12

- - - - -
673ee930 by Bill Su at 2026-02-21T00:52:13-05:00
wxScrolled<>: simplify autoscroll zone config API

- - - - -
583d44d6 by Carlo Bramini at 2026-02-21T19:59:13+01:00
Fix undefined reference to cairo_surface_get_device_scale()

This function needs to be loaded dynamically too.

Closes #26218.

- - - - -
29e6610a by Vadim Zeitlin at 2026-02-21T20:13:14+01:00
Merge branch 'qt-artprov' of github.com:AliKet/wxWidgets

Add wxArtProvider implementation for wxQt.

See #26210.

- - - - -
9720f1fd by Sean Maas at 2026-02-21T21:19:48+01:00
wxOSX: fix missing axes in wxJoystick

Add code to handle D-pads as X/Y axes, which is the behaviour observed
when using wxJoystick on Linux.

Closes #26216.

- - - - -
15285067 by Vadim Zeitlin at 2026-02-21T21:23:18+01:00
Merge branch 'autoscroll-zone' of github.com:wsu-cb/wxWidgets

Make wxScrolled<> autoscroll region configurable.

See #25978.

- - - - -


23 changed files:

- Makefile.in
- build/bakefiles/files.bkl
- build/cmake/files.cmake
- build/files
- include/wx/artprov.h
- include/wx/renderer.h
- include/wx/scrolwin.h
- interface/wx/renderer.h
- interface/wx/scrolwin.h
- samples/drawing/drawing.cpp
- src/common/cairo.cpp
- src/generic/richtooltipg.cpp
- src/generic/scrlwing.cpp
- src/generic/textdlgg.cpp
- src/jpeg
- src/osx/core/hidjoystick.cpp
- src/qt/anybutton.cpp
- + src/qt/artqt.cpp
- src/qt/bmpbuttn.cpp
- src/qt/button.cpp
- src/qt/renderer.cpp
- src/zlib
- tests/graphics/bmpbundle.cpp


Changes:

=====================================
Makefile.in
=====================================
@@ -5563,7 +5563,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS = \
monodll_qt_timectrl.o \
monodll_qt_overlay.o \
monodll_qt_renderer.o \
- monodll_qt_graphics.o
+ monodll_qt_graphics.o \
+ monodll_artqt.o
@COND_TOOLKIT_QT@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS)
@COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS = \
@COND_PLATFORM_UNIX_1@ monodll_unix_dialup.o monodll_unix_joystick.o \
@@ -7347,7 +7348,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1 = \
monolib_qt_timectrl.o \
monolib_qt_overlay.o \
monolib_qt_renderer.o \
- monolib_qt_graphics.o
+ monolib_qt_graphics.o \
+ monolib_artqt.o
@COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1)
@COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_1 = \
@COND_PLATFORM_UNIX_1@ monolib_unix_dialup.o monolib_unix_joystick.o \
@@ -9278,7 +9280,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2 = \
coredll_qt_timectrl.o \
coredll_qt_overlay.o \
coredll_qt_renderer.o \
- coredll_qt_graphics.o
+ coredll_qt_graphics.o \
+ coredll_artqt.o
@COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2)
@COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_2 = \
@COND_PLATFORM_UNIX_1@ coredll_unix_dialup.o coredll_unix_joystick.o \
@@ -10788,7 +10791,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3 = \
corelib_qt_timectrl.o \
corelib_qt_overlay.o \
corelib_qt_renderer.o \
- corelib_qt_graphics.o
+ corelib_qt_graphics.o \
+ corelib_artqt.o
@COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3)
@COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_3 = \
@COND_PLATFORM_UNIX_1@ corelib_unix_dialup.o corelib_unix_joystick.o \
@@ -16392,6 +16396,9 @@ monodll_qt_renderer.o: $(srcdir)/src/qt/renderer.cpp $(MONODLL_ODEP)
monodll_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp

+monodll_artqt.o: $(srcdir)/src/qt/artqt.cpp $(MONODLL_ODEP)
+ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/artqt.cpp
+
monodll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp

@@ -21177,6 +21184,9 @@ monolib_qt_renderer.o: $(srcdir)/src/qt/renderer.cpp $(MONOLIB_ODEP)
monolib_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp

+monolib_artqt.o: $(srcdir)/src/qt/artqt.cpp $(MONOLIB_ODEP)
+ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/artqt.cpp
+
monolib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp

@@ -26628,6 +26638,9 @@ coredll_qt_renderer.o: $(srcdir)/src/qt/renderer.cpp $(COREDLL_ODEP)
coredll_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(COREDLL_ODEP)
$(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp

+coredll_artqt.o: $(srcdir)/src/qt/artqt.cpp $(COREDLL_ODEP)
+ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/artqt.cpp
+
coredll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(COREDLL_ODEP)
$(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp

@@ -30378,6 +30391,9 @@ corelib_qt_renderer.o: $(srcdir)/src/qt/renderer.cpp $(CORELIB_ODEP)
corelib_qt_graphics.o: $(srcdir)/src/qt/graphics.cpp $(CORELIB_ODEP)
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/graphics.cpp

+corelib_artqt.o: $(srcdir)/src/qt/artqt.cpp $(CORELIB_ODEP)
+ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/artqt.cpp
+
corelib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(CORELIB_ODEP)
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp



=====================================
build/bakefiles/files.bkl
=====================================
@@ -461,6 +461,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/qt/overlay.cpp
src/qt/renderer.cpp
src/qt/graphics.cpp
+ src/qt/artqt.cpp
</set>

<set var="MEDIA_QT_SRC" hints="files">


=====================================
build/cmake/files.cmake
=====================================
@@ -382,6 +382,7 @@ set(QT_SRC
src/qt/overlay.cpp
src/qt/renderer.cpp
src/qt/graphics.cpp
+ src/qt/artqt.cpp
)

set(MEDIA_QT_SRC


=====================================
build/files
=====================================
@@ -319,6 +319,7 @@ QT_SRC=
src/qt/anybutton.cpp
src/qt/app.cpp
src/qt/apptraits.cpp
+ src/qt/artqt.cpp
src/qt/bitmap.cpp
src/qt/bmpbuttn.cpp
src/qt/brush.cpp


=====================================
include/wx/artprov.h
=====================================
@@ -280,7 +280,7 @@ private:


#if !defined(__WXUNIVERSAL__) && \
- (defined(__WXGTK__) || defined(__WXMSW__) || defined(__WXMAC__))
+ (defined(__WXGTK__) || defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXQT__))
// *some* (partial) native implementation of wxArtProvider exists; this is
// not the same as wxArtProvider::HasNativeProvider()!
#define wxHAS_NATIVE_ART_PROVIDER_IMPL


=====================================
include/wx/renderer.h
=====================================
@@ -41,8 +41,9 @@ class WXDLLIMPEXP_FWD_CORE wxWindow;
#undef wxHAS_NATIVE_RENDERER
#endif

-// only MSW and OS X currently provides DrawTitleBarBitmap() method
-#if defined(__WXMSW__) || (defined(__WXMAC__) && wxUSE_LIBPNG && wxUSE_IMAGE)
+// only wxMSW, wxOSX and wxQt currently provides DrawTitleBarBitmap() method
+#if defined(__WXMSW__) || (defined(__WXMAC__) && wxUSE_LIBPNG && wxUSE_IMAGE) || \
+ defined(__WXQT__)
#define wxHAS_DRAW_TITLE_BAR_BITMAP
#endif



=====================================
include/wx/scrolwin.h
=====================================
@@ -152,6 +152,22 @@ public:
// returns 0 if no scrollbars are there.
int GetScrollLines( int orient ) const;

+ // wxWidgets <= 3.3.1 autoscrolled exactly when the (captured) mouse cursor
+ // was outside the entire window. Starting with wxWidgets 3.3.2, the
+ // region where the mouse cursor triggers autoscrolling is configurable.
+ // Allow autoscrolling when the mouse is inside the window but within
+ // insideWidth pixels of the edge.
+ void EnableAutoScrollInside(wxCoord insideWidth);
+ // Forbid autoscrolling when the mouse is outside the window
+ void DisableAutoScrollOutside();
+
+ // Check whether clientPt triggers autoscrolling in each direction: return
+ // true if it does and fill the corresponding output parameter with the
+ // event type to generate.
+ bool AutoscrollTest(wxPoint clientPt,
+ wxEventType& evtHorzScroll,
+ wxEventType& evtVertScroll) const;
+
// Set the x, y scrolling increments.
void SetScrollRate( int xstep, int ystep );

@@ -263,8 +279,10 @@ public:
// the methods to be called from the window event handlers
void HandleOnScroll(wxScrollWinEvent& event);
void HandleOnSize(wxSizeEvent& event);
- void HandleOnMouseEnter(wxMouseEvent& event);
- void HandleOnMouseLeave(wxMouseEvent& event);
+ void OnMotion(wxMouseEvent& event);
+ void OnLeftDown(wxMouseEvent& event);
+ void OnLeaveAutoScrollRegion();
+ void OnEnterAutoScrollRegion();
#if wxUSE_MOUSEWHEEL
void HandleOnMouseWheel(wxMouseEvent& event);
#endif // wxUSE_MOUSEWHEEL
@@ -345,6 +363,10 @@ protected:
}


+ wxCoord m_innerScrollWidth = 0;
+ bool m_outerScrollEnabled = true;
+ bool m_inAutoScrollRegion = false;
+
double m_scaleX;
double m_scaleY;



=====================================
interface/wx/renderer.h
=====================================
@@ -523,8 +523,8 @@ public:
/**
Draw a title bar button in the given state.

- This function is currently only available under MSW and macOS (and only
- for wxTITLEBAR_BUTTON_CLOSE under the latter), its best replacement for
+ This function is currently only available in wxMSW, wxOSX (only for
+ wxTITLEBAR_BUTTON_CLOSE) and wxQt ports, its best replacement for
the other platforms is to use wxArtProvider to retrieve the bitmaps for
@c wxART_HELP and @c wxART_CLOSE (but not any other title bar buttons
and not for any state but normal, i.e. not pressed and not current one).


=====================================
interface/wx/scrolwin.h
=====================================
@@ -95,6 +95,28 @@ enum wxScrollbarVisibility
window out of the visible area), the child window will report a position
of (10,-90).

+ @section scrolled_autoscroll Automatic scrolling
+
+ Scrolled windows implement automatic scrolling behaviour: when the mouse is
+ captured by the application and the user holds the mouse button down, the
+ window may start and keep scrolling even if the mouse doesn't move,
+ provided that it is in the "autoscroll zone". This is convenient to allow
+ extending selection to the parts of the window currently outside of the
+ visible area, for example.
+
+ By default, autoscrolling is triggered when the mouse is anywhere outside
+ of the window, i.e. the window starts scrolling when the (captured) mouse
+ pointer leaves the window and stops when it re-enters the window. However,
+ this behaviour can be customized using EnableAutoScrollInside() and
+ DisableAutoScrollOutside() functions. The first of them allows to enable
+ autoscrolling even when mouse is inside the window, but close to its
+ border, while the second one allows to disable autoscrolling when mouse is
+ outside the window.
+
+ To disable autoscrolling completely, call DisableAutoScrollOutside()
+ without calling EnableAutoScrollInside().
+
+
@beginStyleTable
@style{wxHSCROLL}
If this style is specified and ::wxVSCROLL isn't, the window will be
@@ -603,6 +625,41 @@ public:
void SetScrollPageSize(int orient, int pageSize);
int GetScrollLines( int orient ) const;

+ /**
+ Set the width of the autoscroll zone inside the window rectangle.
+
+ Setting inner scroll zone to a non-zero value enables autoscrolling if
+ the distance between the mouse and the closest edge of the window
+ rectangle is less than the given value.
+
+ By default, autoscrolling is not triggered when the mouse is inside the
+ window.
+
+ @see @ref scrolled_autoscroll, SetOuterScrollZone()
+
+ @param insideWidth
+ The width of the inner scroll zone in pixels. If this parameter is
+ set to 0, there is no inner scroll zone
+ and autoscrolling may be triggered only when the mouse is outside
+ of the window (unless it is disabled too). (Negative values,
+ including ::wxDefaultCoord, are forbidden.)
+
+ @since 3.3.2
+ */
+ void EnableAutoScrollInside(wxCoord insideWidth);
+
+ /**
+ By default, autoscrolling is triggered when the mouse is anywhere
+ outside of the window. This function disables autoscrolling
+ when the mouse is outside the window. (Autoscrolling could
+ still be enabled when the mouse is inside the window.)
+
+ @see @ref scrolled_autoscroll, EnableAutoScrollInside()
+
+ @since 3.3.2
+ */
+ void DisableAutoScrollOutside();
+
/**
Set the scaling factor for the window.



=====================================
samples/drawing/drawing.cpp
=====================================
@@ -272,6 +272,29 @@ public:
}
#endif // wxUSE_GRAPHICS_CONTEXT

+ void OnAutoscrollOuter(wxCommandEvent& WXUNUSED(event))
+ {
+ m_outerScrollEnabled = false;
+ m_canvas->DisableAutoScrollOutside();
+ }
+
+ void OnAutoscrollOuterUpdateUI(wxUpdateUIEvent& event)
+ {
+ event.Check(m_outerScrollEnabled);
+ event.Enable(m_outerScrollEnabled);
+ }
+
+ void OnAutoscrollInner(wxCommandEvent& WXUNUSED(event))
+ {
+ m_innerScrollWidth = FromDIP(16) - m_innerScrollWidth;
+ m_canvas->EnableAutoScrollInside(m_innerScrollWidth);
+ }
+
+ void OnAutoscrollInnerUpdateUI(wxUpdateUIEvent& event)
+ {
+ event.Check(m_innerScrollWidth != 0);
+ }
+
void OnBuffer(wxCommandEvent& event);
void OnCopy(wxCommandEvent& event);
#if wxUSE_FILEDLG
@@ -314,6 +337,9 @@ public:
MyCanvas *m_canvas;
wxMenuItem *m_menuItemUseDC;
private:
+ bool m_outerScrollEnabled = true;
+ int m_innerScrollWidth = 0;
+
// any class wishing to process wxWidgets events must use this macro
wxDECLARE_EVENT_TABLE();
};
@@ -374,6 +400,8 @@ enum
#if wxUSE_GRAPHICS_CONTEXT
File_AntiAliasing,
#endif
+ File_AutoscrollOuter,
+ File_AutoscrollInner,
File_Copy,
File_Save,

@@ -2521,6 +2549,10 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU (File_AntiAliasing, MyFrame::OnAntiAliasing)
EVT_UPDATE_UI (File_AntiAliasing, MyFrame::OnAntiAliasingUpdateUI)
#endif // wxUSE_GRAPHICS_CONTEXT
+ EVT_MENU (File_AutoscrollOuter, MyFrame::OnAutoscrollOuter)
+ EVT_UPDATE_UI (File_AutoscrollOuter, MyFrame::OnAutoscrollOuterUpdateUI)
+ EVT_MENU (File_AutoscrollInner, MyFrame::OnAutoscrollInner)
+ EVT_UPDATE_UI (File_AutoscrollInner, MyFrame::OnAutoscrollInnerUpdateUI)

EVT_MENU (File_Buffer, MyFrame::OnBuffer)
EVT_MENU (File_Copy, MyFrame::OnCopy)
@@ -2621,6 +2653,9 @@ MyFrame::MyFrame(const wxString& title)
->Check();
#endif
menuFile->AppendSeparator();
+ menuFile->AppendCheckItem(File_AutoscrollOuter, "&Outer Scroll Zone", "Autoscroll zone outside window");
+ menuFile->AppendCheckItem(File_AutoscrollInner, "&Inner Scroll Zone", "Autoscroll zone inside window");
+ menuFile->AppendSeparator();
#if wxUSE_METAFILE && defined(wxMETAFILE_IS_ENH)
menuFile->Append(File_Copy, "Copy to clipboard");
#endif


=====================================
src/common/cairo.cpp
=====================================
@@ -187,6 +187,8 @@
(cairo_t* cr, double *dx, double* dy), (cr, dx, dy) ) \
m( cairo_surface_mark_dirty, \
(cairo_surface_t* surface), (surface)) \
+ m( cairo_surface_get_device_scale, \
+ (cairo_surface_t *surface, double *x_scale, double *y_scale), (surface, x_scale, y_scale)) \
m( cairo_surface_set_device_offset, \
(cairo_surface_t* surface, double x_offset, double y_offset), (surface, x_offset, y_offset) )



=====================================
src/generic/richtooltipg.cpp
=====================================
@@ -181,7 +181,14 @@ public:
else
#endif // HAVE_MSW_THEME
{
+ // In wxGTK wxSYS_COLOUR_INFOBK typically uses alpha channel
+ // and this doesn't work as wxPopupWindow background currently,
+ // so prefer not to set any colour at all to at least get
+ // something visible on the screen instead of using black
+ // bacgkround.
+#ifndef __WXGTK__
colStart = wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK);
+#endif
}
}

@@ -198,7 +205,7 @@ public:

SetBackgroundBitmap(bmp);
}
- else // Use solid colour.
+ else if ( colStart.IsOk() ) // Use solid colour.
{
SetBackgroundColour(colStart);
}


=====================================
src/generic/scrlwing.cpp
=====================================
@@ -77,18 +77,13 @@ class wxAutoScrollTimer : public wxTimer
{
public:
wxAutoScrollTimer(wxWindow *winToScroll,
- wxScrollHelperBase *scroll,
- wxEventType eventTypeToSend,
- int pos, int orient);
+ wxScrollHelperBase *scroll);

virtual void Notify() override;

private:
wxWindow *m_win;
wxScrollHelperBase *m_scrollHelper;
- wxEventType m_eventType;
- int m_pos,
- m_orient;

wxDECLARE_NO_COPY_CLASS(wxAutoScrollTimer);
};
@@ -102,15 +97,10 @@ private:
// ----------------------------------------------------------------------------

wxAutoScrollTimer::wxAutoScrollTimer(wxWindow *winToScroll,
- wxScrollHelperBase *scroll,
- wxEventType eventTypeToSend,
- int pos, int orient)
+ wxScrollHelperBase *scroll)
{
m_win = winToScroll;
m_scrollHelper = scroll;
- m_eventType = eventTypeToSend;
- m_pos = pos;
- m_orient = orient;
}

void wxAutoScrollTimer::Notify()
@@ -122,20 +112,44 @@ void wxAutoScrollTimer::Notify()
}
else // we still capture the mouse, continue generating events
{
+ // where is the mouse?
+ // client coords
+ const wxPoint pt = m_win->ScreenToClient(wxGetMousePosition());
+
+ wxEventType horizontalEvent, verticalEvent;
+ // if no event needed, stop auto-scroll
+ if ( !m_scrollHelper->AutoscrollTest(pt, horizontalEvent, verticalEvent) )
+ {
+ Stop();
+ return;
+ }
+
// first scroll the window if we are allowed to do it
- wxScrollWinEvent event1(m_eventType, m_pos, m_orient);
- event1.SetEventObject(m_win);
- event1.SetId(m_win->GetId());
- if ( m_scrollHelper->SendAutoScrollEvents(event1) &&
- m_win->GetEventHandler()->ProcessEvent(event1) )
+ bool needMotion = false;
+ const auto orientations = {
+ std::make_pair(horizontalEvent, wxHORIZONTAL),
+ std::make_pair(verticalEvent, wxVERTICAL),
+ };
+ for (const auto& orientation : orientations)
+ {
+ if (orientation.first != wxEVT_NULL)
+ {
+ wxScrollWinEvent event1(orientation.first, 0, orientation.second);
+ event1.SetEventObject(m_win);
+ event1.SetId(m_win->GetId());
+ if ( m_scrollHelper->SendAutoScrollEvents(event1) &&
+ m_win->GetEventHandler()->ProcessEvent(event1) )
+ {
+ needMotion = true;
+ }
+ }
+ }
+
+ if (needMotion)
{
// and then send a pseudo mouse-move event to refresh the selection
wxMouseEvent event2(wxEVT_MOTION);
- event2.SetPosition(wxGetMousePosition());
-
- // the mouse event coordinates should be client, not screen as
- // returned by wxGetMousePosition
- m_win->ScreenToClient(&event2.m_x, &event2.m_y);
+ event2.SetPosition(pt);

event2.SetEventObject(m_win);

@@ -152,10 +166,6 @@ void wxAutoScrollTimer::Notify()

m_win->GetEventHandler()->ProcessEvent(event2);
}
- else // can't scroll further, stop
- {
- Stop();
- }
}
}
#endif
@@ -171,6 +181,17 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
{
wxEventType evType = event.GetEventType();

+ // always process these mouse events ourselves, even if the user code handles
+ // them as well, as we need to autoscroll
+ if ( evType == wxEVT_LEFT_DOWN )
+ {
+ m_scrollHelper->OnLeftDown((wxMouseEvent&)event);
+ }
+ else if ( evType == wxEVT_MOTION )
+ {
+ m_scrollHelper->OnMotion((wxMouseEvent&)event);
+ }
+
// Pass it on to the real handler: notice that we must not call
// ProcessEvent() on this object itself as it wouldn't pass it to the next
// handler (i.e. the real window) if we're called from a previous handler
@@ -248,14 +269,6 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
}
}

- if ( evType == wxEVT_ENTER_WINDOW )
- {
- m_scrollHelper->HandleOnMouseEnter((wxMouseEvent &)event);
- }
- else if ( evType == wxEVT_LEAVE_WINDOW )
- {
- m_scrollHelper->HandleOnMouseLeave((wxMouseEvent &)event);
- }
#if wxUSE_MOUSEWHEEL
// Use GTK's own scroll wheel handling in GtkScrolledWindow
#ifndef __WXGTK__
@@ -696,6 +709,67 @@ void wxScrollHelperBase::DoPrepareReadOnlyDC(wxReadOnlyDC& dc)
dc.SetUserScale( m_scaleX, m_scaleY );
}

+// see scrolwin.h for description
+void wxScrollHelperBase::EnableAutoScrollInside(wxCoord insideWidth)
+{
+ wxCHECK_RET( insideWidth >= 0,
+ "arg should be non-negative");
+ m_innerScrollWidth = insideWidth;
+}
+
+// see scrolwin.h for description
+void wxScrollHelperBase::DisableAutoScrollOutside()
+{
+ m_outerScrollEnabled = false;
+}
+
+// check whether clientPt triggers autoscrolling in each direction
+bool
+wxScrollHelperBase::AutoscrollTest(wxPoint clientPt,
+ wxEventType& evtHorzScroll,
+ wxEventType& evtVertScroll) const
+{
+ // is mouse in autoscroll region?
+ if ( !m_outerScrollEnabled &&
+ !m_win->GetRect().Contains(clientPt) )
+ {
+ return false;
+ }
+ wxRect inner = m_win->GetRect().Deflate(m_innerScrollWidth);
+ if ( inner.Contains(clientPt) )
+ {
+ return false;
+ }
+
+ // can window can be scrolled in this direction?
+ if ( m_win->HasScrollbar(wxHORIZONTAL) )
+ {
+ if ( clientPt.x < inner.GetLeft() )
+ {
+ evtHorzScroll = wxEVT_SCROLLWIN_LINEUP;
+ }
+ else if (clientPt.x >= inner.GetRight() )
+ {
+ evtHorzScroll = wxEVT_SCROLLWIN_LINEDOWN;
+ }
+ }
+
+ // can window can be scrolled in this direction?
+ if ( m_win->HasScrollbar(wxVERTICAL) )
+ {
+ if ( clientPt.y < inner.GetTop() )
+ {
+ evtVertScroll = wxEVT_SCROLLWIN_LINEUP;
+ }
+ else if ( clientPt.y >= inner.GetBottom() )
+ {
+ evtVertScroll = wxEVT_SCROLLWIN_LINEDOWN;
+ }
+ }
+
+ return true;
+}
+
void wxScrollHelperBase::SetScrollRate( int xstep, int ystep )
{
int old_x = m_xScrollPixelsPerLine * m_xScrollPosition;
@@ -974,80 +1048,62 @@ void wxScrollHelperBase::StopAutoScrolling()
#endif
}

-void wxScrollHelperBase::HandleOnMouseEnter(wxMouseEvent& event)
-{
- StopAutoScrolling();
-
- event.Skip();
-}
-
-void wxScrollHelperBase::HandleOnMouseLeave(wxMouseEvent& event)
+void wxScrollHelperBase::OnMotion(wxMouseEvent& event)
{
// don't prevent the usual processing of the event from taking place
event.Skip();

- // when a captured mouse leave a scrolled window we start generate
- // scrolling events to allow, for example, extending selection beyond the
- // visible area in some controls
- if ( wxWindow::GetCapture() == m_targetWindow )
+ // if not dragging, no autoscroll
+ if ( wxWindow::GetCapture() != m_targetWindow )
{
- // where is the mouse leaving?
- int pos, orient;
- wxPoint pt = event.GetPosition();
- if ( pt.x < 0 )
+ return;
+ }
+
+ wxEventType dummy1, dummy2;
+ bool inAutoScrollRegion = AutoscrollTest(event.GetPosition(), dummy1, dummy2);
+
+ // process change of state
+ if ( inAutoScrollRegion != m_inAutoScrollRegion )
+ {
+ m_inAutoScrollRegion = inAutoScrollRegion;
+ if ( m_inAutoScrollRegion )
{
- orient = wxHORIZONTAL;
- pos = 0;
+ OnEnterAutoScrollRegion();
}
- else if ( pt.y < 0 )
+ else
{
- orient = wxVERTICAL;
- pos = 0;
+ OnLeaveAutoScrollRegion();
}
- else // we're lower or to the right of the window
- {
- wxSize size = m_targetWindow->GetClientSize();
- if ( pt.x >= size.x )
- {
- orient = wxHORIZONTAL;
- pos = m_xScrollLines;
- }
- else if ( pt.y >= size.y )
- {
- orient = wxVERTICAL;
- pos = m_yScrollLines;
- }
- else // this should be impossible
- {
- // but seems to happen sometimes under wxMSW - maybe it's a bug
- // there but for now just ignore it
+ }
+}

- //wxFAIL_MSG( wxT("can't understand where has mouse gone") );
+void wxScrollHelperBase::OnLeftDown(wxMouseEvent& event)
+{
+ // don't prevent the usual processing of the event from taking place
+ event.Skip();

- return;
- }
- }
+ // potential for new autoscroll, so reinitialize
+ m_inAutoScrollRegion = false;
+}

- // only start the auto scroll timer if the window can be scrolled in
- // this direction
- if ( !m_targetWindow->HasScrollbar(orient) )
- return;
+void wxScrollHelperBase::OnLeaveAutoScrollRegion()
+{
+ StopAutoScrolling();
+}

+void wxScrollHelperBase::OnEnterAutoScrollRegion()
+{
+ // when a captured mouse enters the scroll region we start generate
+ // scrolling events to allow, for example, extending selection beyond the
+ // visible area in some controls
#if wxUSE_TIMER
- delete m_timerAutoScroll;
- m_timerAutoScroll = new wxAutoScrollTimer
- (
- m_targetWindow, this,
- pos == 0 ? wxEVT_SCROLLWIN_LINEUP
- : wxEVT_SCROLLWIN_LINEDOWN,
- pos,
- orient
- );
- m_timerAutoScroll->Start(50); // FIXME: make configurable
-#else
- wxUnusedVar(pos);
+ delete m_timerAutoScroll;
+ m_timerAutoScroll = new wxAutoScrollTimer
+ (
+ m_targetWindow, this
+ );
+ m_timerAutoScroll->Start(50); // FIXME: make configurable
#endif
- }
}

#if wxUSE_MOUSEWHEEL


=====================================
src/generic/textdlgg.cpp
=====================================
@@ -115,7 +115,17 @@ bool wxTextEntryDialog::Create(wxWindow *parent,

SetSizer( topsizer );

- topsizer->Fit( this );
+ // Size returned by Fit() is the minimum size needed to fit the contents.
+ const wxSize minSize = topsizer->Fit( this );
+
+ // Prevent the dialog from being resized smaller than the minimum size.
+ SetMinSize(minSize);
+
+ // For single-line entry, also constrain max height to prevent vertical expansion
+ if ( !(style & wxTE_MULTILINE) )
+ {
+ SetMaxSize(wxSize(-1, minSize.GetHeight()));
+ }

if ( style & wxCENTRE )
Centre( wxBOTH );


=====================================
src/jpeg
=====================================
@@ -1 +1 @@
-Subproject commit f1df26641a1d3621639ff25df5f787854a4e6628
+Subproject commit 88cf215c8eee225148e007a66ee1dea5916fc949


=====================================
src/osx/core/hidjoystick.cpp
=====================================
@@ -64,6 +64,19 @@ enum
wxJS_AXIS_RUDDER,
wxJS_AXIS_U,
wxJS_AXIS_V,
+ wxJS_AXIS_EXT,
+};
+
+enum
+{
+ wxJS_DPAD_UP = 0,
+ wxJS_DPAD_UPRIGHT,
+ wxJS_DPAD_RIGHT,
+ wxJS_DPAD_RIGHTDOWN,
+ wxJS_DPAD_DOWN,
+ wxJS_DPAD_DOWNLEFT,
+ wxJS_DPAD_LEFT,
+ wxJS_DPAD_LEFTUP,
};

//---------------------------------------------------------------------------
@@ -83,6 +96,7 @@ public:

int m_nXMax, m_nYMax, m_nZMax, m_nRudderMax, m_nUMax, m_nVMax,
m_nXMin, m_nYMin, m_nZMin, m_nRudderMin, m_nUMin, m_nVMin;
+ int m_nDpadIdx;

friend class wxJoystick;
};
@@ -285,27 +299,21 @@ wxString wxJoystick::GetProductName() const
//---------------------------------------------------------------------------
int wxJoystick::GetNumberButtons() const
{
- int nCount = 0;
-
- for(int nIndex = 0; nIndex < 40; ++nIndex)
+ for (int i = wxJS_MAX_BUTTONS; i > 0; i--)
{
- if(m_hid->HasElement(nIndex))
- ++nCount;
+ if (m_hid->HasElement(i - 1))
+ return i;
}
-
- return nCount;
+ return 0;
}
int wxJoystick::GetNumberAxes() const
{
- int nCount = 0;
-
- for(int nIndex = 40; nIndex < 50; ++nIndex)
+ for (int i = wxJS_MAX_AXES; i > 0; i--)
{
- if(m_hid->HasElement(nIndex))
- ++nCount;
+ if (m_hid->HasElement(wxJS_MAX_BUTTONS + i - 1))
+ return i;
}
-
- return nCount;
+ return 0;
}

//---------------------------------------------------------------------------
@@ -524,7 +532,8 @@ bool wxJoystick::HasPOVCTS() const
//---------------------------------------------------------------------------
wxHIDJoystick::wxHIDJoystick() :
m_nXMax(0), m_nYMax(0), m_nZMax(0), m_nRudderMax(0), m_nUMax(0), m_nVMax(0),
- m_nXMin(0), m_nYMin(0), m_nZMin(0), m_nRudderMin(0), m_nUMin(0), m_nVMin(0)
+ m_nXMin(0), m_nYMin(0), m_nZMin(0), m_nRudderMin(0), m_nUMin(0), m_nVMin(0),
+ m_nDpadIdx(0)
{
}

@@ -594,6 +603,7 @@ void wxHIDJoystick::BuildCookies(CFArrayRef Array)
void wxHIDJoystick::MakeCookies(CFArrayRef Array)
{
int i, nUsage, nPage;
+ int nIndex = wxJS_AXIS_EXT;

for (i = 0; i < CFArrayGetCount(Array); ++i)
{
@@ -663,7 +673,34 @@ void wxHIDJoystick::MakeCookies(CFArrayRef Array)
CFSTR(kIOHIDElementMinKey),
&m_nZMin);
break;
+ case kHIDUsage_GD_Rx:
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_U);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nUMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nUMin);
+ break;
+ case kHIDUsage_GD_Ry:
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_V);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMaxKey),
+ &m_nVMax);
+ wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
+ CFSTR(kIOHIDElementMinKey),
+ &m_nVMin);
+ break;
+ case kHIDUsage_GD_Hatswitch:
+ if (nIndex + 1 < wxJS_MAX_BUTTONS + wxJS_MAX_AXES)
+ {
+ m_nDpadIdx = ++nIndex;
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), nIndex++);
+ }
+ break;
default:
+ if (nIndex < wxJS_MAX_BUTTONS + wxJS_MAX_AXES)
+ AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), nIndex++);
break;
}
}
@@ -873,7 +910,7 @@ uint64_t MachTimeToNanoseconds(uint64_t machTime)
#endif

//is the cookie a button?
- if (nIndex < 32)
+ if (nIndex < wxJS_MAX_BUTTONS)
{
if (hidevent.value)
{
@@ -905,8 +942,56 @@ uint64_t MachTimeToNanoseconds(uint64_t machTime)
wxevent.SetEventType(wxEVT_JOY_ZMOVE);
pThis->m_axe[2] = hidevent.value;
}
+ else if (nIndex == m_hid->m_nDpadIdx)
+ {
+ // Remap the D-pad state to reasonable axis values
+ wxevent.SetEventType(wxEVT_JOY_MOVE);
+ int *axe = &pThis->m_axe[nIndex - wxJS_MAX_BUTTONS - 1];
+ switch (hidevent.value)
+ {
+ case wxJS_DPAD_UP:
+ axe[0] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ axe[1] = m_hid->m_nXMin;
+ break;
+ case wxJS_DPAD_UPRIGHT:
+ axe[0] = m_hid->m_nXMax;
+ axe[1] = m_hid->m_nXMin;
+ break;
+ case wxJS_DPAD_RIGHT:
+ axe[0] = m_hid->m_nXMax;
+ axe[1] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ break;
+ case wxJS_DPAD_RIGHTDOWN:
+ axe[0] = m_hid->m_nXMax;
+ axe[1] = m_hid->m_nXMax;
+ break;
+ case wxJS_DPAD_DOWN:
+ axe[0] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ axe[1] = m_hid->m_nXMax;
+ break;
+ case wxJS_DPAD_DOWNLEFT:
+ axe[0] = m_hid->m_nXMin;
+ axe[1] = m_hid->m_nXMax;
+ break;
+ case wxJS_DPAD_LEFT:
+ axe[0] = m_hid->m_nXMin;
+ axe[1] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ break;
+ case wxJS_DPAD_LEFTUP:
+ axe[0] = m_hid->m_nXMin;
+ axe[1] = m_hid->m_nXMin;
+ break;
+ default: // Released
+ axe[0] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ axe[1] = (m_hid->m_nXMax + m_hid->m_nXMin) / 2;
+ break;
+ }
+ }
else
+ {
wxevent.SetEventType(wxEVT_JOY_MOVE);
+ pThis->m_axe[nIndex - wxJS_MAX_BUTTONS] = hidevent.value;
+ }

uint64_t timestamp = MachTimeToNanoseconds(*((uint64_t*) &hidevent.timestamp));



=====================================
src/qt/anybutton.cpp
=====================================
@@ -115,6 +115,9 @@ void wxAnyButton::QtSetBitmap( const wxBitmapBundle &bitmapBundle )

void wxAnyButton::SetLabel( const wxString &label )
{
+ if ( HasFlag(wxBU_NOTEXT) )
+ return;
+
wxAnyButtonBase::SetLabel( label );

GetQPushButton()->setText( wxQtConvertString( label ));


=====================================
src/qt/artqt.cpp
=====================================
@@ -0,0 +1,253 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/qt/artqt.cpp
+// Purpose: stock wxArtProvider instance with native Qt stock icons
+// Author: Kettab Ali
+// Created: 2026-02-12
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ---------------------------------------------------------------------------
+// headers
+// ---------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+
+#include "wx/artprov.h"
+#include "wx/bitmap.h"
+#include "wx/qt/private/converter.h"
+
+#include <QtGui/QIcon>
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QStyle>
+
+namespace // anonymous
+{
+// This helper function tries to return the standard icon QStyle::StandardPixmap
+// corresponding to the wxArtID if it exists. It tries to return the corresponding
+// theme icon using QIcon::fromTheme() function otherwise.
+QIcon GetQtIconFromArtID(const wxArtID& id)
+{
+ QStyle::StandardPixmap standardIcon;
+
+ if ( id == wxART_GO_BACK )
+ standardIcon = QStyle::SP_ArrowBack;
+ else if ( id == wxART_GO_FORWARD )
+ standardIcon = QStyle::SP_ArrowForward;
+ else if ( id == wxART_GO_UP )
+ standardIcon = QStyle::SP_ArrowUp;
+ else if ( id == wxART_GO_DOWN )
+ standardIcon = QStyle::SP_ArrowDown;
+ else if ( id == wxART_GO_TO_PARENT )
+ standardIcon = QStyle::SP_FileDialogToParent;
+ else if ( id == wxART_GO_HOME )
+ standardIcon = QStyle::SP_DirHomeIcon;
+ else if ( id == wxART_FILE_OPEN )
+ standardIcon = QStyle::SP_DialogOpenButton;
+ else if ( id == wxART_FILE_SAVE )
+ standardIcon = QStyle::SP_DialogSaveButton;
+ else if ( id == wxART_HELP )
+ standardIcon = QStyle::SP_DialogHelpButton;
+ else if ( id == wxART_LIST_VIEW )
+ standardIcon = QStyle::SP_FileDialogListView;
+ else if ( id == wxART_NEW_DIR )
+ standardIcon = QStyle::SP_FileDialogNewFolder;
+ else if ( id == wxART_HARDDISK )
+ standardIcon = QStyle::SP_DriveHDIcon;
+ else if ( id == wxART_FLOPPY )
+ standardIcon = QStyle::SP_DriveFDIcon;
+ else if ( id == wxART_CDROM )
+ standardIcon = QStyle::SP_DriveCDIcon;
+ else if ( id == wxART_FOLDER )
+ standardIcon = QStyle::SP_DirIcon;
+ else if ( id == wxART_FOLDER_OPEN )
+ standardIcon = QStyle::SP_DirOpenIcon;
+ else if ( id == wxART_NORMAL_FILE )
+ standardIcon = QStyle::SP_FileIcon;
+ else if ( id == wxART_TICK_MARK )
+ standardIcon = QStyle::SP_DialogOkButton;
+ else if ( id == wxART_CROSS_MARK )
+ standardIcon = QStyle::SP_DialogCancelButton;
+ else if ( id == wxART_ERROR )
+ standardIcon = QStyle::SP_MessageBoxCritical;
+ else if ( id == wxART_QUESTION )
+ standardIcon = QStyle::SP_MessageBoxQuestion;
+ else if ( id == wxART_WARNING )
+ standardIcon = QStyle::SP_MessageBoxWarning;
+ else if ( id == wxART_INFORMATION )
+ standardIcon = QStyle::SP_MessageBoxInformation;
+ else if ( id == wxART_CLOSE )
+ standardIcon = QStyle::SP_DialogCloseButton;
+ else if ( id == wxART_REFRESH )
+ standardIcon = QStyle::SP_BrowserReload;
+ else if ( id == wxART_STOP )
+ standardIcon = QStyle::SP_BrowserStop;
+ else
+ standardIcon = QStyle::SP_CustomBase;
+
+ if ( standardIcon != QStyle::SP_CustomBase )
+ {
+ return QApplication::style()->standardIcon(standardIcon);
+ }
+
+ // Try returning theme icon if there is no corresponding standard icon:
+
+#define TRY_RETURN_THEMEICON(themeId) \
+ { \
+ if ( QIcon::hasThemeIcon(themeId) ) \
+ return QIcon::fromTheme(themeId); \
+ }
+
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+ #define TRY_RETURN_THEMEICON2(themeId, unused) \
+ return QIcon::fromTheme(QIcon::ThemeIcon::themeId);
+#else // Qt version < 6.7
+ #define TRY_RETURN_THEMEICON2(unused, themeId) TRY_RETURN_THEMEICON(themeId)
+#endif // Qt version >= 6.7
+
+ if ( id == wxART_ADD_BOOKMARK )
+ TRY_RETURN_THEMEICON2(ListAdd, "list-add")
+ else if ( id == wxART_DEL_BOOKMARK )
+ TRY_RETURN_THEMEICON2(ListRemove, "list-remove")
+ else if ( id == wxART_HELP_SETTINGS )
+ TRY_RETURN_THEMEICON("preferences-desktop-font")
+ else if ( id == wxART_HELP_FOLDER )
+ TRY_RETURN_THEMEICON("folder")
+ else if ( id == wxART_HELP_PAGE )
+ TRY_RETURN_THEMEICON("text-x-generic")
+ else if ( id == wxART_GOTO_FIRST )
+ TRY_RETURN_THEMEICON("go-first")
+ else if ( id == wxART_GOTO_LAST )
+ TRY_RETURN_THEMEICON("go-last")
+ else if ( id == wxART_FILE_SAVE_AS )
+ TRY_RETURN_THEMEICON2(DocumentSaveAs, "document-save-as")
+ else if ( id == wxART_PRINT )
+ TRY_RETURN_THEMEICON2(DocumentPrint, "document-print")
+ else if ( id == wxART_TIP )
+ TRY_RETURN_THEMEICON2(DialogInformation, "dialog-information")
+ else if ( id == wxART_REMOVABLE )
+ TRY_RETURN_THEMEICON2(MediaFlash, "drive-removable-media")
+ else if ( id == wxART_EXECUTABLE_FILE )
+ TRY_RETURN_THEMEICON("system-run")
+ else if ( id == wxART_MISSING_IMAGE )
+ TRY_RETURN_THEMEICON2(ImageMissing, "image-missing")
+ else if ( id == wxART_COPY )
+ TRY_RETURN_THEMEICON2(EditCopy, "edit-copy")
+ else if ( id == wxART_CUT )
+ TRY_RETURN_THEMEICON2(EditCut, "edit-cut")
+ else if ( id == wxART_PASTE )
+ TRY_RETURN_THEMEICON2(EditPaste, "edit-paste")
+ else if ( id == wxART_DELETE )
+ TRY_RETURN_THEMEICON2(EditDelete, "edit-delete")
+ else if ( id == wxART_NEW )
+ TRY_RETURN_THEMEICON2(DocumentNew, "document-new")
+ else if ( id == wxART_UNDO )
+ TRY_RETURN_THEMEICON2(EditUndo, "edit-undo")
+ else if ( id == wxART_REDO )
+ TRY_RETURN_THEMEICON2(EditRedo, "edit-redo")
+ else if ( id == wxART_PLUS )
+ TRY_RETURN_THEMEICON2(ListAdd, "list-add")
+ else if ( id == wxART_MINUS )
+ TRY_RETURN_THEMEICON2(ListRemove, "list-remove")
+ else if ( id == wxART_QUIT )
+ TRY_RETURN_THEMEICON2(ApplicationExit, "application-exit")
+ else if ( id == wxART_FIND )
+ TRY_RETURN_THEMEICON2(EditFind, "edit-find")
+ else if ( id == wxART_FIND_AND_REPLACE )
+ TRY_RETURN_THEMEICON("edit-find-replace")
+ else if ( id == wxART_FULL_SCREEN )
+ TRY_RETURN_THEMEICON2(ViewFullscreen, "view-fullscreen")
+ else if ( id == wxART_EDIT )
+ TRY_RETURN_THEMEICON2(InsertText, "accessories-text-editor")
+// else if ( id == wxART_HELP_SIDE_PANEL )
+// else if ( id == wxART_HELP_BOOK )
+// else if ( id == wxART_GO_DIR_UP )
+// else if ( id == wxART_REPORT_VIEW )
+
+ return QIcon();
+}
+} // anonymous
+
+// ----------------------------------------------------------------------------
+// wxQtArtProvider
+// ----------------------------------------------------------------------------
+
+class wxQtArtProvider : public wxArtProvider
+{
+protected:
+ virtual wxBitmap CreateBitmap(const wxArtID& id,
+ const wxArtClient& client,
+ const wxSize& size) override;
+};
+
+wxBitmap wxQtArtProvider::CreateBitmap(const wxArtID& id,
+ const wxArtClient& client,
+ const wxSize& size)
+{
+ wxSize iconSize = size != wxDefaultSize
+ ? size : GetNativeDIPSizeHint(client);
+
+ if ( iconSize != wxDefaultSize )
+ {
+ const QIcon qtIcon = GetQtIconFromArtID(id);
+
+ if ( !qtIcon.isNull() )
+ {
+ return wxBitmap(qtIcon.pixmap(wxQtConvertSize(iconSize)));
+ }
+ }
+
+ return wxNullBitmap;
+}
+
+// ----------------------------------------------------------------------------
+// wxArtProvider::InitNativeProvider
+// ----------------------------------------------------------------------------
+
+/*static*/
+void wxArtProvider::InitNativeProvider()
+{
+ PushBack(new wxQtArtProvider);
+}
+
+// ----------------------------------------------------------------------------
+// wxArtProvider::GetNativeSizeHint()
+// ----------------------------------------------------------------------------
+
+/*static*/
+wxSize wxArtProvider::GetNativeDIPSizeHint(const wxArtClient& client)
+{
+ QStyle* const qtStyle = QApplication::style();
+
+ int pm = -1;
+
+ if ( client == wxART_TOOLBAR )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_ToolBarIconSize);
+ }
+ else if ( client == wxART_MENU )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_SmallIconSize);
+ }
+ else if ( client == wxART_FRAME_ICON )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_SmallIconSize);
+ }
+ else if ( client == wxART_CMN_DIALOG ||
+ client == wxART_MESSAGE_BOX )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_MessageBoxIconSize);
+ }
+ else if ( client == wxART_BUTTON )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_ButtonIconSize);
+ }
+ else if ( client == wxART_LIST )
+ {
+ pm = qtStyle->pixelMetric(QStyle::PM_ListViewIconSize);
+ }
+
+ return wxSize(pm, pm);
+}


=====================================
src/qt/bmpbuttn.cpp
=====================================
@@ -12,6 +12,8 @@

#include "wx/bmpbuttn.h"

+#include <QtWidgets/QPushButton>
+
wxBitmapButton::wxBitmapButton(wxWindow *parent,
wxWindowID id,
const wxBitmapBundle& bitmap,
@@ -39,11 +41,19 @@ bool wxBitmapButton::Create(wxWindow *parent,
// Show the initial bitmap and resize accordingly:
if ( bitmap.IsOk() )
{
- wxBitmapButtonBase::SetBitmapLabel(bitmap);
-
- // we need to adjust the size after setting the bitmap as it may be too
- // big for the default button size
- SetInitialSize(size);
+ SetBitmapLabel(bitmap);
+
+ if ( HasFlag(wxBU_EXACTFIT) )
+ {
+ GetQPushButton()->setFlat(true);
+ GetQPushButton()->setStyleSheet("QPushButton { border: none; }");
+ }
+ else
+ {
+ // we need to adjust the size after setting the bitmap as it may be too
+ // big for the default button size
+ SetInitialSize(size);
+ }
}
return true;
}


=====================================
src/qt/button.cpp
=====================================
@@ -40,7 +40,11 @@ bool wxButton::Create(wxWindow *parent, wxWindowID id,
const wxString& name )
{
QtCreate(parent);
- SetLabel( label.IsEmpty() && wxIsStockID( id ) ? wxGetStockLabel( id ) : label );
+
+ if ( !(style & wxBU_NOTEXT) )
+ {
+ SetLabel( label.IsEmpty() && wxIsStockID( id ) ? wxGetStockLabel( id ) : label );
+ }

return wxButtonBase::Create( parent, id, pos, size, style, validator, name );
}


=====================================
src/qt/renderer.cpp
=====================================
@@ -128,6 +128,12 @@ public:
const wxRect& rect,
int flags = 0) override;

+ virtual void DrawTitleBarBitmap(wxWindow *win,
+ wxDC& dc,
+ const wxRect& rect,
+ wxTitleBarButton button,
+ int flags = 0) override;
+
virtual wxSize GetCheckBoxSize(wxWindow *win, int flags = 0) override;

virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) override;
@@ -637,6 +643,67 @@ wxRendererQt::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int WXU
qtStyle->drawPrimitive(QStyle::PE_FrameFocusRect, &option, painter, qtWidget);
}

+void
+wxRendererQt::DrawTitleBarBitmap(wxWindow* win,
+ wxDC& dc,
+ const wxRect& rect,
+ wxTitleBarButton button,
+ int flags)
+{
+ auto painter = wxGetQtPainter(dc);
+
+ wxCHECK_RET( painter, "Invalid painter!" );
+
+ wxDCClipper clip(dc, rect);
+
+ auto qtWidget = win->GetHandle();
+ auto qtStyle = qtWidget->style();
+
+ QStyleOption option;
+ option.initFrom(qtWidget);
+ option.rect = wxQtConvertRect(rect);
+ option.state = QStyle::State_Enabled;
+
+ if ( flags & wxCONTROL_CURRENT )
+ option.state |= QStyle::State_Active | QStyle::State_MouseOver;
+
+ if ( flags & wxCONTROL_PRESSED )
+ option.state |= QStyle::State_Sunken;
+
+ QStyle::StandardPixmap standardIcon;
+
+ switch ( button )
+ {
+ case wxTITLEBAR_BUTTON_CLOSE:
+ standardIcon = QStyle::SP_TitleBarCloseButton;
+ break;
+
+ case wxTITLEBAR_BUTTON_MAXIMIZE:
+ standardIcon = QStyle::SP_TitleBarMaxButton;
+ break;
+
+ case wxTITLEBAR_BUTTON_ICONIZE:
+ standardIcon = QStyle::SP_TitleBarMinButton;
+ break;
+
+ case wxTITLEBAR_BUTTON_RESTORE:
+ standardIcon = QStyle::SP_TitleBarNormalButton;
+ break;
+
+ case wxTITLEBAR_BUTTON_HELP:
+ standardIcon = QStyle::SP_TitleBarContextHelpButton;
+ break;
+
+ default:
+ wxFAIL_MSG( "unsupported title bar button" );
+ return;
+ }
+
+ QIcon icon = qtStyle->standardIcon(standardIcon, &option, qtWidget);
+
+ icon.paint(painter, option.rect);
+}
+
namespace
{
// N.B.: Keep the Windows and non-Windows versions separate


=====================================
src/zlib
=====================================
@@ -1 +1 @@
-Subproject commit d672063aa21e7b12f6ea00f9e9027637f79cbff8
+Subproject commit 62eba04c6ff5a91aff6ce9ffd50ff7a52994412c


=====================================
tests/graphics/bmpbundle.cpp
=====================================
@@ -22,6 +22,10 @@
#include "wx/msw/private/resource_usage.h"
#endif // __WXMSW__

+#ifdef __WXQT__
+ #include <QtGlobal> // QT_VERSION and QT_VERSION_CHECK
+#endif
+
#include "asserthelper.h"

// ----------------------------------------------------------------------------
@@ -529,13 +533,23 @@ TEST_CASE("BitmapBundle::ArtProvider", "[bmpbundle][art]")
// client for which GetNativeSizeHint() of the native art provider returns
// wxDefaultSize.
const wxArtClient artClient =
-#ifdef __WXMSW__
+#if defined(__WXMSW__) || defined(__WXQT__)
wxART_TOOLBAR
#else
wxART_LIST
#endif
;

+#ifdef __WXQT__
+ #if ( QT_VERSION < QT_VERSION_CHECK(5, 12, 0) )
+ if ( IsRunningUnderXVFB() )
+ {
+ WARN("Ignoring test failing under xvfb with Qt < 5.12");
+ return;
+ }
+ #endif // QT < 5.12
+#endif // __WXQT__
+
// We also need to use an image provided by Tango but not by the native art
// provider, but here we can at least avoid the platform checks by using an
// image not provided by any native providers.



View it on GitLab: https://gitlab.com/wxwidgets/wxwidgets/-/compare/b0d50ffe916456dd0b5c6244d5dc178b35442a6c...15285067673a40a318989d42ffc0d9ac5833ff70

--
View it on GitLab: https://gitlab.com/wxwidgets/wxwidgets/-/compare/b0d50ffe916456dd0b5c6244d5dc178b35442a6c...15285067673a40a318989d42ffc0d9ac5833ff70
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help


Reply all
Reply to author
Forward
0 new messages