Use wx to draw the arrow on the collapsable pane

This allows for color changes and scaling of the arrow
when the display needs it (e.g. HiDPI displays).

Also make the arrow and text respond to if the window is
active to mimic native controls.

Fixes https://gitlab.com/kicad/code/kicad/issues/6042
This commit is contained in:
Ian McInerney 2021-03-25 21:14:06 +00:00
parent 1d81826409
commit 804c09b8f2
9 changed files with 77 additions and 178 deletions

View File

@ -115,8 +115,6 @@ set( BMAPS_SMALL
small_warning
tree_nosel
tree_sel
triangle_down
triangle_right
visibility
visibility_off
www

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="16" height="16" viewBox="0 0 4.2333332 4.2333335" version="1.1" id="svg8" inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" sodipodi:docname="triangle_down.svg">
<defs id="defs2" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="89.6" inkscape:cx="6.3261338" inkscape:cy="5.4996444" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" units="px" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showguides="true" inkscape:lockguides="false" inkscape:guide-bbox="true" inkscape:window-width="2560" inkscape:window-height="1370" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1">
<inkscape:grid type="xygrid" id="grid815" />
<sodipodi:guide position="0,2.1166667" orientation="0,1" id="guide4520" inkscape:locked="false" />
<sodipodi:guide position="2.1166666,4.2333335" orientation="1,0" id="guide4522" inkscape:locked="false" />
</sodipodi:namedview>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-292.76665)">
<path style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22048618px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 0.79375,294.88331 h 2.6458333 l -1.3229202,1.32292 z" id="path4526" inkscape:connector-curvature="0" inkscape:transform-center-y="0.65386359" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="16" height="16" viewBox="0 0 4.2333332 4.2333335" version="1.1" id="svg8" inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" sodipodi:docname="triangle_right.svg">
<defs id="defs2" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="44.8" inkscape:cx="6.7613636" inkscape:cy="7.2582474" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" units="px" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showguides="true" inkscape:lockguides="false" inkscape:guide-bbox="true" inkscape:window-width="2560" inkscape:window-height="1370" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1">
<inkscape:grid type="xygrid" id="grid815" />
<sodipodi:guide position="0,2.1166667" orientation="0,1" id="guide4520" inkscape:locked="false" />
<sodipodi:guide position="2.1166666,4.2333335" orientation="1,0" id="guide4522" inkscape:locked="false" />
</sodipodi:namedview>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-292.76665)">
<path style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22048602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 2.1166666,296.20623 v -2.64583 l 1.3229167,1.32292 z" id="path4526" inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="16" height="16" viewBox="0 0 4.2333332 4.2333335" version="1.1" id="svg8" inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" sodipodi:docname="triangle_down.svg">
<defs id="defs2" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="89.6" inkscape:cx="6.3261338" inkscape:cy="5.4996444" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" units="px" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showguides="true" inkscape:lockguides="false" inkscape:guide-bbox="true" inkscape:window-width="2560" inkscape:window-height="1370" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1">
<inkscape:grid type="xygrid" id="grid815" />
<sodipodi:guide position="0,2.1166667" orientation="0,1" id="guide4520" inkscape:locked="false" />
<sodipodi:guide position="2.1166666,4.2333335" orientation="1,0" id="guide4522" inkscape:locked="false" />
</sodipodi:namedview>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-292.76665)">
<path style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22048618px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 0.79375,294.88331 h 2.6458333 l -1.3229202,1.32292 z" id="path4526" inkscape:connector-curvature="0" inkscape:transform-center-y="0.65386359" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="16" height="16" viewBox="0 0 4.2333332 4.2333335" version="1.1" id="svg8" inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)" sodipodi:docname="triangle_right.svg">
<defs id="defs2" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="44.8" inkscape:cx="6.7613636" inkscape:cy="7.2582474" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" units="px" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" showguides="true" inkscape:lockguides="false" inkscape:guide-bbox="true" inkscape:window-width="2560" inkscape:window-height="1370" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1">
<inkscape:grid type="xygrid" id="grid815" />
<sodipodi:guide position="0,2.1166667" orientation="0,1" id="guide4520" inkscape:locked="false" />
<sodipodi:guide position="2.1166666,4.2333335" orientation="1,0" id="guide4522" inkscape:locked="false" />
</sodipodi:namedview>
<metadata id="metadata5">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-292.76665)">
<path style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22048602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 2.1166666,296.20623 v -2.64583 l 1.3229167,1.32292 z" id="path4526" inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -22,6 +22,8 @@
#include <wx/collpane.h>
#include <wx/renderer.h>
#include <wx/toplevel.h>
#include <wx/window.h>
#include <algorithm>
@ -214,9 +216,6 @@ bool WX_COLLAPSIBLE_PANE_HEADER::Create( wxWindow* aParent, wxWindowID aId, cons
if ( !wxControl::Create( aParent, aId, aPos, aSize, aStyle, aValidator, aName ) )
return false;
m_iconRight = KiBitmap( BITMAPS::triangle_right );
m_iconDown = KiBitmap( BITMAPS::triangle_down );
SetLabel( aLabel );
Bind( wxEVT_PAINT, &WX_COLLAPSIBLE_PANE_HEADER::onPaint, this );
@ -260,9 +259,8 @@ wxSize WX_COLLAPSIBLE_PANE_HEADER::DoGetBestClientSize() const
wxSize size = dc.GetTextExtent( text );
// Reserve space for icon
size.x += m_iconRight.GetWidth();
size.y = std::max( size.y, m_iconRight.GetHeight() );
// Reserve space for arrow (which is a square the height of the text)
size.x += size.GetHeight();
#ifdef __WXMSW__
size.IncBy( GetSystemMetrics( SM_CXFOCUSBORDER ),
@ -286,25 +284,43 @@ void WX_COLLAPSIBLE_PANE_HEADER::onPaint( wxPaintEvent& aEvent )
dc.DrawRectangle( rect );
#endif
// Make the background look like a button when the pointer is over it
if( m_inWindow )
{
dc.SetBrush( wxBrush( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) ) );
dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle( rect );
}
wxString text;
int indexAccel = wxControl::FindAccelIndex( GetLabel(), &text );
wxSize textSize = dc.GetTextExtent( text );
wxRect textRect( wxPoint( m_iconRight.GetWidth(), 0 ), textSize );
// Compute all the sizes
wxRect arrowRect( 0, 0, textSize.GetHeight(), textSize.GetHeight() );
wxRect textRect( arrowRect.GetTopRight(), textSize );
textRect = textRect.CenterIn( rect, wxVERTICAL );
wxBitmap* icon = m_collapsed ? &m_iconRight : &m_iconDown;
// Find out if the window we are in is active or not
bool isActive = true;
wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>( wxGetTopLevelParent( this ) );
if( m_inWindow )
{
dc.SetTextForeground( wxSystemColour::wxSYS_COLOUR_HOTLIGHT );
dc.DrawBitmap( icon->ConvertToDisabled( 200 ), wxPoint( 0, 0 ) );
}
if( tlw && !tlw->IsActive() )
isActive = false;
// Draw the arrow
drawArrow( dc, arrowRect, isActive );
// We are responsible for showing the text as disabled when the window isn't active
wxColour clr;
if( isActive )
clr = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
else
{
dc.DrawBitmap( *icon, wxPoint( 0, 0 ) );
}
clr = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
dc.SetTextForeground( clr );
dc.DrawLabel( text, textRect, wxALIGN_CENTER_VERTICAL, indexAccel );
#ifdef __WXMSW__
@ -365,3 +381,46 @@ void WX_COLLAPSIBLE_PANE_HEADER::onChar( wxKeyEvent& aEvent )
break;
}
}
void WX_COLLAPSIBLE_PANE_HEADER::drawArrow( wxDC& aDC, wxRect aRect, bool aIsActive )
{
// The bottom corner of the triangle is located halfway across the area and 3/4 down from the top
wxPoint btmCorner( aRect.GetWidth() / 2, 3 * aRect.GetHeight() / 4 );
// The right corner of the triangle is located halfway down from the top and 3/4 across the area
wxPoint rtCorner( 3 * aRect.GetWidth() / 4, aRect.GetHeight() / 2 );
// Choose the other corner depending on if the panel is expanded or collapsed
wxPoint otherCorner( 0, 0 );
if( m_collapsed )
otherCorner = wxPoint( aRect.GetWidth() / 2, aRect.GetHeight() / 4 );
else
otherCorner = wxPoint( aRect.GetWidth() / 4, aRect.GetHeight() / 2 );
// Choose the color to draw the triangle
wxColour clr;
// Highlight the arrow when the pointer is inside the header, otherwise use text color
if( m_inWindow )
clr = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
else
clr = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
// If the window isn't active, then use the disabled text color
if( !aIsActive )
clr = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
// Must set both the pen (for the outline) and the brush (for the polygon fill)
aDC.SetPen( wxPen( clr ) );
aDC.SetBrush( wxBrush( clr ) );
// Draw the triangle
wxPointList points;
points.Append( &btmCorner );
points.Append( &rtCorner );
points.Append( &otherCorner );
aDC.DrawPolygon( &points );
}

