KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_textbox_properties.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) 2022-2023 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
25#include <widgets/font_choice.h>
27#include <confirm.h>
28#include <board_commit.h>
30#include <board.h>
31#include <footprint.h>
32#include <pcb_textbox.h>
33#include <project.h>
34#include <pcb_edit_frame.h>
36#include <scintilla_tricks.h>
37
39 PCB_TEXTBOX* aTextBox ) :
41 m_frame( aParent ),
42 m_textBox( aTextBox ),
43 m_textWidth( aParent, m_SizeXLabel, m_SizeXCtrl, m_SizeXUnits ),
44 m_textHeight( aParent, m_SizeYLabel, m_SizeYCtrl, m_SizeYUnits ),
45 m_thickness( aParent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnits ),
46 m_orientation( aParent, m_OrientLabel, m_OrientCtrl, nullptr ),
47 m_borderWidth( aParent, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits )
48{
49 m_MultiLineText->SetEOLMode( wxSTC_EOL_LF );
50
51 m_scintillaTricks = new SCINTILLA_TRICKS( m_MultiLineText, wxT( "{}" ), false,
52 // onAccept handler
53 [this]()
54 {
55 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
56 },
57 // onCharAdded handler
58 [this]( wxStyledTextEvent& aEvent )
59 {
61 [this]( const wxString& crossRef, wxArrayString* tokens )
62 {
63 m_frame->GetContextualTextVars( m_textBox, crossRef, tokens );
64 } );
65 } );
66
67 // A hack which causes Scintilla to auto-size the text editor canvas
68 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
69 m_MultiLineText->SetScrollWidth( 1 );
70 m_MultiLineText->SetScrollWidthTracking( true );
71
73 {
74 // Do not allow locking items in the footprint editor
75 m_cbLocked->Show( false );
76 }
77
79
81
83 m_bold->SetBitmap( KiBitmap( BITMAPS::text_bold ) );
85 m_italic->SetBitmap( KiBitmap( BITMAPS::text_italic ) );
86
88
90 m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
92 m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) );
94 m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
95
97
99 m_mirrored->SetBitmap( KiBitmap( BITMAPS::text_mirrored ) );
100
102
103 // Configure the layers list selector. Note that footprints are built outside the current
104 // board and so we may need to show all layers if the text is on an unactivated layer.
107
111
112 m_orientation.SetUnits( EDA_UNITS::DEGREES );
114
115 // Set predefined rotations in combo dropdown, according to the locale floating point
116 // separator notation
117 double rot_list[] = { 0.0, 90.0, -90.0, 180.0 };
118
119 for( size_t ii = 0; ii < m_OrientCtrl->GetCount() && ii < 4; ++ii )
120 m_OrientCtrl->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) );
121
122 for( const std::pair<const PLOT_DASH_TYPE, lineTypeStruct>& typeEntry : lineTypeNames )
123 m_borderStyleCombo->Append( typeEntry.second.name, KiBitmap( typeEntry.second.bitmap ) );
124
126
128
129 // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
130 // so we have to listen to wxEVT_CHAR_HOOK events instead.
131 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
132 nullptr, this );
133
135}
136
137
139{
140 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
141 nullptr, this );
142
143 delete m_scintillaTricks;
144}
145
146
148{
149 DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
150
151 // QuasiModal required for Scintilla auto-complete
152 return dlg.ShowQuasiModal();
153}
154
155
157{
158 BOARD* board = m_frame->GetBoard();
159 wxString converted = board->ConvertKIIDsToCrossReferences(
161
162 m_MultiLineText->SetValue( converted );
163 m_MultiLineText->SetSelection( -1, -1 );
164 m_MultiLineText->EmptyUndoBuffer();
165
166 m_cbLocked->SetValue( m_textBox->IsLocked() );
167
169
171
175
178
179 switch ( m_textBox->GetHorizJustify() )
180 {
181 case GR_TEXT_H_ALIGN_LEFT: m_alignLeft->Check( true ); break;
182 case GR_TEXT_H_ALIGN_CENTER: m_alignCenter->Check( true ); break;
183 case GR_TEXT_H_ALIGN_RIGHT: m_alignRight->Check( true ); break;
184 }
185
187
188 EDA_ANGLE orientation = m_textBox->GetTextAngle();
190
192 m_borderCheckbox->SetValue( stroke.GetWidth() >= 0 );
193
194 if( stroke.GetWidth() >= 0 )
195 m_borderWidth.SetValue( stroke.GetWidth() );
196
197 PLOT_DASH_TYPE style = stroke.GetPlotStyle();
198
199 if( style == PLOT_DASH_TYPE::DEFAULT )
200 style = PLOT_DASH_TYPE::SOLID;
201
202 if( (int) style < (int) lineTypeNames.size() )
203 m_borderStyleCombo->SetSelection( (int) style );
204
205 m_borderWidth.Enable( stroke.GetWidth() >= 0 );
206 m_borderStyleLabel->Enable( stroke.GetWidth() >= 0 );
207 m_borderStyleCombo->Enable( stroke.GetWidth() >= 0 );
208
209 return DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataToWindow();
210}
211
212
213void DIALOG_TEXTBOX_PROPERTIES::onFontSelected( wxCommandEvent & aEvent )
214{
215 if( KIFONT::FONT::IsStroke( aEvent.GetString() ) )
216 {
217 m_thickness.Show( true );
218
219 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
220 int thickness = m_thickness.GetValue();
221
222 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
223 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
224 }
225 else
226 {
227 m_thickness.Show( false );
228 }
229}
230
231
232void DIALOG_TEXTBOX_PROPERTIES::onBoldToggle( wxCommandEvent & aEvent )
233{
234 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
235
236 if( aEvent.IsChecked() )
238 else
240
241 aEvent.Skip();
242}
243
244
245void DIALOG_TEXTBOX_PROPERTIES::onAlignButton( wxCommandEvent& aEvent )
246{
248 {
249 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
250 btn->Check( false );
251 }
252}
253
254
255void DIALOG_TEXTBOX_PROPERTIES::onThickness( wxCommandEvent& event )
256{
257 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
258 int thickness = m_thickness.GetValue();
259
260 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
261 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
262}
263
264
266{
267 bool border = m_borderCheckbox->GetValue();
268
269 if( border && m_borderWidth.GetValue() <= 0 )
270 {
273 }
274
275 m_borderWidth.Enable( border );
276 m_borderStyleLabel->Enable( border );
277 m_borderStyleCombo->Enable( border );
278}
279
280
282{
283 if( !DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataFromWindow() )
284 return false;
285
287 int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
288
289 if( !m_textWidth.Validate( minSize, maxSize ) || !m_textHeight.Validate( minSize, maxSize ) )
290 return false;
291
292 BOARD_COMMIT commit( m_frame );
293 commit.Modify( m_textBox );
294
295 // If no other command in progress, prepare undo command
296 // (for a command in progress, will be made later, at the completion of command)
297 bool pushCommit = ( m_textBox->GetEditFlags() == 0 );
298
299 // Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
300 // SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
301 if( !pushCommit )
303
304 BOARD* board = m_frame->GetBoard();
305 wxString txt = board->ConvertCrossReferencesToKIIDs( m_MultiLineText->GetValue() );
306
307#ifdef __WXMAC__
308 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
309 // Replace it now.
310 txt.Replace( "\r", "\n" );
311#elif defined( __WINDOWS__ )
312 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
313 // drawing routines so strip the \r char.
314 txt.Replace( "\r", "" );
315#endif
316
318 m_textBox->SetLocked( m_cbLocked->GetValue() );
320
322 {
324 m_italic->IsChecked() ) );
325 }
326
329
330 // Test for acceptable values for thickness and size and clamp if fails
332
333 if( m_textBox->GetTextThickness() > maxPenWidth )
334 {
335 DisplayError( this, _( "The text thickness is too large for the text size.\n"
336 "It will be clamped." ) );
337 m_textBox->SetTextThickness( maxPenWidth );
338 }
339
343
344 if( m_alignLeft->IsChecked() )
346 else if( m_alignCenter->IsChecked() )
348 else
350
352
354
355 if( m_borderCheckbox->GetValue() )
356 {
358 stroke.SetWidth( m_borderWidth.GetValue() );
359 }
360 else
361 {
362 stroke.SetWidth( -1 );
363 }
364
365 auto it = lineTypeNames.begin();
366 std::advance( it, m_borderStyleCombo->GetSelection() );
367
368 if( it == lineTypeNames.end() )
369 stroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT );
370 else
371 stroke.SetPlotStyle( it->first );
372
373 m_textBox->SetStroke( stroke );
374
377
378 if( pushCommit )
379 commit.Push( _( "Change text box properties" ) );
380
381 return true;
382}
383
384
386{
389
390 event.Skip();
391}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:106
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
Definition: bitmap_button.h:41
void SetIsRadioButton()
bool IsChecked() const
void Check(bool aCheck=true)
Check the control.
void SetIsSeparator()
Render button as a toolbar separator.
void SetIsCheckButton()
Setup the control as a two-state button (checked or unchecked).
void SetBitmap(const wxBitmapBundle &aBmp)
Set the bitmap shown when the button is enabled.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Container for design settings for a BOARD object.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:196
virtual void SetLocked(bool aLocked)
Definition: board_item.h:270
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:230
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:44
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:240
virtual bool IsLocked() const
Definition: board_item.cpp:72
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:270
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:637
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1184
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:728
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1238
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:104
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual void OnCharHook(wxKeyEvent &aEvt)
Class DIALOG_TEXTBOX_PROPERTIES_BASE.
void onAlignButton(wxCommandEvent &aEvent) override
void onThickness(wxCommandEvent &aEvent) override
void onBoldToggle(wxCommandEvent &aEvent) override
DIALOG_TEXTBOX_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, PCB_TEXTBOX *aTextBox)
void onMultiLineTCLostFocus(wxFocusEvent &event) override
void onFontSelected(wxCommandEvent &aEvent) override
void onBorderChecked(wxCommandEvent &event) override
EDA_ANGLE Normalize()
Definition: eda_angle.h:249
EDA_ANGLE Normalize180()
Definition: eda_angle.h:288
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:129
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
bool IsItalic() const
Definition: eda_text.h:138
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:128
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:92
KIFONT::FONT * GetFont() const
Definition: eda_text.h:196
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:236
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:157
virtual void ClearBoundingBoxCache()
Definition: eda_text.cpp:474
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
virtual void ClearRenderCache()
Definition: eda_text.cpp:468
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsMirrored() const
Definition: eda_text.h:147
bool IsBold() const
Definition: eda_text.h:141
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:359
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:175
int GetTextThickness() const
Definition: eda_text.h:120
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:343
VECTOR2I GetTextSize() const
Definition: eda_text.h:204
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:252
bool HaveFontSelection() const
Definition: font_choice.cpp:94
void SetFontSelection(KIFONT::FONT *aFont)
Definition: font_choice.cpp:73
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic) const
virtual bool IsStroke() const
Definition: font.h:112
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
Common, abstract interface for edit frames.
int ShowTextBoxPropertiesDialog(PCB_TEXTBOX *aTextBox)
void GetContextualTextVars(BOARD_ITEM *aSourceItem, const wxString &aCrossRef, wxArrayString *aTokens)
BOARD * GetBoard() const
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void ShowNonActivatedLayers(bool aShow)
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:71
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
void SetTextAngle(const EDA_ANGLE &aAngle) override
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoTextVarAutocomplete(std::function< void(const wxString &crossRef, wxArrayString *tokens)> aTokenProvider)
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
int GetWidth() const
Definition: stroke_params.h:98
void SetWidth(int aWidth)
Definition: stroke_params.h:99
PLOT_DASH_TYPE GetPlotStyle() const
void SetPlotStyle(PLOT_DASH_TYPE aPlotStyle)
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetPrecision(int aLength)
Normally not needed, but can be used to set the precision when using internal units that are floats (...
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual EDA_ANGLE GetAngleValue()
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual void SetAngleValue(const EDA_ANGLE &aValue)
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:283
This file is part of the common library.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
#define IN_EDIT
Item currently edited.
#define TEXT_MIN_SIZE_MILS
Minimum text size in mils.
Definition: eda_text.h:42
#define TEXT_MAX_SIZE_MILS
Maximum text size in mils (10 inches)
Definition: eda_text.h:43
int GetPenSizeForBold(int aTextSize)
Definition: gr_text.cpp:40
int GetPenSizeForNormal(int aTextSize)
Definition: gr_text.cpp:64
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition: gr_text.cpp:87
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_QUOTED_STR
Definition: string_utils.h:58
PLOT_DASH_TYPE
Dashed line types.
Definition: stroke_params.h:48
const std::map< PLOT_DASH_TYPE, struct lineTypeStruct > lineTypeNames
Definition: stroke_params.h:70
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588