From d2b3484e602651e89443722fe7d46c902629b05b Mon Sep 17 00:00:00 2001 From: Jouk Date: Fri, 8 Jul 2016 15:15:27 +0200 Subject: [PATCH 01/16] g_log_set_default_handler not avaliable for gtk1 --- tests/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test.cpp b/tests/test.cpp index b9f23e07b6..2a0c38fc22 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -633,7 +633,7 @@ bool TestApp::OnInit() Connect(wxEVT_IDLE, wxIdleEventHandler(TestApp::OnIdle)); -#ifdef __WXGTK__ +#ifdef __WXGTK20__ g_log_set_default_handler(wxTestGLogHandler, NULL); #endif // __WXGTK__ From 4f1e3b7172e3e6bda17bb28f7d7e5ca52935722a Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 8 Jul 2016 19:44:32 +0200 Subject: [PATCH 02/16] Fixed setting colours of wxPGProperty When wxPGProperty's text or background colours are modified with dedicated wxPropertyGridInterface utility functions (SetPropertyBackgroundColour, SetPropertyTextColour, SetPropertyColoursToDefault) then it is enough to redraw the property with new colours because its internal state remains unmodified and full refreshing is not necessary. Closes #17588 --- interface/wx/propgrid/property.h | 19 ++++++++++-- interface/wx/propgrid/propgridiface.h | 43 ++++++++++++++++++++++----- src/propgrid/propgridiface.cpp | 33 ++++++++++++++++++-- 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index 8dfb65ec18..6de57de2c7 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -1664,6 +1664,10 @@ public: Default is wxPG_RECURSE which causes colour to be set recursively. Omit this flag to only set colour for the property in question and not any of its children. + + @remarks + Unlike wxPropertyGridInterface::SetPropertyBackgroundColour(), + this does not automatically update the display. */ void SetBackgroundColour( const wxColour& colour, int flags = wxPG_RECURSE ); @@ -1753,8 +1757,11 @@ public: /** Sets property's label. - @remarks Properties under same parent may have same labels. However, - property names must still remain unique. + @remarks + - Properties under same parent may have same labels. However, + property names must still remain unique. + - Unlike wxPropertyGridInterface::SetPropertyLabel(), + this does not automatically update the display. */ void SetLabel( const wxString& label ); @@ -1796,6 +1803,10 @@ public: Default is wxPG_RECURSE which causes colour to be set recursively. Omit this flag to only set colour for the property in question and not any of its children. + + @remarks + Unlike wxPropertyGridInterface::SetPropertyTextColour(), + this does not automatically update the display. */ void SetTextColour( const wxColour& colour, int flags = wxPG_RECURSE ); @@ -1807,6 +1818,10 @@ public: Default is wxPG_RECURSE which causes colours to be set recursively. Omit this flag to only set colours for the property in question and not any of its children. + + @remarks + Unlike wxPropertyGridInterface::SetPropertyColoursToDefault(), + this does not automatically update the display. */ void SetDefaultColours(int flags = wxPG_RECURSE); diff --git a/interface/wx/propgrid/propgridiface.h b/interface/wx/propgrid/propgridiface.h index b5931ea2d7..855d8ae2a8 100644 --- a/interface/wx/propgrid/propgridiface.h +++ b/interface/wx/propgrid/propgridiface.h @@ -156,6 +156,9 @@ public: /** Disables a property. + @remarks + Property is refreshed with new settings. + @see EnableProperty(), wxPGProperty::Enable() */ bool DisableProperty( wxPGPropArg id ); @@ -176,6 +179,9 @@ public: @param enable If @false, property is disabled instead. + @remarks + Property is refreshed with new settings. + @see wxPGProperty::Enable() */ bool EnableProperty( wxPGPropArg id, bool enable = true ); @@ -603,6 +609,9 @@ public: /** Disables (limit = @true) or enables (limit = @false) wxTextCtrl editor of a property, if it is not the sole mean to edit the value. + + @remarks + Property is refreshed with new settings. */ void LimitPropertyEditing( wxPGPropArg id, bool limit = true ); @@ -768,8 +777,10 @@ public: Optional. Use wxPG_RECURSE to set the attribute to child properties recursively. - @remarks Setting attribute's value to wxNullVariant will simply remove it - from property's set of attributes. + @remarks + - Setting attribute's value to wxNullVariant will simply remove it + from property's set of attributes. + - Property is refreshed with new settings. */ void SetPropertyAttribute( wxPGPropArg id, const wxString& attrName, wxVariant value, long argFlags = 0 ); @@ -778,11 +789,14 @@ public: Sets property attribute for all applicapple properties. Be sure to use this method only after all properties have been added to the grid. + + @remarks + Properties are refreshed with new settings. */ void SetPropertyAttributeAll( const wxString& attrName, wxVariant value ); /** - Sets background colour of a property. + Sets background colour of given property. @param id Property name or pointer. @@ -794,6 +808,10 @@ public: Default is wxPG_RECURSE which causes colour to be set recursively. Omit this flag to only set colour for the property in question and not any of its children. + + @remarks + - If category is tried to set recursively, only its children are affected. + - Property is redrawn with new colour. */ void SetPropertyBackgroundColour( wxPGPropArg id, const wxColour& colour, @@ -823,12 +841,17 @@ public: /** Resets text and background colours of given property. + @param id Property name or pointer. @param flags Default is wxPG_DONT_RECURSE which causes colour to be reset only for the property in question (for backward compatibility). + + @remarks + - If category is tried to set recursively, only its children are affected. + - Property is redrawn with new colours. */ void SetPropertyColoursToDefault(wxPGPropArg id, int flags = wxPG_DONT_RECURSE); @@ -887,8 +910,10 @@ public: By default changes are applied recursively. Set this parameter to wxPG_DONT_RECURSE to prevent this. - @remarks This is mainly for use with textctrl editor. Only some other - editors fully support it. + @remarks + - This is mainly for use with textctrl editor. Only some other + editors fully support it. + - Property is refreshed with new settings. */ void SetPropertyReadOnly( wxPGPropArg id, bool set = true, int flags = wxPG_RECURSE ); @@ -936,18 +961,22 @@ public: /** - Sets text colour of a property. + Sets text colour of given property. @param id Property name or pointer. @param colour - New background colour. + New text colour. @param flags Default is wxPG_RECURSE which causes colour to be set recursively. Omit this flag to only set colour for the property in question and not any of its children. + + @remarks + - If category is tried to set recursively, only its children are affected. + - Property is redrawn with new colour. */ void SetPropertyTextColour( wxPGPropArg id, const wxColour& colour, diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 9394649a84..85e8f95c2a 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -669,7 +669,16 @@ wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id, { wxPG_PROP_ARG_CALL_PROLOG() p->SetBackgroundColour(colour, flags); - RefreshProperty(p); + + // Redraw the control + wxPropertyGrid* pg = m_pState->GetGrid(); + if ( pg == p->GetGrid() ) + { + if ( flags & wxPG_RECURSE ) + pg->DrawItemAndChildren(p); + else + pg->DrawItem(p); + } } // ----------------------------------------------------------------------- @@ -680,7 +689,16 @@ void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id, { wxPG_PROP_ARG_CALL_PROLOG() p->SetTextColour(colour, flags); - RefreshProperty(p); + + // Redraw the control + wxPropertyGrid* pg = m_pState->GetGrid(); + if ( pg == p->GetGrid() ) + { + if ( flags & wxPG_RECURSE ) + pg->DrawItemAndChildren(p); + else + pg->DrawItem(p); + } } // ----------------------------------------------------------------------- @@ -695,8 +713,17 @@ void wxPropertyGridInterface::SetPropertyColoursToDefault(wxPGPropArg id) void wxPropertyGridInterface::SetPropertyColoursToDefault(wxPGPropArg id, int flags) { wxPG_PROP_ARG_CALL_PROLOG() - p->SetDefaultColours(flags); + + // Redraw the control + wxPropertyGrid* pg = m_pState->GetGrid(); + if ( pg == p->GetGrid() ) + { + if ( flags & wxPG_RECURSE ) + pg->DrawItemAndChildren(p); + else + pg->DrawItem(p); + } } // ----------------------------------------------------------------------- From 04ba48e6855ed4501bcf94bc322cd1025d7cdbc9 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 8 Jul 2016 19:47:24 +0200 Subject: [PATCH 03/16] Use enum instead of macro to represent flag used in wxPGPropertyGridInterface and wxPGProperty methods. Use enums to represent all flags. --- include/wx/propgrid/propgriddefs.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/wx/propgrid/propgriddefs.h b/include/wx/propgrid/propgriddefs.h index cd68322810..71aca25211 100644 --- a/include/wx/propgrid/propgriddefs.h +++ b/include/wx/propgrid/propgriddefs.h @@ -319,6 +319,8 @@ WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(wxObject*, wxArrayPGObject, enum wxPG_GETPROPERTYVALUES_FLAGS { +/** Flags for wxPropertyGrid::SetPropertyAttribute() etc */ +wxPG_DONT_RECURSE = 0x00000000, /** Flags for wxPropertyGridInterface::GetPropertyValues */ wxPG_KEEP_STRUCTURE = 0x00000010, @@ -339,12 +341,8 @@ wxPG_FORCE = 0x00000100, Sorting done by wxPG_AUTO_SORT option uses this. */ wxPG_SORT_TOP_LEVEL_ONLY = 0x00000200 - }; -/** Flags for wxPropertyGrid::SetPropertyAttribute() etc */ -#define wxPG_DONT_RECURSE 0x00000000 - // ----------------------------------------------------------------------- // Misc. argument flags. From c910085507d5ffc9926c0f159bc1d204b36511e7 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 8 Jul 2016 19:49:03 +0200 Subject: [PATCH 04/16] Update documentation of some flags used by wxPropertyGridInterface methods. --- include/wx/propgrid/propgriddefs.h | 26 ++++++----- interface/wx/propgrid/propgridiface.h | 64 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/include/wx/propgrid/propgriddefs.h b/include/wx/propgrid/propgriddefs.h index 71aca25211..6987755922 100644 --- a/include/wx/propgrid/propgriddefs.h +++ b/include/wx/propgrid/propgriddefs.h @@ -317,29 +317,35 @@ WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(wxObject*, wxArrayPGObject, // ----------------------------------------------------------------------- -enum wxPG_GETPROPERTYVALUES_FLAGS +enum wxPG_PROPERTYVALUES_FLAGS { -/** Flags for wxPropertyGrid::SetPropertyAttribute() etc */ +// Flag for wxPropertyGridInterface::SetProperty* functions, +// wxPropertyGridInterface::HideProperty(), etc. +// Apply changes only for the property in question. wxPG_DONT_RECURSE = 0x00000000, -/** Flags for wxPropertyGridInterface::GetPropertyValues */ +// Flag for wxPropertyGridInterface::GetPropertyValues(). +// Use this flag to retain category structure; each sub-category +// will be its own wxVariantList of wxVariant. wxPG_KEEP_STRUCTURE = 0x00000010, -/** Flags for wxPropertyGrid::SetPropertyAttribute() etc */ +// Flag for wxPropertyGridInterface::SetProperty* functions, +// wxPropertyGridInterface::HideProperty(), etc. +// Apply changes recursively for the property and all its children. wxPG_RECURSE = 0x00000020, -/** Include attributes for GetPropertyValues. */ +// Flag for wxPropertyGridInterface::GetPropertyValues(). +// Use this flag to include property attributes as well. wxPG_INC_ATTRIBUTES = 0x00000040, -/** Used when first starting recursion. */ +// Used when first starting recursion. wxPG_RECURSE_STARTS = 0x00000080, -/** Force value change. */ +// Force value change. wxPG_FORCE = 0x00000100, -/** Only sort categories and their immediate children. - Sorting done by wxPG_AUTO_SORT option uses this. -*/ +// Only sort categories and their immediate children. +// Sorting done by wxPG_AUTO_SORT option uses this. wxPG_SORT_TOP_LEVEL_ONLY = 0x00000200 }; diff --git a/interface/wx/propgrid/propgridiface.h b/interface/wx/propgrid/propgridiface.h index 855d8ae2a8..77c850bd47 100644 --- a/interface/wx/propgrid/propgridiface.h +++ b/interface/wx/propgrid/propgridiface.h @@ -6,6 +6,70 @@ ///////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------- +/** + @section propgrid_property_values_attributes wxPropertyGrid Property Values Attribute Identifiers + + Many wxPropertyGridInterface and wxPropertyGrid methods to set property + value or to modify its state use these flags to specify additional details + of the operation. + + @{ +*/ +enum wxPG_PROPERTYVALUES_FLAGS +{ +/** + Flag for wxPropertyGridInterface::SetProperty* functions, + wxPropertyGridInterface::HideProperty(), etc. + Apply changes only for the property in question. + @hideinitializer +*/ +wxPG_DONT_RECURSE = 0x00000000, + +/** + Flag for wxPropertyGridInterface::GetPropertyValues(). + Use this flag to retain category structure; each sub-category + will be its own wxVariantList of wxVariant. + @hideinitializer +*/ +wxPG_KEEP_STRUCTURE = 0x00000010, + +/** + Flag for wxPropertyGridInterface::SetProperty* functions, + wxPropertyGridInterface::HideProperty(), etc. + Apply changes recursively for the property and all its children. + @hideinitializer +*/ +wxPG_RECURSE = 0x00000020, + +/** + Flag for wxPropertyGridInterface::GetPropertyValues(). + Use this flag to include property attributes as well. + @hideinitializer +*/ +wxPG_INC_ATTRIBUTES = 0x00000040, + +/** + Used when first starting recursion. + @hideinitializer +*/ +wxPG_RECURSE_STARTS = 0x00000080, + +/** + Force value change. + @hideinitializer +*/ +wxPG_FORCE = 0x00000100, + +/** + Only sort categories and their immediate children. + Sorting done by wxPG_AUTO_SORT option uses this. + @hideinitializer +*/ +wxPG_SORT_TOP_LEVEL_ONLY = 0x00000200 +}; + +/** @} +*/ /** @class wxPropertyGridInterface From 9be1251f020a6708112189e7e2c8b0ccec1b8608 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 8 Jul 2016 19:51:02 +0200 Subject: [PATCH 05/16] Modified methods used to set/unset wxPGProperty as read-only and to hide/show it. If there is requested to set/unset a single property (without recursion) as a read-only (wxPropertyGridInterface::SetPropertyReadOnly) or to hide/show it (wxPropertyGridInterface::HideProperty) then first check if property is already in the requested state and if so do nothing. This prevents from unneeded refreshing of the display. --- src/propgrid/propgridiface.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 85e8f95c2a..52c10de16c 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -279,9 +279,17 @@ void wxPropertyGridInterface::SetPropertyReadOnly( wxPGPropArg id, bool set, int wxPG_PROP_ARG_CALL_PROLOG() if ( flags & wxPG_RECURSE ) + { p->SetFlagRecursively(wxPG_PROP_READONLY, set); + } else + { + // Do nothing if flag is already set. + if ( p->HasFlag(wxPG_PROP_READONLY) ) + return; + p->ChangeFlag(wxPG_PROP_READONLY, set); + } wxPropertyGridPageState* state = p->GetParentState(); if( state ) @@ -557,6 +565,15 @@ bool wxPropertyGridInterface::HideProperty( wxPGPropArg id, bool hide, int flags { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) + // Do nothing if single property is already hidden/visible as requested. + if ( !(flags & wxPG_RECURSE) ) + { + if ( hide && p->HasFlag(wxPG_PROP_HIDDEN) ) + return false; + if ( !hide && !p->HasFlag(wxPG_PROP_HIDDEN) ) + return false; + } + wxPropertyGrid* pg = m_pState->GetGrid(); if ( pg == p->GetGrid() ) From c08b8c6f6d126647b8c7163367c93d3fb9d3c3fc Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 8 Jul 2016 19:51:58 +0200 Subject: [PATCH 06/16] Fixed minor typo in comment. --- include/wx/propgrid/property.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index 35b4451a2c..4d3b6f002f 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -1527,8 +1527,8 @@ public: // Hides or reveals the property. // hide - true for hide, false for reveal. - // flags - By default changes are applied recursively. Set this paramter - // wxPG_DONT_RECURSE to prevent this. + // flags - By default changes are applied recursively. Set this + // parameter to wxPG_DONT_RECURSE to prevent this. bool Hide( bool hide, int flags = wxPG_RECURSE ); // Returns true if property has visible children. From fa54e1af158e2cbe5014efefddffd6c2704bb9bf Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Fri, 8 Jul 2016 22:57:27 -0700 Subject: [PATCH 07/16] Be more conservative in avoiding Cairo's maximum coordinate limit. Fixes wxGCDC::Clear(). See #17584 --- src/common/dcgraph.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 90f856609a..d42a4f4659 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -1151,9 +1151,10 @@ void wxGCDCImpl::Clear(void) wxCompositionMode formerMode = m_graphicContext->GetCompositionMode(); m_graphicContext->SetCompositionMode(wxCOMPOSITION_SOURCE); // maximum positive coordinate Cairo can handle is 2^23 - 1 + // Use a value slightly less than this to be sure we avoid the limit DoDrawRectangle( DeviceToLogicalX(0), DeviceToLogicalY(0), - DeviceToLogicalXRel(0x007fffff), DeviceToLogicalYRel(0x007fffff)); + DeviceToLogicalXRel(0x800000 - 64), DeviceToLogicalYRel(0x800000 - 64)); m_graphicContext->SetCompositionMode(formerMode); m_graphicContext->SetPen( m_pen ); m_graphicContext->SetBrush( m_brush ); From fc0108ce71c870059271a7bb1c56e5a91c8c7746 Mon Sep 17 00:00:00 2001 From: Damien Ruscoe Date: Sat, 9 Jul 2016 15:32:34 +0200 Subject: [PATCH 08/16] Hide empty wxCheckBoxes in wxGTK to fix display problem Focus rectangle was still drawn around the label when it was empty with some themes, so hide it completely to ensure this doesn't happen. Closes #17443. --- docs/changes.txt | 1 + src/gtk/checkbox.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index cba00d6460..1b8ee90d70 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -101,6 +101,7 @@ wxGTK: - Support background colour in wxDataViewCtrl attributes. - Improve wxSpinCtrl best size calculation. - Implement support for icon locations in wxMimeTypesManager (Hanmac). +- Cosmetic fix for empty wxCheckBoxes display (Chuddah). wxMSW: diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index 166d37cf02..997f81fb55 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -204,6 +204,13 @@ void wxCheckBox::SetLabel( const wxString& label ) { wxCHECK_RET( m_widgetLabel != NULL, wxT("invalid checkbox") ); + // If we don't hide the empty label, in some themes a focus rectangle is + // still drawn around it and this looks out of place. + if ( label.empty() ) + gtk_widget_hide(m_widgetLabel); + else + gtk_widget_show(m_widgetLabel); + // save the label inside m_label in case user calls GetLabel() later wxControl::SetLabel(label); From 53230aaf4d3347d6b4893e0f71eb0c1a35df0af4 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 9 Jul 2016 22:50:27 +0200 Subject: [PATCH 09/16] Fixed retrieving clipping box for transformed wxDC Because wxDC can be the subject of geometric transformations (like translation, scaling) so we cannot assume in the calculations of the clipping box that DC origin is always at (0,0) and its logical size is the same as physical size. To get correct result we have to use logical coordinates of wxDC area in all clipping box calculations. --- include/wx/dc.h | 8 ++++---- src/common/dcbase.cpp | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/wx/dc.h b/include/wx/dc.h index ac0f97d6ea..c61498724f 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -449,13 +449,13 @@ public: DoGetSize(&dcWidth, &dcHeight); if ( x ) - *x = m_clipping ? m_clipX1 : 0; + *x = m_clipping ? m_clipX1 : DeviceToLogicalX(0); if ( y ) - *y = m_clipping ? m_clipY1 : 0; + *y = m_clipping ? m_clipY1 : DeviceToLogicalY(0); if ( w ) - *w = m_clipping ? m_clipX2 - m_clipX1 : dcWidth; + *w = m_clipping ? m_clipX2 - m_clipX1 : DeviceToLogicalXRel(dcWidth); if ( h ) - *h = m_clipping ? m_clipY2 - m_clipY1 : dcHeight; + *h = m_clipping ? m_clipY2 - m_clipY1 : DeviceToLogicalYRel(dcHeight); } virtual void DestroyClippingRegion() { ResetClipping(); } diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index d298ad300c..427955aca2 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -387,7 +387,8 @@ void wxDCImpl::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) // of required clipping box and DC surface. int dcWidth, dcHeight; DoGetSize(&dcWidth, &dcHeight); - wxRect dcRect(wxSize(dcWidth, dcHeight)); + wxRect dcRect(DeviceToLogicalX(0), DeviceToLogicalY(0), + DeviceToLogicalXRel(dcWidth), DeviceToLogicalYRel(dcHeight)); clipRegion = dcRect.Intersect(newRegion); m_clipping = true; From 2b7aab70fff3933ffaad18c71e05e47eb93a05a3 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 9 Jul 2016 22:56:55 +0200 Subject: [PATCH 10/16] Added tests to check setting of clipping region for transformed wxDC/wxGCDC. In these tests clipping region is set for transformed wxDC/wxGCDC (with changed device origin, logical origin and scale) to check if all these transformations are taken into account in the clipping box calculations. --- tests/graphics/clippingbox.cpp | 81 +++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/tests/graphics/clippingbox.cpp b/tests/graphics/clippingbox.cpp index 3cd9cf58a0..d145ebd4d9 100644 --- a/tests/graphics/clippingbox.cpp +++ b/tests/graphics/clippingbox.cpp @@ -27,7 +27,7 @@ // test class // ---------------------------------------------------------------------------- -static const wxSize s_dcSize(100, 105); +static const wxSize s_dcSize(100, 120); static const wxColour s_bgColour(*wxWHITE); // colour to draw outside clipping box static const wxColour s_fgColour(*wxGREEN); // colour to draw inside clipping box @@ -52,12 +52,14 @@ private: protected: void InitialState(); + void InitialStateWithTransformedDC(); void OneRegion(); void OneLargeRegion(); void OneOuterRegion(); void OneRegionNegDim(); void OneRegionAndReset(); void OneRegionAndEmpty(); + void OneRegionWithTransformedDC(); void TwoRegionsOverlapping(); void TwoRegionsOverlappingNegDim(); void TwoRegionsNonOverlapping(); @@ -100,12 +102,14 @@ public: private: CPPUNIT_TEST_SUITE( ClippingBoxTestCaseDC ); CPPUNIT_TEST( InitialState ); + CPPUNIT_TEST( InitialStateWithTransformedDC ); CPPUNIT_TEST( OneRegion ); CPPUNIT_TEST( OneLargeRegion ); CPPUNIT_TEST( OneOuterRegion ); CPPUNIT_TEST( OneRegionNegDim ); CPPUNIT_TEST( OneRegionAndReset ); CPPUNIT_TEST( OneRegionAndEmpty ); + CPPUNIT_TEST( OneRegionWithTransformedDC ); CPPUNIT_TEST( TwoRegionsOverlapping ); CPPUNIT_TEST( TwoRegionsOverlappingNegDim ); CPPUNIT_TEST( TwoRegionsNonOverlapping ); @@ -161,12 +165,14 @@ public: private: CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDC ); CPPUNIT_TEST( InitialState ); + CPPUNIT_TEST( InitialStateWithTransformedDC ); CPPUNIT_TEST( OneRegion ); CPPUNIT_TEST( OneLargeRegion ); CPPUNIT_TEST( OneOuterRegion ); CPPUNIT_TEST( OneRegionNegDim ); CPPUNIT_TEST( OneRegionAndReset ); CPPUNIT_TEST( OneRegionAndEmpty ); + CPPUNIT_TEST( OneRegionWithTransformedDC ); CPPUNIT_TEST( TwoRegionsOverlapping ); CPPUNIT_TEST( TwoRegionsOverlappingNegDim ); CPPUNIT_TEST( TwoRegionsNonOverlapping ); @@ -208,12 +214,14 @@ public: private: CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGDIPlus ); CPPUNIT_TEST( InitialState ); + CPPUNIT_TEST( InitialStateWithTransformedDC ); CPPUNIT_TEST( OneRegion ); CPPUNIT_TEST( OneLargeRegion ); CPPUNIT_TEST( OneOuterRegion ); CPPUNIT_TEST( OneRegionNegDim ); CPPUNIT_TEST( OneRegionAndReset ); CPPUNIT_TEST( OneRegionAndEmpty ); + CPPUNIT_TEST( OneRegionWithTransformedDC ); CPPUNIT_TEST( TwoRegionsOverlapping ); CPPUNIT_TEST( TwoRegionsOverlappingNegDim ); CPPUNIT_TEST( TwoRegionsNonOverlapping ); @@ -259,12 +267,14 @@ public: private: CPPUNIT_TEST_SUITE( ClippingBoxTestCaseDirect2D ); CPPUNIT_TEST( InitialState ); + CPPUNIT_TEST( InitialStateWithTransformedDC ); CPPUNIT_TEST( OneRegion ); CPPUNIT_TEST( OneLargeRegion ); CPPUNIT_TEST( OneOuterRegion ); CPPUNIT_TEST( OneRegionNegDim ); CPPUNIT_TEST( OneRegionAndReset ); CPPUNIT_TEST( OneRegionAndEmpty ); + CPPUNIT_TEST( OneRegionWithTransformedDC ); CPPUNIT_TEST( TwoRegionsOverlapping ); CPPUNIT_TEST( TwoRegionsOverlappingNegDim ); CPPUNIT_TEST( TwoRegionsNonOverlapping ); @@ -302,12 +312,14 @@ public: private: CPPUNIT_TEST_SUITE( ClippingBoxTestCaseCairo ); CPPUNIT_TEST( InitialState ); + CPPUNIT_TEST( InitialStateWithTransformedDC ); CPPUNIT_TEST( OneRegion ); CPPUNIT_TEST( OneLargeRegion ); CPPUNIT_TEST( OneOuterRegion ); CPPUNIT_TEST( OneRegionNegDim ); CPPUNIT_TEST( OneRegionAndReset ); CPPUNIT_TEST( OneRegionAndEmpty ); + CPPUNIT_TEST( OneRegionWithTransformedDC ); CPPUNIT_TEST( TwoRegionsOverlapping ); CPPUNIT_TEST( TwoRegionsOverlappingNegDim ); CPPUNIT_TEST( TwoRegionsNonOverlapping ); @@ -367,17 +379,26 @@ void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height) msg = msgDim; } + // We will examine pixels directly in the underlying bitmap + // so we need to get device coordinates of examined area. + x = m_dc->LogicalToDeviceX(x); + y = m_dc->LogicalToDeviceY(y); + width = m_dc->LogicalToDeviceXRel(width); + height = m_dc->LogicalToDeviceYRel(height); + // Update wxDC contents. FlushDC(); // Check whether diagonal corners of the clipping box // are actually drawn at the edge of the clipping region. #if wxUSE_IMAGE - // For some renderers is's not possible to get pixels + // For some renderers it's not possible to get pixels // value from wxDC so we would have to examine pixels // in the underlying bitmap. wxImage img; img = m_bmp.ConvertToImage(); +#else + return; #endif // wxUSE_IMAGE // Check area near the top-left corner @@ -394,18 +415,15 @@ void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height) for( int px = xmin; px <= xmax; px++ ) { wxColour c; - if ( !m_dc->GetPixel(px, py, &c) ) - { #if wxUSE_IMAGE - unsigned char r = img.GetRed(px, py); - unsigned char g = img.GetGreen(px, py); - unsigned char b = img.GetBlue(px, py); - c.Set(r, g, b); + unsigned char r = img.GetRed(px, py); + unsigned char g = img.GetGreen(px, py); + unsigned char b = img.GetBlue(px, py); + c.Set(r, g, b); #else - // We cannot get pixel value - break; + // We cannot get pixel value + break; #endif // wxUSE_IMAGE / !wxUSE_IMAGE - } wxString msgColour; if ( px >= x && px <= x + (width-1) && @@ -458,18 +476,15 @@ void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height) for( int px = xmin; px <= xmax; px++ ) { wxColour c; - if ( !m_dc->GetPixel(px, py, &c) ) - { #if wxUSE_IMAGE - unsigned char r = img.GetRed(px, py); - unsigned char g = img.GetGreen(px, py); - unsigned char b = img.GetBlue(px, py); - c.Set(r, g, b); + unsigned char r = img.GetRed(px, py); + unsigned char g = img.GetGreen(px, py); + unsigned char b = img.GetBlue(px, py); + c.Set(r, g, b); #else - // We cannot get pixel value - break; + // We cannot get pixel value + break; #endif // wxUSE_IMAGE / !wxUSE_IMAGE - } wxString msgColour; if ( px >= x && px <= x + (width-1) && @@ -525,6 +540,18 @@ void ClippingBoxTestCaseBase::InitialState() CheckBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight()); } +void ClippingBoxTestCaseBase::InitialStateWithTransformedDC() +{ + // Initial clipping box with transformed DC. + m_dc->SetDeviceOrigin(10, 15); + m_dc->SetUserScale(0.5, 1.5); + m_dc->SetLogicalScale(4.0, 2.0); + m_dc->SetLogicalOrigin(-15, -20); + m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID)); + m_dc->Clear(); + CheckBox(-20, -25, 50, 40); +} + void ClippingBoxTestCaseBase::OneRegion() { // Setting one clipping box inside DC area. @@ -587,6 +614,20 @@ void ClippingBoxTestCaseBase::OneRegionAndEmpty() CheckBox(0, 0, 0, 0); } +void ClippingBoxTestCaseBase::OneRegionWithTransformedDC() +{ + // Setting one clipping box inside DC area + // with applied some transformations. + m_dc->SetDeviceOrigin(10, 15); + m_dc->SetUserScale(0.5, 1.5); + m_dc->SetLogicalScale(4.0, 2.0); + m_dc->SetLogicalOrigin(-15, -20); + m_dc->SetClippingRegion(-10, -20, 80, 75); + m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID)); + m_dc->Clear(); + CheckBox(-10, -20, 40, 35); +} + void ClippingBoxTestCaseBase::TwoRegionsOverlapping() { // Setting one clipping box and next another box (partially overlapping). From 13f9789996672cb48d5e88b03db0273522ab8273 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 9 Jul 2016 23:32:23 +0200 Subject: [PATCH 11/16] Fixed clearing wxWindowDC, wxMemoryDC for wxMSW. Current implementation suffers for two issues: 1. Because wxClientDC and wxWindowDC are not distinguished in wxMSWDCImpl::Clear and in both cases DC coordinates are obtained with GetClientRect() Win API what leads to this that for wxWindowDC the entire area is not cleared. 2. Translations like moving logical origin or scaling are not taken into account in wxMemoryDC coordinates calculations (only device origin is included) so for transformed DC calculated coordinates are invalid and finally the entire area is not cleared. To fix these issues we can use GetClipBox() Win API to obtain actual logical coordinates of the clipping box (with all translations and scaling already included) and this way we can avoid using separate methods of retrieving coordinates for wxClientDC, wxWindowDC and wxMemoryDC. --- src/msw/dc.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 7207c2311f..186db72bb0 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -709,30 +709,19 @@ int wxMSWDCImpl::GetDepth() const void wxMSWDCImpl::Clear() { - RECT rect; - if (m_window) - { - GetClientRect((HWND) m_window->GetHWND(), &rect); - } - else + if ( !m_window ) { // No, I think we should simply ignore this if printing on e.g. // a printer DC. // wxCHECK_RET( m_selectedBitmap.IsOk(), wxT("this DC can't be cleared") ); if (!m_selectedBitmap.IsOk()) return; - - rect.left = rect.top = 0; - rect.right = m_selectedBitmap.GetWidth(); - rect.bottom = m_selectedBitmap.GetHeight(); } - ::OffsetRect(&rect, -m_deviceOriginX, -m_deviceOriginY); - - (void) ::SetMapMode(GetHdc(), MM_TEXT); - DWORD colour = ::GetBkColor(GetHdc()); HBRUSH brush = ::CreateSolidBrush(colour); + RECT rect; + ::GetClipBox(GetHdc(), &rect); ::FillRect(GetHdc(), &rect, brush); ::DeleteObject(brush); From d6a6b8fbd4c1f6659a08577856a490666b878eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sun, 10 Jul 2016 16:39:09 +0200 Subject: [PATCH 12/16] Fix VC++ warning about comparing bool with > 0 --- src/common/utilscmn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 4d612202c8..973ded2631 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -1171,7 +1171,7 @@ wxString wxStripMenuCodes(const wxString& in, int flags) } // The initial '?' means we match "Foo(&F)" but not "(&F)" - if (label.Matches("?*(&?)") > 0) + if (label.Matches("?*(&?)")) { label = label.Left( label.Len()-4 ).Trim(); return label + accel; From 97713c12d7666a8da4497c01b3298885b955052b Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 11 Jul 2016 21:27:42 +0200 Subject: [PATCH 13/16] Fixed setting wxPGProperty label If wxPropertyGrid has wxPG_AUTO_SORT flag set then renaming the label of any property can change the order of displayed properties including this one which is currently selected. To be properly displayed in the new location this selected property has to be refreshed separately. --- src/propgrid/propgridiface.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 52c10de16c..6085f50a22 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -635,6 +635,9 @@ void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id, const wxString& { wxPG_PROP_ARG_CALL_PROLOG() + if ( p->GetLabel() == newproplabel ) + return; + p->SetLabel( newproplabel ); wxPropertyGridPageState* state = p->GetParentState(); @@ -646,9 +649,19 @@ void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id, const wxString& if ( pg->GetState() == state ) { if ( pg->HasFlag(wxPG_AUTO_SORT) ) + { pg->Refresh(); + // If any property is selected it has to + // be refreshed in the new location. + if ( pg == p->GetGrid() && pg->GetSelectedProperty() ) + { + RefreshProperty(pg->GetSelectedProperty()); + } + } else + { pg->DrawItem( p ); + } } } From e9af6d6ec7f11de58bb3a27537d21ad9cde7e0e4 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 11 Jul 2016 21:41:31 +0200 Subject: [PATCH 14/16] Fixed setting/unsetting wxPGProperty as read-only. Don't do any action only if property is exactly in the same state as required (and action is requested for single property only). --- src/propgrid/propgridiface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 6085f50a22..ea19305d7f 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -284,8 +284,10 @@ void wxPropertyGridInterface::SetPropertyReadOnly( wxPGPropArg id, bool set, int } else { - // Do nothing if flag is already set. - if ( p->HasFlag(wxPG_PROP_READONLY) ) + // Do nothing if flag is already set as required. + if ( set && p->HasFlag(wxPG_PROP_READONLY) ) + return; + if ( !set && !p->HasFlag(wxPG_PROP_READONLY) ) return; p->ChangeFlag(wxPG_PROP_READONLY, set); From 3057c18939a0ff63a49c5d9de2f905b1c155c798 Mon Sep 17 00:00:00 2001 From: Paul Kulchenko Date: Tue, 12 Jul 2016 09:31:52 -0700 Subject: [PATCH 15/16] Use wgetcwd() with MinGW to handle non-ASCII working directory All versions of MinGW seem to have this function, so use it to ensure that wxGetCwd() returns the correct result even when the current directory contains non-ASCII characters. Closes https://github.com/wxWidgets/wxWidgets/pull/307 --- src/common/filefn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index a5fc4e6265..a0e5b275b8 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -82,7 +82,7 @@ #endif // TODO: Borland probably has _wgetcwd as well? -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW32__) #define HAVE_WGETCWD #endif From aa3acfdd15eff1519a41b48a2babe4cba75660f9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 13 Jul 2016 23:33:23 +0200 Subject: [PATCH 16/16] Work around an apparent gcc optimizer bug in wxClassInfo Rewrite a complex expression in wxClassInfo::IsKindOf() as several statements to avoid what looks like a gcc optimizer bug as it was dereferencing m_baseInfo1 pointer even when it was null. The new version is not completely equivalent to the old one as it doesn't check for info == NULL which is not really necessary, but this is just a side effect and doesn't affect anything, the important change is avoiding doing everything in a single expression. Closes #17483. --- include/wx/rtti.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/include/wx/rtti.h b/include/wx/rtti.h index 308b65767b..34d8d387bf 100644 --- a/include/wx/rtti.h +++ b/include/wx/rtti.h @@ -85,10 +85,22 @@ public: bool IsKindOf(const wxClassInfo *info) const { - return info != 0 && - ( info == this || - ( m_baseInfo1 && m_baseInfo1->IsKindOf(info) ) || - ( m_baseInfo2 && m_baseInfo2->IsKindOf(info) ) ); + if ( info == this ) + return true; + + if ( m_baseInfo1 ) + { + if ( m_baseInfo1->IsKindOf(info) ) + return true; + } + + if ( m_baseInfo2 ) + { + if ( m_baseInfo2->IsKindOf(info) ) + return true; + } + + return false; } wxDECLARE_CLASS_INFO_ITERATORS();