View File

@ -85,8 +85,6 @@ const std::vector<BITMAP_INFO> g_BitmapInfo = {
{ BITMAPS::small_warning, wxT( "small_warning_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::tree_nosel, wxT( "tree_nosel_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::tree_sel, wxT( "tree_sel_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::triangle_down, wxT( "triangle_down_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::triangle_right, wxT( "triangle_right_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::visibility, wxT( "visibility_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::visibility_off, wxT( "visibility_off_16.png" ), 16, wxT( "light" ) },
{ BITMAPS::www, wxT( "www_16.png" ), 16, wxT( "light" ) },
@ -137,8 +135,6 @@ const std::vector<BITMAP_INFO> g_BitmapInfo = {
{ BITMAPS::small_warning, wxT( "small_warning_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::tree_nosel, wxT( "tree_nosel_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::tree_sel, wxT( "tree_sel_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::triangle_down, wxT( "triangle_down_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::triangle_right, wxT( "triangle_right_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::visibility, wxT( "visibility_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::visibility_off, wxT( "visibility_off_dark_16.png" ), 16, wxT( "dark" ) },
{ BITMAPS::www, wxT( "www_dark_16.png" ), 16, wxT( "dark" ) },

View File

@ -507,8 +507,6 @@ enum class BITMAPS : unsigned int
trash,
tree_nosel,
tree_sel,
triangle_right,
triangle_down,
undelete,
undo,
unit_inch,

View File

@ -71,8 +71,6 @@ private:
wxString m_label;
bool m_collapsed;
bool m_inWindow;
wxBitmap m_iconRight;
wxBitmap m_iconDown;
void init();
@ -89,6 +87,8 @@ private:
void onChar( wxKeyEvent& aEvent );
void doSetCollapsed( bool aCollapsed );
void drawArrow( wxDC& aDC, wxRect aRect, bool aIsActive );
};