You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.6 KiB

3 years ago
3 years ago
  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020 Kicad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <gal/color4d.h>
  24. #include <widgets/number_badge.h>
  25. #include <algorithm>
  26. #include <kiplatform/ui.h>
  27. NUMBER_BADGE::NUMBER_BADGE( wxWindow* aParent, wxWindowID aId, const wxPoint& aPos,
  28. const wxSize& aSize, int aStyles ) :
  29. wxPanel( aParent, aId, aPos, aSize, aStyles ),
  30. m_textSize( 10 ),
  31. m_maxNumber( 1000 ),
  32. m_currentNumber( 0 ),
  33. m_showBadge( false )
  34. {
  35. computeSize();
  36. Bind( wxEVT_PAINT, &NUMBER_BADGE::onPaint, this );
  37. }
  38. void NUMBER_BADGE::UpdateNumber( int aNumber, SEVERITY aSeverity )
  39. {
  40. m_showBadge = true;
  41. m_currentNumber = aNumber;
  42. // Choose the colors of the badge rectangle and font
  43. if( aNumber < 0 )
  44. {
  45. m_showBadge = false;
  46. }
  47. else if( aNumber == 0 )
  48. {
  49. if( aSeverity == RPT_SEVERITY_ERROR || aSeverity == RPT_SEVERITY_WARNING )
  50. {
  51. m_badgeColour = KIGFX::COLOR4D( GREEN ).ToColour();
  52. m_textColour = *wxWHITE;
  53. }
  54. else
  55. {
  56. m_showBadge = false;
  57. }
  58. }
  59. else
  60. {
  61. switch( aSeverity )
  62. {
  63. case RPT_SEVERITY_ERROR:
  64. m_badgeColour = KIPLATFORM::UI::IsDarkTheme() ? wxColour( 240, 64, 64 ) : *wxRED;
  65. m_textColour = *wxWHITE;
  66. break;
  67. case RPT_SEVERITY_WARNING:
  68. m_badgeColour = *wxYELLOW;
  69. m_textColour = *wxBLACK;
  70. break;
  71. case RPT_SEVERITY_ACTION:
  72. m_badgeColour = KIGFX::COLOR4D( GREEN ).ToColour();
  73. m_textColour = *wxWHITE;
  74. break;
  75. case RPT_SEVERITY_EXCLUSION:
  76. case RPT_SEVERITY_INFO:
  77. default:
  78. m_badgeColour = *wxLIGHT_GREY;
  79. m_textColour = *wxBLACK;
  80. break;
  81. }
  82. }
  83. computeSize();
  84. // Force the badge UI to refresh so the new number and color is displayed
  85. Refresh();
  86. }
  87. void NUMBER_BADGE::SetMaximumNumber( int aMax )
  88. {
  89. m_maxNumber = aMax;
  90. }
  91. void NUMBER_BADGE::SetTextSize( int aSize )
  92. {
  93. m_textSize = aSize;
  94. computeSize();
  95. }
  96. // OSX has prevalent badges in the application bar at the bottom of the screen so we try to
  97. // match those. Other platforms may also need tweaks to spacing, fontweight, etc.
  98. #if defined( __WXMAC__ )
  99. #define BADGE_FONTWEIGHT wxFONTWEIGHT_NORMAL
  100. #define PLATFORM_FUDGE_X 0.92
  101. #define PLATFORM_FUDGE_Y 1.6
  102. #else
  103. #define BADGE_FONTWEIGHT wxFONTWEIGHT_BOLD
  104. #define PLATFORM_FUDGE_X 1.0
  105. #define PLATFORM_FUDGE_Y 1.0
  106. #endif
  107. void NUMBER_BADGE::computeSize()
  108. {
  109. wxClientDC dc( this );
  110. wxString test = wxString::Format( wxT( "%d" ), m_currentNumber );
  111. int len = test.length();
  112. // Determine the size using the string "m999{+}" where the 'm' on the front serves as a margin
  113. // so the number isn't too close to the curved edge.
  114. test = wxS( "m" );
  115. test.Pad( len, '9' );
  116. if( m_currentNumber > m_maxNumber )
  117. test += wxS( "+" );
  118. dc.SetFont( wxFont( m_textSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, BADGE_FONTWEIGHT ) );
  119. wxSize size = dc.GetTextExtent( test );
  120. size.y *= PLATFORM_FUDGE_Y;
  121. size.x = std::max<int>( size.x * PLATFORM_FUDGE_X, size.y );
  122. SetMinSize( size );
  123. SetSize( size );
  124. }
  125. void NUMBER_BADGE::onPaint( wxPaintEvent& aEvt )
  126. {
  127. // The drawing rectangle
  128. wxSize clientSize = GetSize();
  129. wxPaintDC dc( this );
  130. wxString text;
  131. wxBrush brush;
  132. // Give the badge a transparent background to show the panel underneath
  133. dc.SetBackground( *wxTRANSPARENT_BRUSH );
  134. dc.Clear();
  135. // We always draw a transparent background, but only draw the badge when it is needed
  136. if( !m_showBadge )
  137. return;
  138. // The rectangle the color is drawn in needs to be shrunk by 1px on each axis because for some
  139. // reason it seems to be padded out by 1px and is cutoff otherwise.
  140. wxRect rect( wxPoint( 0, 0 ), clientSize - wxSize( 1, 1 ) );
  141. brush.SetStyle( wxBRUSHSTYLE_SOLID );
  142. brush.SetColour( m_badgeColour );
  143. dc.SetBrush( brush );
  144. dc.SetPen( wxPen( m_badgeColour, 0 ) );
  145. dc.DrawRoundedRectangle( rect, rect.height / 2 );
  146. // Cap the number displayed and add the "+" to the end if required
  147. if( m_currentNumber > m_maxNumber )
  148. text = wxString::Format( wxT( "%d+" ), m_maxNumber );
  149. else
  150. text = wxString::Format( wxT( "%d" ), m_currentNumber );
  151. dc.SetFont( wxFont( m_textSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, BADGE_FONTWEIGHT ) );
  152. dc.SetTextForeground( m_textColour );
  153. dc.DrawLabel( text, wxRect( wxPoint( 0, 0 ), clientSize ), wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL );
  154. }