KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_re_bitmap_overlay_panel.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 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, see <https://www.gnu.org/licenses/>.
18 */
19
22
23#include <bitmaps.h>
24
25#include <wx/bmpbndl.h>
26#include <wx/checkbox.h>
27#include <wx/dcbuffer.h>
28#include <wx/dcclient.h>
29#include <wx/stattext.h>
30
31
33 wxPanel(),
36{
37 // Must set background style BEFORE creating the window
38 SetBackgroundStyle( wxBG_STYLE_PAINT );
39 Create( aParent, aId );
40
41 Bind( wxEVT_PAINT, &DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint, this );
42 Bind( wxEVT_DPI_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged, this );
43 Bind( wxEVT_SYS_COLOUR_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange, this );
44}
45
46
50
51
52void DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint( wxPaintEvent& aEvent )
53{
54 wxAutoBufferedPaintDC dc( this );
55
56 dc.SetBackground( wxBrush( GetBackgroundColour() ) );
57 dc.Clear();
58
59 if( !m_bitmap.IsOk() )
60 return;
61
62 dc.DrawBitmap( m_bitmap, 0, 0, true );
63}
64
65
66void DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged( wxDPIChangedEvent& aEvent )
67{
68 LoadBitmap();
70 Refresh();
71 aEvent.Skip();
72}
73
74
75void DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange( wxSysColourChangedEvent& aEvent )
76{
77 LoadBitmap();
78 Refresh();
79 aEvent.Skip();
80}
81
82
84{
85 // Platform handles focus ring automatically.
86 // Could add custom highlighting here if needed.
87 aEvent.Skip();
88}
89
90
91void DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur( wxFocusEvent& aEvent )
92{
93 // Platform handles focus ring automatically.
94 aEvent.Skip();
95}
96
97
99{
100 if( !aControl )
101 return;
102
103 // Bind focus events to track active field
104 aControl->Bind( wxEVT_SET_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldFocus, this );
105 aControl->Bind( wxEVT_KILL_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur, this );
106}
107
108
110{
112 return;
113
114 wxBitmapBundle bundle = KiBitmapBundle( m_bitmapId );
115
116 m_logicalBitmapSize = FromDIP( bundle.GetDefaultSize() );
117 m_bitmap = bundle.GetBitmap( ToPhys( m_logicalBitmapSize ) );
118
119 Refresh();
120}
121
122
124{
125 m_bitmapId = aBitmap;
126 LoadBitmap();
127
128 if( m_bitmap.IsOk() )
129 SetMinSize( m_logicalBitmapSize );
130}
131
132
134{
135 for( const auto& field : m_fields )
136 {
137 const DRC_RE_FIELD_POSITION& pos = field->GetPosition();
138 wxControl* ctrl = field->GetControl();
139
140 if( !ctrl )
141 continue;
142
143 int heightLogical = ctrl->GetBestSize().GetHeight();
144 int widthLogical = FromDIP( pos.xEnd - pos.xStart );
145 int xLogical = FromDIP( pos.xStart );
146 int yLogical = FromDIP( pos.yCenter ) - heightLogical / 2;
147
148 ctrl->SetPosition( wxPoint( xLogical, yLogical ) );
149 ctrl->SetSize( wxSize( widthLogical, heightLogical ) );
150
151 // Position labels if present
152 if( field->HasLabel() )
153 PositionLabel( field.get() );
154
155 if( field->HasPrefixLabel() )
156 PositionPrefixLabel( field.get() );
157 }
158}
159
160
162{
163 wxStaticText* label = aField->GetLabel();
164 wxControl* ctrl = aField->GetControl();
165
166 if( !label || !ctrl )
167 return;
168
169 const DRC_RE_FIELD_POSITION& pos = aField->GetPosition();
170 wxPoint ctrlPos = ctrl->GetPosition();
171 wxSize ctrlSize = ctrl->GetSize();
172 wxSize labelSize = label->GetBestSize();
173
174 wxPoint labelPos;
175 int GAP = FromDIP( 4 );
176
177 switch( pos.labelPosition )
178 {
180 labelPos.x = ctrlPos.x - labelSize.GetWidth() - GAP;
181 labelPos.y = ctrlPos.y + ( ctrlSize.GetHeight() - labelSize.GetHeight() ) / 2;
182 break;
183
185 labelPos.x = ctrlPos.x + ctrlSize.GetWidth() + GAP;
186 labelPos.y = ctrlPos.y + ( ctrlSize.GetHeight() - labelSize.GetHeight() ) / 2;
187 break;
188
190 labelPos.x = ctrlPos.x + ( ctrlSize.GetWidth() - labelSize.GetWidth() ) / 2;
191 labelPos.y = ctrlPos.y - labelSize.GetHeight() - GAP;
192 break;
193
195 labelPos.x = ctrlPos.x + ( ctrlSize.GetWidth() - labelSize.GetWidth() ) / 2;
196 labelPos.y = ctrlPos.y + ctrlSize.GetHeight() + GAP;
197 break;
198
200 default:
201 return;
202 }
203
204 label->SetPosition( labelPos );
205 label->SetSize( labelSize );
206}
207
208
210{
211 wxStaticText* prefix = aField->GetPrefixLabel();
212 wxControl* ctrl = aField->GetControl();
213
214 if( !prefix || !ctrl )
215 return;
216
217 wxPoint ctrlPos = ctrl->GetPosition();
218 wxSize ctrlSize = ctrl->GetSize();
219 wxSize prefixSize = prefix->GetBestSize();
220
221 int GAP = FromDIP( 4 );
222
223 wxPoint prefixPos;
224 prefixPos.x = ctrlPos.x - prefixSize.GetWidth() - GAP;
225 prefixPos.y = ctrlPos.y + ( ctrlSize.GetHeight() - prefixSize.GetHeight() ) / 2;
226
227 prefix->SetPosition( prefixPos );
228 prefix->SetSize( prefixSize );
229}
230
231
233{
234 // Base implementation does nothing; derived classes override to populate fields
235 return true;
236}
237
238
240{
241 // Base implementation does nothing; derived classes override to read fields
242 return true;
243}
244
245
247{
248 for( const auto& field : m_fields )
249 field->ShowError( false );
250}
251
252
253void DRC_RE_BITMAP_OVERLAY_PANEL::ShowFieldError( const wxString& aFieldId )
254{
255 auto it = m_fieldIdMap.find( aFieldId );
256
257 if( it != m_fieldIdMap.end() )
258 it->second->ShowError( true );
259}
260
261
263 const DRC_RE_FIELD_POSITION& aPosition )
264{
265 long style = wxALIGN_CENTER_VERTICAL;
266
267 if( aPosition.labelPosition == LABEL_POSITION::LEFT )
268 style |= wxALIGN_RIGHT;
269 else
270 style |= wxALIGN_LEFT;
271
272 wxCheckBox* checkbox =
273 new wxCheckBox( this, wxID_ANY, aPosition.labelText, wxDefaultPosition, wxDefaultSize, style );
274
275 return AddControl( aId, aPosition, checkbox );
276}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
BITMAPS
A list of all bitmap identifiers.
@ INVALID_BITMAP
DRC_RE_OVERLAY_FIELD * AddCheckbox(const wxString &aId, const DRC_RE_FIELD_POSITION &aPosition)
Create and position a checkbox control on the bitmap overlay.
void LoadBitmap()
Load the appropriate bitmap variant for the current theme and DPI.
void OnThemeChange(wxSysColourChangedEvent &aEvent)
wxBitmap m_bitmap
Current background bitmap.
DRC_RE_OVERLAY_FIELD * AddControl(const wxString &aId, const DRC_RE_FIELD_POSITION &aPosition, T *aControl)
Position a control on the bitmap overlay.
void OnDPIChanged(wxDPIChangedEvent &aEvent)
void PositionLabel(DRC_RE_OVERLAY_FIELD *aField)
Position a label relative to its field control based on the label position setting.
void ShowFieldError(const wxString &aFieldId)
Show an error indicator on the specified field.
void SetupFieldStyling(wxControl *aControl)
Apply transparent styling to a field control.
std::map< wxString, DRC_RE_OVERLAY_FIELD * > m_fieldIdMap
Field ID to field lookup.
void SetBackgroundBitmap(BITMAPS aBitmap)
Set the background bitmap for this panel.
wxSize m_logicalBitmapSize
Bitmap size in logical pixels.
DRC_RE_BITMAP_OVERLAY_PANEL(wxWindow *aParent, wxWindowID aId=wxID_ANY)
void ClearFieldErrors()
Clear error indicators from all fields.
BITMAPS m_bitmapId
BITMAPS enum value.
void PositionFields()
Position all fields based on the current scale factor.
void OnFieldFocus(wxFocusEvent &aEvent)
std::vector< std::unique_ptr< DRC_RE_OVERLAY_FIELD > > m_fields
All overlay fields.
void PositionPrefixLabel(DRC_RE_OVERLAY_FIELD *aField)
Position a prefix label to the left of its field control.
Wraps a wxControl positioned over a bitmap overlay panel.
wxStaticText * GetLabel() const
wxStaticText * GetPrefixLabel() const
const DRC_RE_FIELD_POSITION & GetPosition() const
wxControl * GetControl() const
@ BOTTOM
Label below the field.
@ RIGHT
Label to the right of the field.
@ TOP
Label above the field.
@ LEFT
Label to the left of the field.
Specifies the position and size of a field overlaid on a constraint bitmap.
LABEL_POSITION labelPosition
Position of label relative to field.
int xEnd
Right edge X coordinate where the field ends.
int xStart
Left edge X coordinate where the field starts.
wxString labelText
Optional label text (empty for no label)
int yCenter
Vertical center Y coordinate of the field.