Merge branch 'nicer-boxsizer-asserts'
Improve the error messages by indicating what should be done to avoid the asserts and provide a way to disable them if really needed. See https://github.com/wxWidgets/wxWidgets/pull/2375
This commit is contained in:
@@ -25,7 +25,11 @@ Changes in behaviour not resulting in compilation errors
|
|||||||
(it used to succeed in wxMSW).
|
(it used to succeed in wxMSW).
|
||||||
|
|
||||||
- Using invalid flags with wxBoxSizer or wxGridSizer items now triggers asserts
|
- Using invalid flags with wxBoxSizer or wxGridSizer items now triggers asserts
|
||||||
when done from the code or error messages when done in XRC.
|
when done from the code or error messages when done in XRC. These asserts are
|
||||||
|
best avoided by fixing the flags, but wxSizerFlags::DisableConsistencyChecks()
|
||||||
|
can be used to globally suppress them until this can be done. Even less
|
||||||
|
intrusively, environment variable WXSUPPRESS_SIZER_FLAGS_CHECK can be set (to
|
||||||
|
any value) to achieve the same effect.
|
||||||
|
|
||||||
- wxWS_EX_VALIDATE_RECURSIVELY is now the default behaviour, i.e. calling
|
- wxWS_EX_VALIDATE_RECURSIVELY is now the default behaviour, i.e. calling
|
||||||
Validate() or TransferData{From,To}Window() will now also call the same
|
Validate() or TransferData{From,To}Window() will now also call the same
|
||||||
|
@@ -32,5 +32,10 @@ wxWidgets programs.
|
|||||||
set it to @c "CURL" to force using libcurl-based implementation under
|
set it to @c "CURL" to force using libcurl-based implementation under
|
||||||
MSW or macOS platforms where the native implementation would be chosen
|
MSW or macOS platforms where the native implementation would be chosen
|
||||||
by default.}
|
by default.}
|
||||||
|
@itemdef{WXSUPPRESS_SIZER_FLAGS_CHECK,
|
||||||
|
If set, disables asserts about using invalid sizer flags in the code.
|
||||||
|
This can be helpful when running older programs recompiled with
|
||||||
|
wxWidgets 3.1 or later, as these asserts are mostly harmless and can
|
||||||
|
be safely ignored if the code works as expected.}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -238,6 +238,9 @@ public:
|
|||||||
int GetFlags() const { return m_flags; }
|
int GetFlags() const { return m_flags; }
|
||||||
int GetBorderInPixels() const { return m_borderInPixels; }
|
int GetBorderInPixels() const { return m_borderInPixels; }
|
||||||
|
|
||||||
|
// Disablee sizer flags (in)consistency asserts.
|
||||||
|
static void DisableConsistencyChecks();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef wxNEEDS_BORDER_IN_PX
|
#ifdef wxNEEDS_BORDER_IN_PX
|
||||||
static float DoGetDefaultBorderInPx();
|
static float DoGetDefaultBorderInPx();
|
||||||
|
@@ -1480,6 +1480,33 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxSizerFlags& CentreVertical();
|
wxSizerFlags& CentreVertical();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Globally disable checks for sizer flag consistency in debug builds.
|
||||||
|
|
||||||
|
By default, sizer classes such as wxBoxSizer and wxFlexGridSizer assert
|
||||||
|
when passed invalid flags, even though doing this usually doesn't
|
||||||
|
result in any catastrophic consequences and the invalid flags are
|
||||||
|
simply ignored later. Due to this, and the fact that these checks were
|
||||||
|
only added in wxWidgets 3.1, existing code may run into multiple
|
||||||
|
asserts warning about incorrect sizer flags use. Using this function
|
||||||
|
provides a temporary solution for avoiding such asserts when upgrading
|
||||||
|
to wxWidgets 3.1 from a previous version and will prevent such checks
|
||||||
|
from being done.
|
||||||
|
|
||||||
|
Please do note that correcting the code by removing the invalid flags
|
||||||
|
remains a much better solution as these asserts may be very helpful to
|
||||||
|
understand why some code using sizer flags doesn't work as expected, so
|
||||||
|
using this function, especially permanently, rather than a temporary
|
||||||
|
workaround, is @e not recommended.
|
||||||
|
|
||||||
|
Notice that the same effect as calling this function can be achieved by
|
||||||
|
setting the environment variable @c WXSUPPRESS_SIZER_FLAGS_CHECK to any
|
||||||
|
value.
|
||||||
|
|
||||||
|
@since 3.1.6
|
||||||
|
*/
|
||||||
|
static void DisableConsistencyChecks();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the border in the given @a direction having twice the default
|
Sets the border in the given @a direction having twice the default
|
||||||
border size.
|
border size.
|
||||||
|
@@ -144,11 +144,78 @@ static const int SIZER_FLAGS_MASK =
|
|||||||
wxADD_FLAG(wxSHAPED,
|
wxADD_FLAG(wxSHAPED,
|
||||||
0))))))))))))))))));
|
0))))))))))))))))));
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
int gs_disableFlagChecks = -1;
|
||||||
|
|
||||||
|
// Check condition taking gs_disableFlagChecks into account.
|
||||||
|
//
|
||||||
|
// Note that because this is not a macro, the condition is always evaluated,
|
||||||
|
// even if gs_disableFlagChecks is 0, but this shouldn't matter because the
|
||||||
|
// conditions used with this function are just simple bit checks.
|
||||||
|
bool CheckSizerFlags(bool cond)
|
||||||
|
{
|
||||||
|
// Once-only initialization: check if disabled via environment.
|
||||||
|
if ( gs_disableFlagChecks == -1 )
|
||||||
|
{
|
||||||
|
gs_disableFlagChecks = wxGetEnv("WXSUPPRESS_SIZER_FLAGS_CHECK", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gs_disableFlagChecks || cond;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString MakeFlagsCheckMessage(const char* start, const char* whatToRemove)
|
||||||
|
{
|
||||||
|
return wxString::Format
|
||||||
|
(
|
||||||
|
"%s"
|
||||||
|
"\n\nDO NOT PANIC !!\n\n"
|
||||||
|
"If you're an end user running a program not developed by you, "
|
||||||
|
"please ignore this message, it is harmless, and please try "
|
||||||
|
"reporting the problem to the program developers.\n"
|
||||||
|
"\n"
|
||||||
|
"You may also set WXSUPPRESS_SIZER_FLAGS_CHECK environment "
|
||||||
|
"variable to suppress all such checks when running this program.\n"
|
||||||
|
"\n"
|
||||||
|
"If you're the developer, simply remove %s from your code to "
|
||||||
|
"avoid getting this message. You can also call "
|
||||||
|
"wxSizerFlags::DisableConsistencyChecks() to globally disable "
|
||||||
|
"all such checks, but this is strongly not recommended.",
|
||||||
|
start,
|
||||||
|
whatToRemove
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
#endif // wxDEBUG_LEVEL
|
#endif // wxDEBUG_LEVEL
|
||||||
|
|
||||||
|
#define ASSERT_NO_IGNORED_FLAGS_IMPL(f, value, name, explanation) \
|
||||||
|
wxASSERT_MSG \
|
||||||
|
( \
|
||||||
|
CheckSizerFlags(!((f) & (value))), \
|
||||||
|
MakeFlagsCheckMessage \
|
||||||
|
( \
|
||||||
|
name " will be ignored in this sizer: " explanation, \
|
||||||
|
"this flag" \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ASSERT_NO_IGNORED_FLAGS(f, flags, explanation) \
|
||||||
|
ASSERT_NO_IGNORED_FLAGS_IMPL(f, flags, #flags, explanation)
|
||||||
|
|
||||||
#define ASSERT_INCOMPATIBLE_NOT_USED_IMPL(f, f1, n1, f2, n2) \
|
#define ASSERT_INCOMPATIBLE_NOT_USED_IMPL(f, f1, n1, f2, n2) \
|
||||||
wxASSERT_MSG(((f) & (f1 | f2)) != (f1 | f2), \
|
wxASSERT_MSG \
|
||||||
n1 " and " n2 " can't be used together")
|
( \
|
||||||
|
CheckSizerFlags(((f) & (f1 | f2)) != (f1 | f2)), \
|
||||||
|
MakeFlagsCheckMessage \
|
||||||
|
( \
|
||||||
|
"One of " n1 " and " n2 " will be ignored in this sizer: " \
|
||||||
|
"they are incompatible and cannot be used together", \
|
||||||
|
"one of these flags" \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
#define ASSERT_INCOMPATIBLE_NOT_USED(f, f1, f2) \
|
#define ASSERT_INCOMPATIBLE_NOT_USED(f, f1, f2) \
|
||||||
ASSERT_INCOMPATIBLE_NOT_USED_IMPL(f, f1, #f1, f2, #f2)
|
ASSERT_INCOMPATIBLE_NOT_USED_IMPL(f, f1, #f1, f2, #f2)
|
||||||
@@ -159,6 +226,14 @@ static const int SIZER_FLAGS_MASK =
|
|||||||
ASSERT_INCOMPATIBLE_NOT_USED(f, wxALIGN_CENTRE_VERTICAL, wxALIGN_BOTTOM)
|
ASSERT_INCOMPATIBLE_NOT_USED(f, wxALIGN_CENTRE_VERTICAL, wxALIGN_BOTTOM)
|
||||||
|
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void wxSizerFlags::DisableConsistencyChecks()
|
||||||
|
{
|
||||||
|
#if wxDEBUG_LEVEL
|
||||||
|
gs_disableFlagChecks = true;
|
||||||
|
#endif // wxDEBUG_LEVEL
|
||||||
|
}
|
||||||
|
|
||||||
void wxSizerItem::Init(const wxSizerFlags& flags)
|
void wxSizerItem::Init(const wxSizerFlags& flags)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
@@ -1470,10 +1545,17 @@ wxSizerItem *wxGridSizer::DoInsert(size_t index, wxSizerItem *item)
|
|||||||
{
|
{
|
||||||
// Check that expansion will happen in at least one of the directions.
|
// Check that expansion will happen in at least one of the directions.
|
||||||
wxASSERT_MSG
|
wxASSERT_MSG
|
||||||
|
(
|
||||||
|
CheckSizerFlags
|
||||||
(
|
(
|
||||||
!(flags & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL)) ||
|
!(flags & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL)) ||
|
||||||
!(flags & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL)),
|
!(flags & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL))
|
||||||
wxS("wxEXPAND flag will be overridden by alignment flags")
|
),
|
||||||
|
MakeFlagsCheckMessage
|
||||||
|
(
|
||||||
|
"wxEXPAND flag will be overridden by alignment flags",
|
||||||
|
"either wxEXPAND or the alignment in at least one direction"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2083,10 +2165,10 @@ wxSizerItem *wxBoxSizer::DoInsert(size_t index, wxSizerItem *item)
|
|||||||
const int flags = item->GetFlag();
|
const int flags = item->GetFlag();
|
||||||
if ( IsVertical() )
|
if ( IsVertical() )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG
|
ASSERT_NO_IGNORED_FLAGS
|
||||||
(
|
(
|
||||||
!(flags & wxALIGN_BOTTOM),
|
flags, wxALIGN_BOTTOM,
|
||||||
wxS("Vertical alignment flags are ignored in vertical sizers")
|
"only horizontal alignment flags can be used in vertical sizers"
|
||||||
);
|
);
|
||||||
|
|
||||||
// We need to accept wxALIGN_CENTRE_VERTICAL when it is combined with
|
// We need to accept wxALIGN_CENTRE_VERTICAL when it is combined with
|
||||||
@@ -2094,50 +2176,44 @@ wxSizerItem *wxBoxSizer::DoInsert(size_t index, wxSizerItem *item)
|
|||||||
// and we accept it historically in wxSizer API.
|
// and we accept it historically in wxSizer API.
|
||||||
if ( !(flags & wxALIGN_CENTRE_HORIZONTAL) )
|
if ( !(flags & wxALIGN_CENTRE_HORIZONTAL) )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG
|
ASSERT_NO_IGNORED_FLAGS
|
||||||
(
|
(
|
||||||
!(flags & wxALIGN_CENTRE_VERTICAL),
|
flags, wxALIGN_CENTRE_VERTICAL,
|
||||||
wxS("Vertical alignment flags are ignored in vertical sizers")
|
"only horizontal alignment flags can be used in vertical sizers"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else // horizontal
|
||||||
|
{
|
||||||
|
ASSERT_NO_IGNORED_FLAGS
|
||||||
|
(
|
||||||
|
flags, wxALIGN_RIGHT,
|
||||||
|
"only vertical alignment flags can be used in horizontal sizers"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !(flags & wxALIGN_CENTRE_VERTICAL) )
|
||||||
|
{
|
||||||
|
ASSERT_NO_IGNORED_FLAGS
|
||||||
|
(
|
||||||
|
flags, wxALIGN_CENTRE_HORIZONTAL,
|
||||||
|
"only vertical alignment flags can be used in horizontal sizers"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note that using alignment with wxEXPAND can make sense if wxSHAPED
|
// Note that using alignment with wxEXPAND can make sense if wxSHAPED
|
||||||
// is also used, as the item doesn't necessarily fully expand in the
|
// is also used, as the item doesn't necessarily fully expand in the
|
||||||
// other direction in this case.
|
// other direction in this case.
|
||||||
if ( (flags & wxEXPAND) && !(flags & wxSHAPED) )
|
if ( (flags & wxEXPAND) && !(flags & wxSHAPED) )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG
|
ASSERT_NO_IGNORED_FLAGS
|
||||||
(
|
(
|
||||||
!(flags & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL)),
|
flags,
|
||||||
wxS("Horizontal alignment flags are ignored with wxEXPAND")
|
wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL |
|
||||||
|
wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL,
|
||||||
|
"wxEXPAND overrides alignment flags in box sizers"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
wxASSERT_MSG
|
|
||||||
(
|
|
||||||
!(flags & wxALIGN_RIGHT),
|
|
||||||
wxS("Horizontal alignment flags are ignored in horizontal sizers")
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( !(flags & wxALIGN_CENTRE_VERTICAL) )
|
|
||||||
{
|
|
||||||
wxASSERT_MSG
|
|
||||||
(
|
|
||||||
!(flags & wxALIGN_CENTRE_HORIZONTAL),
|
|
||||||
wxS("Horizontal alignment flags are ignored in horizontal sizers")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (flags & wxEXPAND) && !(flags & wxSHAPED) )
|
|
||||||
{
|
|
||||||
wxASSERT_MSG(
|
|
||||||
!(flags & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL)),
|
|
||||||
wxS("Vertical alignment flags are ignored with wxEXPAND")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxSizer::DoInsert(index, item);
|
return wxSizer::DoInsert(index, item);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user