wxQt: put cursor hotspot at 0, 0 by default. This has worked in other ports because wxAtoi of empty string returns 0.
wxQt: support DPI-independent pixels.
wxQt: respect wxTR_EDIT_LABELS style flag for wxTreeCtrl.
Fix build error with C++20. An explicit conversion is required now.
wxQt: vertically center cell content in wxListCtrl.
wxQt: improve best size calculation for wxTextCtrl. The size hint provided by Qt is usually too large for being a min size.
wxQt: replace deprecated API usage in settings and radiobox.
wxQt: fix crash in wxListCtrl if the window gets destructed while an editor is open.
Remove wxQt special-case in wxTextCtrl::GetBestSize test. Best size for multiline text controls is now calculated similarly to wxGTK.
wxQt: implement wxBitmapRefData:IsOk().
wxQt: implement wxListCtrl::SetSingleStyle().
wxQt: hide wxListCtrl header in non-report modes. Header has no use in wxLC_LIST, wxLC_ICON, wxLC_SMALL_ICON modes.
Merge branch 'wxqt-hidpi' of https://github.com/dsa-t/wxWidgets Various wxQt fixes including improved high DPI support. See #24573.
Merge branch 'wxqt-fixes-1' of https://github.com/dsa-t/wxWidgets More wxQt fixes for wxListCtrl, wxTreeCtrl and wxBitmap. Also fix compiling a sample when using C++20. See #24586.
wxrc: Generate C++ code which is faster to compile and smaller Avoiding performing the conversions from "const wxChar*" to wxString in all places where XRC_ADD_FILE is used and doing it in just a single function allows to significantly reduce both the compilation time and the size of the generated machine code. Also add a simple script allowing to generate the XRC file that can be used to test this improvement. Closes #24579.
Recognize Windows Server 2019 in wxGetOsDescription() For some reason, testing for Windows Server 2019 was missing there. Closes #24598.
Do not scale the size of bitmap in wxMSW Create(size, dc) overload The size passed to Create() should be interpreted in the same way as the size passed to CreateWithLogicalSize() and in wxMSW this means that it should _not_ be scaled. This makes the size of the bitmap returned by this function overload consistent with wxDC::GetSize(), so it looks like the right thing to do, even if it's a backwards-incompatible change. Closes #24559.
... | ... | @@ -92,6 +92,10 @@ Changes in behaviour not resulting in compilation errors |
92 | 92 | made is behaviour there incompatible with the other platforms. Please call
|
93 | 93 | wxWebRequest::EnablePersistentStorage() explicitly if you need it.
|
94 | 94 | |
95 | +- In wxMSW, behaviour of wxBitmap::Create(size, dc) overload has changed to
|
|
96 | + not scale the size by the content scale factor of the DC any longer, as the
|
|
97 | + size here is expressed in physical pixels and not in DIPs.
|
|
98 | + |
|
95 | 99 | |
96 | 100 | Changes in behaviour which may result in build errors
|
97 | 101 | -----------------------------------------------------
|
... | ... | @@ -112,7 +112,7 @@ |
112 | 112 | physical pixels and a window must be 200px wide to have the same apparent
|
113 | 113 | size in high DPI as in normal DPI.
|
114 | 114 | */
|
115 | -#if defined(__WXGTK3__) || defined(__WXMAC__)
|
|
115 | +#if defined(__WXGTK3__) || defined(__WXMAC__) || defined(__WXQT__)
|
|
116 | 116 | #define wxHAS_DPI_INDEPENDENT_PIXELS
|
117 | 117 | |
118 | 118 | // This is an older synonym kept only for compatibility
|
... | ... | @@ -38,6 +38,9 @@ public: |
38 | 38 | virtual bool Create(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH) override;
|
39 | 39 | virtual bool Create(int width, int height, const wxDC& dc);
|
40 | 40 | |
41 | + virtual void SetScaleFactor(double scale);
|
|
42 | + virtual double GetScaleFactor() const;
|
|
43 | + |
|
41 | 44 | virtual int GetHeight() const override;
|
42 | 45 | virtual int GetWidth() const override;
|
43 | 46 | virtual int GetDepth() const override;
|
... | ... | @@ -83,6 +86,8 @@ protected: |
83 | 86 | virtual wxGDIRefData *CreateGDIRefData() const override;
|
84 | 87 | virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const override;
|
85 | 88 | |
89 | + virtual bool DoCreate(const wxSize& sz, double scale, int depth) override;
|
|
90 | + |
|
86 | 91 | private:
|
87 | 92 | #if wxUSE_IMAGE
|
88 | 93 | void InitFromImage(const wxImage& image, int depth, double WXUNUSED(scale));
|
... | ... | @@ -101,6 +101,10 @@ public: |
101 | 101 | // get the (average) character size for the current font
|
102 | 102 | virtual int GetCharHeight() const override;
|
103 | 103 | virtual int GetCharWidth() const override;
|
104 | + virtual double GetContentScaleFactor() const override;
|
|
105 | + |
|
106 | + virtual wxSize GetDPI() const;
|
|
107 | + virtual double GetDPIScaleFactor() const override;
|
|
104 | 108 | |
105 | 109 | virtual void SetScrollbar( int orient,
|
106 | 110 | int pos,
|
... | ... | @@ -528,7 +528,7 @@ public: |
528 | 528 | The physical size of the bitmap created by this function depends on the
|
529 | 529 | platform and will be the same as @a size on the platforms for which
|
530 | 530 | `wxHAS_DPI_INDEPENDENT_PIXELS` is not defined (e.g. wxMSW) or @a size
|
531 | - multiplied by @a scale for those where it is (e.g. wxGTK3 and wxOSX).
|
|
531 | + multiplied by @a scale for those where it is (e.g. wxGTK3, wxOSX and wxQt).
|
|
532 | 532 | In other words, this function is the same as CreateWithDIPSize() if
|
533 | 533 | `wxHAS_DPI_INDEPENDENT_PIXELS` is defined, but not otherwise.
|
534 | 534 |
... | ... | @@ -600,7 +600,9 @@ void DoDownload(const wxString& urlname) |
600 | 600 | // Print the contents type and file size
|
601 | 601 | wxLogMessage("Contents type: %s\nFile size: %s\nStarting to download...",
|
602 | 602 | url.GetProtocol().GetContentType(),
|
603 | - data->GetSize() != (size_t)-1 ? wxString::Format("%zu", data->GetSize()) : "n/a");
|
|
603 | + data->GetSize() != (size_t)-1
|
|
604 | + ? wxString::Format("%zu", data->GetSize())
|
|
605 | + : wxString("n/a"));
|
|
604 | 606 | |
605 | 607 | // Get the data
|
606 | 608 | wxStringOutputStream sout;
|
... | ... | @@ -751,12 +751,10 @@ bool wxBitmap::Create(int width, int height, const wxDC& dc) |
751 | 751 | {
|
752 | 752 | wxCHECK_MSG( dc.IsOk(), false, wxT("invalid HDC in wxBitmap::Create()") );
|
753 | 753 | |
754 | - const double scale = dc.GetContentScaleFactor();
|
|
755 | - |
|
756 | - if ( !DoCreate(wxRound(width*scale), wxRound(height*scale), -1, dc.GetHDC()) )
|
|
754 | + if ( !DoCreate(width, height, -1, dc.GetHDC()) )
|
|
757 | 755 | return false;
|
758 | 756 | |
759 | - GetBitmapData()->m_scaleFactor = scale;
|
|
757 | + GetBitmapData()->m_scaleFactor = dc.GetContentScaleFactor();
|
|
760 | 758 | |
761 | 759 | return true;
|
762 | 760 | }
|
... | ... | @@ -1108,6 +1108,8 @@ int wxIsWindowsServer() |
1108 | 1108 | return -1;
|
1109 | 1109 | }
|
1110 | 1110 | |
1111 | +static const int WINDOWS_SERVER2019_BUILD = 17763;
|
|
1112 | + |
|
1111 | 1113 | // Windows 11 uses the same version as Windows 10 but its build numbers start
|
1112 | 1114 | // from 22000, which provides a way to test for it.
|
1113 | 1115 | static const int FIRST_WINDOWS11_BUILD = 22000;
|
... | ... | @@ -1176,13 +1178,20 @@ wxString wxGetOsDescription() |
1176 | 1178 | |
1177 | 1179 | case 10:
|
1178 | 1180 | if (info.dwBuildNumber >= FIRST_WINDOWS11_BUILD)
|
1181 | + {
|
|
1179 | 1182 | str = wxIsWindowsServer() == 1
|
1180 | 1183 | ? "Windows Server 2022"
|
1181 | 1184 | : "Windows 11";
|
1185 | + |
|
1186 | + }
|
|
1187 | + else if ( wxIsWindowsServer() == 1 )
|
|
1188 | + {
|
|
1189 | + str = info.dwBuildNumber >= WINDOWS_SERVER2019_BUILD
|
|
1190 | + ? "Windows Server 2019"
|
|
1191 | + : "Windows Server 2016";
|
|
1192 | + }
|
|
1182 | 1193 | else
|
1183 | - str = wxIsWindowsServer() == 1
|
|
1184 | - ? "Windows Server 2016"
|
|
1185 | - : "Windows 10";
|
|
1194 | + str = "Windows 10";
|
|
1186 | 1195 | break;
|
1187 | 1196 | }
|
1188 | 1197 |
... | ... | @@ -104,7 +104,7 @@ void wxAnyButton::QtSetBitmap( const wxBitmapBundle &bitmapBundle ) |
104 | 104 | if ( pixmap != nullptr )
|
105 | 105 | {
|
106 | 106 | m_qtPushButton->setIcon(QIcon(*pixmap));
|
107 | - m_qtPushButton->setIconSize(pixmap->rect().size());
|
|
107 | + m_qtPushButton->setIconSize(pixmap->rect().size() / pixmap->devicePixelRatio());
|
|
108 | 108 | |
109 | 109 | InvalidateBestSize();
|
110 | 110 | }
|
... | ... | @@ -161,6 +161,11 @@ class wxBitmapRefData: public wxGDIRefData |
161 | 161 | |
162 | 162 | virtual ~wxBitmapRefData() { delete m_mask; }
|
163 | 163 | |
164 | + virtual bool IsOk() const override
|
|
165 | + {
|
|
166 | + return !m_qtPixmap.isNull();
|
|
167 | + }
|
|
168 | + |
|
164 | 169 | QPixmap m_qtPixmap;
|
165 | 170 | QImage m_rawPixelSource;
|
166 | 171 | wxMask *m_mask;
|
... | ... | @@ -230,13 +235,15 @@ wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type ) |
230 | 235 | }
|
231 | 236 | |
232 | 237 | #if wxUSE_IMAGE
|
233 | -void wxBitmap::InitFromImage(const wxImage& image, int depth, double WXUNUSED(scale) )
|
|
238 | +void wxBitmap::InitFromImage(const wxImage& image, int depth, double scale )
|
|
234 | 239 | {
|
235 | 240 | wxMask* mask = nullptr;
|
236 | 241 | auto qtImage = depth == 1
|
237 | 242 | ? QBitmap::fromImage(ConvertImage(image), Qt::ThresholdDither)
|
238 | 243 | : QPixmap::fromImage(ConvertImage(image, &mask));
|
239 | 244 | |
245 | + qtImage.setDevicePixelRatio(scale);
|
|
246 | + |
|
240 | 247 | m_refData = new wxBitmapRefData(qtImage, mask);
|
241 | 248 | }
|
242 | 249 | |
... | ... | @@ -271,9 +278,38 @@ bool wxBitmap::Create(const wxSize& sz, int depth ) |
271 | 278 | return Create(sz.GetWidth(), sz.GetHeight(), depth);
|
272 | 279 | }
|
273 | 280 | |
274 | -bool wxBitmap::Create(int width, int height, const wxDC& WXUNUSED(dc))
|
|
281 | +bool wxBitmap::Create(int width, int height, const wxDC& dc)
|
|
282 | +{
|
|
283 | + return DoCreate(wxSize(width, height),
|
|
284 | + dc.GetContentScaleFactor(),
|
|
285 | + wxBITMAP_SCREEN_DEPTH);
|
|
286 | +}
|
|
287 | + |
|
288 | +bool wxBitmap::DoCreate(const wxSize& size, double scale, int depth)
|
|
289 | +{
|
|
290 | + Create(size*scale, depth);
|
|
291 | + M_PIXDATA.setDevicePixelRatio( scale );
|
|
292 | + |
|
293 | + return true;
|
|
294 | +}
|
|
295 | + |
|
296 | +void wxBitmap::SetScaleFactor(double scale)
|
|
297 | +{
|
|
298 | + wxCHECK_RET( IsOk(), "invalid bitmap" );
|
|
299 | + |
|
300 | + if ( M_PIXDATA.devicePixelRatio() != scale )
|
|
301 | + {
|
|
302 | + AllocExclusive();
|
|
303 | + |
|
304 | + M_PIXDATA.setDevicePixelRatio( scale );
|
|
305 | + }
|
|
306 | +}
|
|
307 | + |
|
308 | +double wxBitmap::GetScaleFactor() const
|
|
275 | 309 | {
|
276 | - return Create(width, height);
|
|
310 | + wxCHECK_MSG( IsOk(), -1, "invalid bitmap" );
|
|
311 | + |
|
312 | + return M_PIXDATA.devicePixelRatio();
|
|
277 | 313 | }
|
278 | 314 | |
279 | 315 | int wxBitmap::GetHeight() const
|
... | ... | @@ -378,9 +414,23 @@ void wxBitmap::SetMask(wxMask *mask) |
378 | 414 | M_MASK = mask;
|
379 | 415 | }
|
380 | 416 | |
381 | -wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
|
|
417 | +wxBitmap wxBitmap::GetSubBitmap(const wxRect& r) const
|
|
382 | 418 | {
|
383 | - wxBitmap bmp = wxBitmap(M_PIXDATA.copy(wxQtConvertRect(rect)));
|
|
419 | + wxBitmap bmp;
|
|
420 | + |
|
421 | + const double s = M_PIXDATA.devicePixelRatio();
|
|
422 | + const wxRect rect(wxRound(r.x * s), wxRound(r.y * s), wxRound(r.width * s), wxRound(r.height * s));
|
|
423 | + |
|
424 | + const int w = rect.width;
|
|
425 | + const int h = rect.height;
|
|
426 | + |
|
427 | + wxCHECK_MSG(rect.x >= 0 && rect.y >= 0 &&
|
|
428 | + rect.x + w <= M_PIXDATA.width() &&
|
|
429 | + rect.y + h <= M_PIXDATA.height(),
|
|
430 | + bmp, wxT("invalid bitmap region"));
|
|
431 | + |
|
432 | + bmp = wxBitmap(M_PIXDATA.copy(wxQtConvertRect(rect)));
|
|
433 | + bmp.SetScaleFactor(s);
|
|
384 | 434 | |
385 | 435 | if ( M_MASK && M_MASK->GetHandle() )
|
386 | 436 | {
|
... | ... | @@ -165,9 +165,9 @@ void wxCursor::InitFromImage( const wxImage & image ) |
165 | 165 | |
166 | 166 | GetHandle() = QCursor(*bmp.GetHandle(),
|
167 | 167 | image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) ?
|
168 | - image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X) : -1,
|
|
168 | + image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X) : 0,
|
|
169 | 169 | image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y) ?
|
170 | - image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y) : -1);
|
|
170 | + image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y) : 0);
|
|
171 | 171 | }
|
172 | 172 | |
173 | 173 | #endif // wxUSE_IMAGE
|
... | ... | @@ -57,6 +57,8 @@ void wxMemoryDCImpl::DoSelect( const wxBitmap& bitmap ) |
57 | 57 | m_qtPixmap = bitmap.GetHandle();
|
58 | 58 | if ( bitmap.IsOk() && !m_qtPixmap->isNull() )
|
59 | 59 | {
|
60 | + m_contentScaleFactor = bitmap.GetScaleFactor();
|
|
61 | + |
|
60 | 62 | // apply mask before drawing
|
61 | 63 | wxMask *mask = bitmap.GetMask();
|
62 | 64 | if ( mask && mask->GetHandle() )
|
... | ... | @@ -11,9 +11,13 @@ |
11 | 11 | #include "wx/display.h"
|
12 | 12 | #include "wx/private/display.h"
|
13 | 13 | #include <QtWidgets/QApplication>
|
14 | -#include <QtWidgets/QDesktopWidget>
|
|
14 | +#include <QtGui/QScreen>
|
|
15 | 15 | #include "wx/qt/private/converter.h"
|
16 | 16 | |
17 | +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
|
18 | + #include <QtWidgets/QDesktopWidget>
|
|
19 | +#endif
|
|
20 | + |
|
17 | 21 | class wxDisplayImplQt : public wxDisplayImpl
|
18 | 22 | {
|
19 | 23 | public:
|
... | ... | @@ -22,6 +26,7 @@ public: |
22 | 26 | virtual wxRect GetGeometry() const override;
|
23 | 27 | virtual wxRect GetClientArea() const override;
|
24 | 28 | virtual int GetDepth() const override;
|
29 | + virtual double GetScaleFactor() const override;
|
|
25 | 30 | |
26 | 31 | #if wxUSE_DISPLAY
|
27 | 32 | virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const override;
|
... | ... | @@ -37,17 +42,22 @@ wxDisplayImplQt::wxDisplayImplQt( unsigned n ) |
37 | 42 | |
38 | 43 | wxRect wxDisplayImplQt::GetGeometry() const
|
39 | 44 | {
|
40 | - return wxQtConvertRect( QApplication::desktop()->screenGeometry( GetIndex() ));
|
|
45 | + return wxQtConvertRect(QApplication::screens().value(GetIndex())->geometry());
|
|
41 | 46 | }
|
42 | 47 | |
43 | 48 | wxRect wxDisplayImplQt::GetClientArea() const
|
44 | 49 | {
|
45 | - return wxQtConvertRect( QApplication::desktop()->availableGeometry( GetIndex() ));
|
|
50 | + return wxQtConvertRect(QApplication::screens().value(GetIndex())->availableGeometry());
|
|
46 | 51 | }
|
47 | 52 | |
48 | 53 | int wxDisplayImplQt::GetDepth() const
|
49 | 54 | {
|
50 | - return IsPrimary() ? QApplication::desktop()->depth() : 0;
|
|
55 | + return QApplication::screens().value(GetIndex())->depth();
|
|
56 | +}
|
|
57 | + |
|
58 | +double wxDisplayImplQt::GetScaleFactor() const
|
|
59 | +{
|
|
60 | + return QApplication::screens().value(GetIndex())->devicePixelRatio();
|
|
51 | 61 | }
|
52 | 62 | |
53 | 63 | #if wxUSE_DISPLAY
|
... | ... | @@ -58,9 +68,11 @@ wxArrayVideoModes wxDisplayImplQt::GetModes(const wxVideoMode& WXUNUSED(mode)) c |
58 | 68 | |
59 | 69 | wxVideoMode wxDisplayImplQt::GetCurrentMode() const
|
60 | 70 | {
|
61 | - int width = QApplication::desktop()->width();
|
|
62 | - int height = QApplication::desktop()->height();
|
|
63 | - int depth = QApplication::desktop()->depth();
|
|
71 | + QScreen *screen = QApplication::screens().value(GetIndex());
|
|
72 | + |
|
73 | + int width = screen->size().width();
|
|
74 | + int height = screen->size().height();
|
|
75 | + int depth = screen->depth();
|
|
64 | 76 | |
65 | 77 | return wxVideoMode( width, height, depth );
|
66 | 78 | }
|
... | ... | @@ -91,12 +103,16 @@ wxDisplayImpl *wxDisplayFactoryQt::CreateDisplay(unsigned n) |
91 | 103 | |
92 | 104 | unsigned wxDisplayFactoryQt::GetCount()
|
93 | 105 | {
|
94 | - return QApplication::desktop()->screenCount();
|
|
106 | + return QApplication::screens().size();
|
|
95 | 107 | }
|
96 | 108 | |
97 | 109 | int wxDisplayFactoryQt::GetFromPoint(const wxPoint& pt)
|
98 | 110 | {
|
99 | - return QApplication::desktop()->screenNumber( wxQtConvertPoint( pt ));
|
|
111 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
|
112 | + return QApplication::screens().indexOf(QApplication::screenAt(wxQtConvertPoint(pt)));
|
|
113 | +#else
|
|
114 | + return QApplication::desktop()->screenNumber(wxQtConvertPoint(pt));
|
|
115 | +#endif
|
|
100 | 116 | }
|
101 | 117 | |
102 | 118 | //##############################################################################
|
... | ... | @@ -31,29 +31,29 @@ |
31 | 31 | namespace
|
32 | 32 | {
|
33 | 33 | |
34 | -Qt::AlignmentFlag wxQtConvertTextAlign(wxListColumnFormat align)
|
|
34 | +Qt::Alignment wxQtConvertTextAlign(wxListColumnFormat align)
|
|
35 | 35 | {
|
36 | 36 | switch (align)
|
37 | 37 | {
|
38 | 38 | case wxLIST_FORMAT_LEFT:
|
39 | - return Qt::AlignLeft;
|
|
39 | + return Qt::AlignLeft | Qt::AlignVCenter;
|
|
40 | 40 | case wxLIST_FORMAT_RIGHT:
|
41 | - return Qt::AlignRight;
|
|
41 | + return Qt::AlignRight | Qt::AlignVCenter;
|
|
42 | 42 | case wxLIST_FORMAT_CENTRE:
|
43 | - return Qt::AlignCenter;
|
|
43 | + return Qt::AlignHCenter | Qt::AlignVCenter;
|
|
44 | 44 | }
|
45 | - return Qt::AlignLeft;
|
|
45 | + return Qt::AlignLeft | Qt::AlignVCenter;
|
|
46 | 46 | }
|
47 | 47 | |
48 | 48 | wxListColumnFormat wxQtConvertAlignFlag(int align)
|
49 | 49 | {
|
50 | - switch (align)
|
|
50 | + switch (align & Qt::AlignHorizontal_Mask)
|
|
51 | 51 | {
|
52 | 52 | case Qt::AlignLeft:
|
53 | 53 | return wxLIST_FORMAT_LEFT;
|
54 | 54 | case Qt::AlignRight:
|
55 | 55 | return wxLIST_FORMAT_RIGHT;
|
56 | - case Qt::AlignCenter:
|
|
56 | + case Qt::AlignHCenter:
|
|
57 | 57 | return wxLIST_FORMAT_CENTRE;
|
58 | 58 | }
|
59 | 59 | return wxLIST_FORMAT_LEFT;
|
... | ... | @@ -230,7 +230,7 @@ public: |
230 | 230 | : QVariant();
|
231 | 231 | |
232 | 232 | case Qt::TextAlignmentRole:
|
233 | - return columnItem.m_align;
|
|
233 | + return static_cast<int>(columnItem.m_align);
|
|
234 | 234 | |
235 | 235 | case Qt::CheckStateRole:
|
236 | 236 | return col == 0 && m_listCtrl->HasCheckBoxes()
|
... | ... | @@ -306,7 +306,7 @@ public: |
306 | 306 | return header.m_label;
|
307 | 307 | |
308 | 308 | case Qt::TextAlignmentRole:
|
309 | - return header.m_align;
|
|
309 | + return static_cast<int>(header.m_align);
|
|
310 | 310 | |
311 | 311 | case Qt::DecorationRole:
|
312 | 312 | {
|
... | ... | @@ -647,14 +647,27 @@ public: |
647 | 647 | |
648 | 648 | if ( row == -1 || static_cast<size_t>(row) >= m_rows.size() )
|
649 | 649 | {
|
650 | - m_rows.push_back(RowItem(m_headers.size()));
|
|
650 | + size_t colCount = m_headers.size();
|
|
651 | + RowItem rowItem(colCount);
|
|
652 | + |
|
653 | + for (size_t i = 0; i < colCount; i++)
|
|
654 | + rowItem.m_columns[i].m_align = m_headers[i].m_align;
|
|
655 | + |
|
656 | + m_rows.push_back(rowItem);
|
|
651 | 657 | newRowIndex = m_rows.size() - 1;
|
652 | 658 | }
|
653 | 659 | else
|
654 | 660 | {
|
655 | 661 | std::vector<RowItem>::iterator i = m_rows.begin();
|
656 | 662 | std::advance(i, row);
|
657 | - m_rows.insert(i, RowItem(m_headers.size()));
|
|
663 | + |
|
664 | + size_t colCount = m_headers.size();
|
|
665 | + RowItem rowItem(colCount);
|
|
666 | + |
|
667 | + for (size_t col = 0; col < colCount; col++)
|
|
668 | + rowItem.m_columns[col].m_align = m_headers[col].m_align;
|
|
669 | + |
|
670 | + m_rows.insert(i, rowItem);
|
|
658 | 671 | newRowIndex = row;
|
659 | 672 | }
|
660 | 673 | |
... | ... | @@ -805,7 +818,7 @@ private: |
805 | 818 | struct ColumnItem
|
806 | 819 | {
|
807 | 820 | ColumnItem() :
|
808 | - m_align(Qt::AlignLeft),
|
|
821 | + m_align(Qt::AlignLeft | Qt::AlignVCenter),
|
|
809 | 822 | m_image(-1),
|
810 | 823 | m_selectedImage(-1)
|
811 | 824 | {
|
... | ... | @@ -815,7 +828,7 @@ private: |
815 | 828 | QColor m_backgroundColour;
|
816 | 829 | QColor m_textColour;
|
817 | 830 | QFont m_font;
|
818 | - Qt::AlignmentFlag m_align;
|
|
831 | + Qt::Alignment m_align;
|
|
819 | 832 | int m_image;
|
820 | 833 | int m_selectedImage;
|
821 | 834 | };
|
... | ... | @@ -993,6 +1006,11 @@ public: |
993 | 1006 | if (!current_index.isValid())
|
994 | 1007 | return;
|
995 | 1008 | |
1009 | + // closeEditor can be called through wxQtLineEdit destructor,
|
|
1010 | + // after m_qtEdit in wxTextCtrl has been deleted.
|
|
1011 | + if (!m_itemDelegate.GetEditControl() || m_itemDelegate.GetEditControl()->IsBeingDeleted())
|
|
1012 | + return;
|
|
1013 | + |
|
996 | 1014 | const wxString editedText = m_itemDelegate.GetEditControl()->GetLineText(0);
|
997 | 1015 | |
998 | 1016 | wxListEvent event;
|
... | ... | @@ -1836,14 +1854,33 @@ void wxListCtrl::CheckItem(long item, bool check) |
1836 | 1854 | m_model->CheckItem(item, check);
|
1837 | 1855 | }
|
1838 | 1856 | |
1839 | -void wxListCtrl::SetSingleStyle(long WXUNUSED(style), bool WXUNUSED(add))
|
|
1857 | +void wxListCtrl::SetSingleStyle(long style, bool add)
|
|
1840 | 1858 | {
|
1859 | + long flag = GetWindowStyleFlag();
|
|
1860 | + |
|
1861 | + // Get rid of conflicting styles
|
|
1862 | + if (add)
|
|
1863 | + {
|
|
1864 | + if (style & wxLC_MASK_TYPE)
|
|
1865 | + flag &= ~wxLC_MASK_TYPE;
|
|
1866 | + if (style & wxLC_MASK_ALIGN)
|
|
1867 | + flag &= ~wxLC_MASK_ALIGN;
|
|
1868 | + if (style & wxLC_MASK_SORT)
|
|
1869 | + flag &= ~wxLC_MASK_SORT;
|
|
1870 | + }
|
|
1871 | + |
|
1872 | + if (add)
|
|
1873 | + flag |= style;
|
|
1874 | + else
|
|
1875 | + flag &= ~style;
|
|
1876 | + |
|
1877 | + SetWindowStyleFlag(flag);
|
|
1841 | 1878 | }
|
1842 | 1879 | |
1843 | 1880 | void wxListCtrl::SetWindowStyleFlag(long style)
|
1844 | 1881 | {
|
1845 | 1882 | m_windowStyle = style;
|
1846 | - m_qtTreeWidget->setHeaderHidden((style & wxLC_NO_HEADER) != 0);
|
|
1883 | + m_qtTreeWidget->setHeaderHidden((style & wxLC_NO_HEADER) != 0 || (style & wxLC_REPORT) == 0);
|
|
1847 | 1884 | m_qtTreeWidget->EnableEditLabel((style & wxLC_EDIT_LABELS) != 0);
|
1848 | 1885 | m_qtTreeWidget->setSelectionMode((style & wxLC_SINGLE_SEL) != 0
|
1849 | 1886 | ? QAbstractItemView::SingleSelection
|
... | ... | @@ -1898,9 +1935,8 @@ void wxListCtrl::DoUpdateImages(int which) |
1898 | 1935 | |
1899 | 1936 | if ( imageList )
|
1900 | 1937 | {
|
1901 | - int width, height;
|
|
1902 | - imageList->GetSize(0, width, height);
|
|
1903 | - m_qtTreeWidget->setIconSize(QSize(width, height));
|
|
1938 | + const wxBitmap bitmap = imageList->GetBitmap(0);
|
|
1939 | + m_qtTreeWidget->setIconSize(wxQtConvertSize(bitmap.GetLogicalSize()));
|
|
1904 | 1940 | m_qtTreeWidget->update();
|
1905 | 1941 | }
|
1906 | 1942 | }
|
... | ... | @@ -145,9 +145,8 @@ void wxNotebook::OnImagesChanged() |
145 | 145 | {
|
146 | 146 | wxImageList* const imageList = GetUpdatedImageListFor(this);
|
147 | 147 | |
148 | - int width, height;
|
|
149 | - imageList->GetSize(0, width, height);
|
|
150 | - m_qtTabWidget->setIconSize(QSize(width, height));
|
|
148 | + const wxBitmap bitmap = imageList->GetBitmap(0);
|
|
149 | + m_qtTabWidget->setIconSize(wxQtConvertSize(bitmap.GetLogicalSize()));
|
|
151 | 150 | m_qtTabWidget->update();
|
152 | 151 | }
|
153 | 152 | }
|
... | ... | @@ -36,7 +36,7 @@ public: |
36 | 36 | wxQtSignalHandler(handler)
|
37 | 37 | {
|
38 | 38 | connect(this,
|
39 | - static_cast<void (QButtonGroup::*)(int index)>(&QButtonGroup::buttonClicked),
|
|
39 | + static_cast<void (QButtonGroup::*)(QAbstractButton *)>(&QButtonGroup::buttonClicked),
|
|
40 | 40 | this, &wxQtButtonGroup::buttonClicked);
|
41 | 41 | }
|
42 | 42 | |
... | ... | @@ -46,17 +46,17 @@ public: |
46 | 46 | }
|
47 | 47 | |
48 | 48 | private:
|
49 | - void buttonClicked(int index);
|
|
49 | + void buttonClicked(QAbstractButton *qbutton);
|
|
50 | 50 | };
|
51 | 51 | |
52 | -void wxQtButtonGroup::buttonClicked(int index)
|
|
52 | +void wxQtButtonGroup::buttonClicked(QAbstractButton *qbutton)
|
|
53 | 53 | {
|
54 | 54 | wxRadioBox *handler = GetRadioBox();
|
55 | 55 | if ( handler )
|
56 | 56 | {
|
57 | 57 | wxCommandEvent event( wxEVT_RADIOBOX, handler->GetId() );
|
58 | - event.SetInt(index);
|
|
59 | - event.SetString(wxQtConvertString(button(index)->text()));
|
|
58 | + event.SetInt(buttons().indexOf(qbutton));
|
|
59 | + event.SetString(wxQtConvertString(qbutton->text()));
|
|
60 | 60 | EmitEvent( event );
|
61 | 61 | }
|
62 | 62 | }
|
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include "wx/settings.h"
|
12 | 12 | #include "wx/qt/private/converter.h"
|
13 | 13 | #include <QtGui/QPalette>
|
14 | +#include <QtGui/QScreen>
|
|
14 | 15 | #include <QtWidgets/QApplication>
|
15 | 16 | #include <QtWidgets/QDesktopWidget>
|
16 | 17 | #include <QtWidgets/QStyle>
|
... | ... | @@ -196,10 +197,10 @@ int wxSystemSettingsNative::GetMetric(wxSystemMetric index, const wxWindow* WXUN |
196 | 197 | return QApplication::style()->pixelMetric(QStyle::PM_IconViewIconSize);
|
197 | 198 | |
198 | 199 | case wxSYS_SCREEN_X:
|
199 | - return QApplication::desktop()->screenGeometry().width();
|
|
200 | + return QApplication::primaryScreen()->size().width();
|
|
200 | 201 | |
201 | 202 | case wxSYS_SCREEN_Y:
|
202 | - return QApplication::desktop()->screenGeometry().height();
|
|
203 | + return QApplication::primaryScreen()->size().height();
|
|
203 | 204 | |
204 | 205 | case wxSYS_HSCROLL_Y:
|
205 | 206 | case wxSYS_VSCROLL_X:
|
... | ... | @@ -697,11 +697,16 @@ bool wxTextCtrl::Create(wxWindow *parent, |
697 | 697 | wxTextCtrl::~wxTextCtrl()
|
698 | 698 | {
|
699 | 699 | delete m_qtEdit;
|
700 | + m_qtEdit = nullptr;
|
|
700 | 701 | }
|
701 | 702 | |
702 | 703 | wxSize wxTextCtrl::DoGetBestSize() const
|
703 | 704 | {
|
704 | - return wxTextCtrlBase::DoGetBestSize();
|
|
705 | + if (IsSingleLine())
|
|
706 | + return wxQtConvertSize(m_qtEdit->GetHandle()->sizeHint());
|
|
707 | + |
|
708 | + return wxSize(80,
|
|
709 | + 1 + GetCharHeight() * wxMax(wxMin(GetNumberOfLines(), 10), 2));
|
|
705 | 710 | }
|
706 | 711 | |
707 | 712 | int wxTextCtrl::GetLineLength(long lineNo) const
|
... | ... | @@ -1308,6 +1308,12 @@ void wxTreeCtrl::SetWindowStyleFlag(long styles) |
1308 | 1308 | {
|
1309 | 1309 | wxControl::SetWindowStyleFlag(styles);
|
1310 | 1310 | |
1311 | + m_qtTreeWidget->setEditTriggers(
|
|
1312 | + styles & wxTR_EDIT_LABELS
|
|
1313 | + ? (QTreeWidget::SelectedClicked | QTreeWidget::EditKeyPressed)
|
|
1314 | + : QTreeWidget::NoEditTriggers
|
|
1315 | + );
|
|
1316 | + |
|
1311 | 1317 | m_qtTreeWidget->setSelectionMode(
|
1312 | 1318 | styles & wxTR_MULTIPLE
|
1313 | 1319 | ? QTreeWidget::ExtendedSelection
|
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | |
12 | 12 | #include <QtGui/QPicture>
|
13 | 13 | #include <QtGui/QPainter>
|
14 | +#include <QtGui/QWindow>
|
|
14 | 15 | #include <QtWidgets/QScrollBar>
|
15 | 16 | #include <QtWidgets/QGridLayout>
|
16 | 17 | #include <QtWidgets/QApplication>
|
... | ... | @@ -679,6 +680,32 @@ int wxWindowQt::GetCharWidth() const |
679 | 680 | return ( GetHandle()->fontMetrics().averageCharWidth() );
|
680 | 681 | }
|
681 | 682 | |
683 | +double wxWindowQt::GetContentScaleFactor() const
|
|
684 | +{
|
|
685 | + if (GetHandle())
|
|
686 | + {
|
|
687 | + QWidget* npw = GetHandle()->nativeParentWidget();
|
|
688 | + |
|
689 | + if (npw)
|
|
690 | + {
|
|
691 | + QWindow *win = npw->windowHandle();
|
|
692 | + return win->devicePixelRatio();
|
|
693 | + }
|
|
694 | + }
|
|
695 | + |
|
696 | + return qApp->devicePixelRatio();
|
|
697 | +}
|
|
698 | + |
|
699 | +double wxWindowQt::GetDPIScaleFactor() const
|
|
700 | +{
|
|
701 | + return GetContentScaleFactor();
|
|
702 | +}
|
|
703 | + |
|
704 | +wxSize wxWindowQt::GetDPI() const
|
|
705 | +{
|
|
706 | + return MakeDPIFromScaleFactor(GetDPIScaleFactor());
|
|
707 | +}
|
|
708 | + |
|
682 | 709 | void wxWindowQt::DoGetTextExtent(const wxString& string, int *x, int *y, int *descent,
|
683 | 710 | int *externalLeading, const wxFont *font ) const
|
684 | 711 | {
|
... | ... | @@ -1364,18 +1364,11 @@ TEST_CASE("wxTextCtrl::GetBestSize", "[wxTextCtrl][best-size]") |
1364 | 1364 | s += s;
|
1365 | 1365 | const wxSize sizeVeryLong = getBestSizeFor(s);
|
1366 | 1366 | |
1367 | -#ifndef __WXQT__
|
|
1368 | 1367 | // Control with a few lines of text in it should be taller.
|
1369 | 1368 | CHECK( sizeMedium.y > sizeEmpty.y );
|
1370 | 1369 | |
1371 | 1370 | // And a control with many lines in it should be even more so.
|
1372 | 1371 | CHECK( sizeLong.y > sizeMedium.y );
|
1373 | -#else
|
|
1374 | - // Under wxQt, the multiline textctrl has a fixed calculated best size
|
|
1375 | - // regardless of its content.
|
|
1376 | - CHECK( sizeMedium.y == sizeEmpty.y );
|
|
1377 | - CHECK( sizeLong.y == sizeMedium.y );
|
|
1378 | -#endif
|
|
1379 | 1372 | |
1380 | 1373 | // However there is a cutoff at 10 lines currently, so anything longer than
|
1381 | 1374 | // that should still have the same best size.
|
... | ... | @@ -1839,7 +1839,11 @@ TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]") |
1839 | 1839 | // A bitmap "compatible" with this DC should also use the same scale factor.
|
1840 | 1840 | wxBitmap bmp2(4, 4, dc);
|
1841 | 1841 | CHECK( bmp2.GetScaleFactor() == 2 );
|
1842 | +#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
|
1842 | 1843 | CHECK( bmp2.GetSize() == wxSize(8, 8) );
|
1844 | +#else
|
|
1845 | + CHECK( bmp2.GetSize() == wxSize(4, 4) );
|
|
1846 | +#endif
|
|
1843 | 1847 | |
1844 | 1848 | // A compatible bitmap created from wxImage and this DC should also inherit
|
1845 | 1849 | // the same scale factor, but its size should be still the same as that of
|
1 | +#!/bin/bash
|
|
2 | + |
|
3 | +# Usage example:
|
|
4 | +#
|
|
5 | +# The following command line:
|
|
6 | +# './GenerateBigXRCFile.sh' 2000 >'MyInputFileReferencingManyResources.xrc'
|
|
7 | +# will generate an XRC file referencing 2000 small PNG images.
|
|
8 | +#
|
|
9 | +# Compiling this XRC file using `wxrc` and further compiling the generated C++ source code
|
|
10 | +# can help us tune our code and avoid slow C++ compilation process
|
|
11 | +# (when thousands of input resource files have been given as input).
|
|
12 | + |
|
13 | +function GenerateExampleImages
|
|
14 | +{
|
|
15 | + set -e -o pipefail
|
|
16 | + |
|
17 | + local folder_images='ExampleImages'
|
|
18 | + mkdir -p "${folder_images}/"
|
|
19 | + |
|
20 | + local i
|
|
21 | + local n="${1:-10000}"
|
|
22 | + |
|
23 | + printf '<?xml version="1.0" encoding="UTF-8"?>\n'
|
|
24 | + printf '<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">\n'
|
|
25 | + for ((i = 0; i < n; ++i)); do
|
|
26 | + local pathname_image; printf -v pathname_image "%s/Example_%04Xh.png" "${folder_images}" "$((i))"
|
|
27 | + |
|
28 | + rm -f "${pathname_image}"
|
|
29 | + printf >>"${pathname_image}" \
|
|
30 | + '%s' \
|
|
31 | + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" \
|
|
32 | + "\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\x00\x00\x00\x90\x91\x68" \
|
|
33 | + "\x36\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0E\xC4\x00\x00\x0E" \
|
|
34 | + "\xC4\x01\x95\x2B\x0E\x1B\x00\x00\x00\x1A\x49\x44\x41\x54\x28\xCF" \
|
|
35 | + "\x63\x6C\x60\xF8\xCF\x40\x0A\x60\x62\x20\x11\x8C\x6A\x18\xD5\x30" \
|
|
36 | + "\x74\x34\x00\x00\xC5\xBF\x01\x9F\x22\x91\xFF\xBD\x00\x00\x00\x00"
|
|
37 | + "\x49\x45\x4E\x44\xAE\x42\x60\x82"
|
|
38 | + |
|
39 | + printf ' <object class="wxBitmap" name="Cat_%04Xh">%s</object>\n' "$((i))" "${pathname_image}"
|
|
40 | + done
|
|
41 | + printf '</resource>\n'
|
|
42 | +}
|
|
43 | + |
|
44 | +GenerateExampleImages "$@" |
... | ... | @@ -664,13 +664,30 @@ void XmlResApp::MakePackageCPP(const wxArrayString& flist) |
664 | 664 | "#include <wx/xrc/xmlres.h>\n"
|
665 | 665 | "#include <wx/xrc/xh_all.h>\n"
|
666 | 666 | "\n"
|
667 | -"#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805\n"
|
|
668 | -" #define XRC_ADD_FILE(name, data, size, mime) \\\n"
|
|
669 | -" wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)\n"
|
|
670 | -"#else\n"
|
|
671 | -" #define XRC_ADD_FILE(name, data, size, mime) \\\n"
|
|
672 | -" wxMemoryFSHandler::AddFile(name, data, size)\n"
|
|
673 | -"#endif\n"
|
|
667 | + |
|
668 | +/*
|
|
669 | + Define a helper function to ensure that conversions from `const wxChar *` to
|
|
670 | + `const wxString &` are centralized in a single place, as this results in
|
|
671 | + much faster compilation time and much smaller generated machine code.
|
|
672 | + |
|
673 | + For example, for 10,000 binary resources replacing the previously used macro
|
|
674 | + with this function results in the following changes:
|
|
675 | + |
|
676 | + Compiler (with "-g -O2") | Time (seconds) | RAM (KiB) | Machine code (bytes)
|
|
677 | + -------------------------| -------------- | --------- | ---------------------
|
|
678 | + g++-11 before | 158 | 3,316,384 | 1,821,235
|
|
679 | + g++-11 now | 16 | 718,080 | 271,987
|
|
680 | + clang++-14 before | 158 | 5,263,864 | 2,820,830
|
|
681 | + clang++-14 now | 5 | 544,144 | 271,080
|
|
682 | +*/
|
|
683 | +"void XRC_ADD_FILE(const wxChar *filename, const void *binarydata, size_t size, const wxChar *mimetype)\n"
|
|
684 | +"{\n"
|
|
685 | +" #if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805\n"
|
|
686 | +" return wxMemoryFSHandler::AddFileWithMimeType(filename, binarydata, size, mimetype);\n"
|
|
687 | +" #else\n"
|
|
688 | +" return wxMemoryFSHandler::AddFile(filename, binarydata, size);\n"
|
|
689 | +" #endif\n"
|
|
690 | +"}\n"
|
|
674 | 691 | "\n");
|
675 | 692 | |
676 | 693 | for (i = 0; i < flist.GetCount(); i++)
|
—
View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help