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, 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
26
27#include <bitmaps.h>
28
29#include <wx/bmpbndl.h>
30#include <wx/checkbox.h>
31#include <wx/dcbuffer.h>
32#include <wx/dcclient.h>
33#include <wx/stattext.h>
34
35
37 wxPanel(),
39 m_baseBitmapSize( 0, 0 )
40{
41 // Must set background style BEFORE creating the window
42 SetBackgroundStyle( wxBG_STYLE_PAINT );
43 Create( aParent, aId );
44
45 Bind( wxEVT_PAINT, &DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint, this );
46 Bind( wxEVT_DPI_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged, this );
47 Bind( wxEVT_SYS_COLOUR_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange, this );
48}
49
50
54
55
56void DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint( wxPaintEvent& aEvent )
57{
58 wxAutoBufferedPaintDC dc( this );
59
60 dc.SetBackground( wxBrush( GetBackgroundColour() ) );
61 dc.Clear();
62
63 if( !m_bitmap.IsOk() )
64 return;
65
66 dc.DrawBitmap( m_bitmap, 0, 0, true );
67}
68
69
70void DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged( wxDPIChangedEvent& aEvent )
71{
72 LoadBitmap();
74 Refresh();
75 aEvent.Skip();
76}
77
78
79void DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange( wxSysColourChangedEvent& aEvent )
80{
81 LoadBitmap();
82 Refresh();
83 aEvent.Skip();
84}
85
86
88{
89 // Platform handles focus ring automatically.
90 // Could add custom highlighting here if needed.
91 aEvent.Skip();
92}
93
94
95void DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur( wxFocusEvent& aEvent )
96{
97 // Platform handles focus ring automatically.
98 aEvent.Skip();
99}
100
101
103{
104 if( !aControl )
105 return;
106
107 // Bind focus events to track active field
108 aControl->Bind( wxEVT_SET_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldFocus, this );
109 aControl->Bind( wxEVT_KILL_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur, this );
110}
111
112
114{
116 return;
117
118 wxBitmapBundle bundle = KiBitmapBundle( m_bitmapId );
119
120 m_bitmap = bundle.GetBitmapFor( this );
121 m_baseBitmapSize = bundle.GetDefaultSize();
122
123 Refresh();
124}
125
126
128{
129 m_bitmapId = aBitmap;
130 LoadBitmap();
131
132 if( m_bitmap.IsOk() )
133 SetMinSize( m_baseBitmapSize );
134}
135
136
138{
139 for( const auto& field : m_fields )
140 {
141 const DRC_RE_FIELD_POSITION& pos = field->GetPosition();
142 wxControl* ctrl = field->GetControl();
143
144 if( !ctrl )
145 continue;
146
147 wxPoint scaledPos( pos.xStart, pos.yTop );
148 int width = pos.xEnd - pos.xStart + DRC_RE_OVERLAY_WE;
149 wxSize scaledSize( width, ctrl->GetBestSize().GetHeight() );
150
151 ctrl->SetPosition( scaledPos );
152 ctrl->SetSize( scaledSize );
153
154 // Position label if present
155 if( field->HasLabel() )
156 PositionLabel( 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 constexpr int GAP = 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}
206
207
209{
210 // Base implementation does nothing; derived classes override to populate fields
211 return true;
212}
213
214
216{
217 // Base implementation does nothing; derived classes override to read fields
218 return true;
219}
220
221
223{
224 for( const auto& field : m_fields )
225 field->ShowError( false );
226}
227
228
229void DRC_RE_BITMAP_OVERLAY_PANEL::ShowFieldError( const wxString& aFieldId )
230{
231 auto it = m_fieldIdMap.find( aFieldId );
232
233 if( it != m_fieldIdMap.end() )
234 it->second->ShowError( true );
235}
236
237
239 const DRC_RE_FIELD_POSITION& aPosition )
240{
241 wxCheckBox* checkbox = new wxCheckBox( this, wxID_ANY, wxEmptyString );
242
243 auto field = std::make_unique<DRC_RE_OVERLAY_FIELD>( this, aId, checkbox, aPosition );
244 DRC_RE_OVERLAY_FIELD* fieldPtr = field.get();
245
246 SetupFieldStyling( checkbox );
247
248 wxPoint pos( aPosition.xStart, aPosition.yTop );
249 checkbox->SetPosition( pos );
250
251 // Create label if specified
252 fieldPtr->CreateLabel();
253
254 if( fieldPtr->HasLabel() )
255 PositionLabel( fieldPtr );
256
257 m_fieldIdMap[aId] = fieldPtr;
258 m_fields.push_back( std::move( field ) );
259
260 return fieldPtr;
261}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
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.
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_baseBitmapSize
Bitmap size at 1x scale.
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.
Wraps a wxControl positioned over a bitmap overlay panel.
wxStaticText * GetLabel() const
void CreateLabel()
Create and associate a label with this field.
const DRC_RE_FIELD_POSITION & GetPosition() const
wxControl * GetControl() const
constexpr int DRC_RE_OVERLAY_WE
@ 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.
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
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.
int yTop
Top edge Y coordinate of the field.