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 The 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#ifdef _WIN32
52 // Without this setting, on Windows, some esoteric unicode chars create display issue
53 // in a wxStyledTextCtrl.
54 // for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
55 m_MultiLineText->SetTechnology(wxSTC_TECHNOLOGY_DIRECTWRITE);
56#endif
57
58 m_scintillaTricks = new SCINTILLA_TRICKS( m_MultiLineText, wxT( "{}" ), false,
59 // onAcceptFn
60 [this]( wxKeyEvent& aEvent )
61 {
62 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
63 },
64 // onCharFn
65 [this]( wxStyledTextEvent& aEvent )
66 {
68 // getTokensFn
69 [this]( const wxString& xRef, wxArrayString* tokens )
70 {
71 m_frame->GetContextualTextVars( m_textBox, xRef, tokens );
72 } );
73 } );
74
75 // A hack which causes Scintilla to auto-size the text editor canvas
76 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
77 m_MultiLineText->SetScrollWidth( 1 );
78 m_MultiLineText->SetScrollWidthTracking( true );
79
81 {
82 // Do not allow locking items in the footprint editor
83 m_cbLocked->Show( false );
84 }
85
87
89
91 m_bold->SetBitmap( KiBitmapBundle( BITMAPS::text_bold ) );
93 m_italic->SetBitmap( KiBitmapBundle( BITMAPS::text_italic ) );
94
96
98 m_alignLeft->SetBitmap( KiBitmapBundle( BITMAPS::text_align_left ) );
100 m_alignCenter->SetBitmap( KiBitmapBundle( BITMAPS::text_align_center ) );
102 m_alignRight->SetBitmap( KiBitmapBundle( BITMAPS::text_align_right ) );
103
105
107 m_mirrored->SetBitmap( KiBitmapBundle( BITMAPS::text_mirrored ) );
108
110
111 // Configure the layers list selector. Note that footprints are built outside the current
112 // board and so we may need to show all layers if the text is on an unactivated layer.
115
119
120 m_orientation.SetUnits( EDA_UNITS::DEGREES );
122
123 // Set predefined rotations in combo dropdown, according to the locale floating point
124 // separator notation
125 double rot_list[] = { 0.0, 90.0, -90.0, 180.0 };
126
127 for( size_t ii = 0; ii < m_OrientCtrl->GetCount() && ii < 4; ++ii )
128 m_OrientCtrl->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) );
129
130 for( const auto& [ lineStyle, lineStyleDesc ] : lineTypeNames )
131 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmapBundle( lineStyleDesc.bitmap ) );
132
134
135 // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
136 // so we have to listen to wxEVT_CHAR_HOOK events instead.
137 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
138 nullptr, this );
139
141}
142
143
145{
146 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
147 nullptr, this );
148
149 delete m_scintillaTricks;
150}
151
152
154{
155 DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
156
157 // QuasiModal required for Scintilla auto-complete
158 return dlg.ShowQuasiModal();
159}
160
161
163{
164 BOARD* board = m_frame->GetBoard();
165 wxString converted = board->ConvertKIIDsToCrossReferences(
167
168 m_MultiLineText->SetValue( converted );
169 m_MultiLineText->SetSelection( -1, -1 );
170 m_MultiLineText->EmptyUndoBuffer();
171
172 m_cbLocked->SetValue( m_textBox->IsLocked() );
173
175
177
181
184
185 switch ( m_textBox->GetHorizJustify() )
186 {
187 case GR_TEXT_H_ALIGN_LEFT: m_alignLeft->Check( true ); break;
188 case GR_TEXT_H_ALIGN_CENTER: m_alignCenter->Check( true ); break;
189 case GR_TEXT_H_ALIGN_RIGHT: m_alignRight->Check( true ); break;
191 }
192
194
195 EDA_ANGLE orientation = m_textBox->GetTextAngle();
197
200
202 m_borderWidth.SetValue( stroke.GetWidth() );
203
204 LINE_STYLE style = stroke.GetLineStyle();
205
206 if( style == LINE_STYLE::DEFAULT )
207 style = LINE_STYLE::SOLID;
208
209 if( (int) style < (int) lineTypeNames.size() )
210 m_borderStyleCombo->SetSelection( (int) style );
211
215
216 return DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataToWindow();
217}
218
219
220void DIALOG_TEXTBOX_PROPERTIES::onFontSelected( wxCommandEvent & aEvent )
221{
222 if( KIFONT::FONT::IsStroke( aEvent.GetString() ) )
223 {
224 m_thickness.Show( true );
225
226 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
227 int thickness = m_thickness.GetValue();
228
229 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
230 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
231 }
232 else
233 {
234 m_thickness.Show( false );
235 }
236}
237
238
239void DIALOG_TEXTBOX_PROPERTIES::onBoldToggle( wxCommandEvent & aEvent )
240{
241 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
242
243 if( aEvent.IsChecked() )
245 else
247
248 aEvent.Skip();
249}
250
251
252void DIALOG_TEXTBOX_PROPERTIES::onAlignButton( wxCommandEvent& aEvent )
253{
255 {
256 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
257 btn->Check( false );
258 }
259}
260
261
262void DIALOG_TEXTBOX_PROPERTIES::onThickness( wxCommandEvent& event )
263{
264 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
265 int thickness = m_thickness.GetValue();
266
267 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
268 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
269}
270
271
273{
274 bool border = m_borderCheckbox->GetValue();
275
276 if( border && m_borderWidth.GetValue() <= 0 )
277 {
280 }
281
282 m_borderWidth.Enable( border );
283 m_borderStyleLabel->Enable( border );
284 m_borderStyleCombo->Enable( border );
285}
286
287
289{
290 if( !DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataFromWindow() )
291 return false;
292
294 int maxSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
295
296 if( !m_textWidth.Validate( minSize, maxSize ) || !m_textHeight.Validate( minSize, maxSize ) )
297 return false;
298
299 BOARD_COMMIT commit( m_frame );
300 commit.Modify( m_textBox );
301
302 // If no other command in progress, prepare undo command
303 // (for a command in progress, will be made later, at the completion of command)
304 bool pushCommit = ( m_textBox->GetEditFlags() == 0 );
305
306 // Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
307 // SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
308 if( !pushCommit )
310
311 BOARD* board = m_frame->GetBoard();
312 wxString txt = board->ConvertCrossReferencesToKIIDs( m_MultiLineText->GetValue() );
313
314#ifdef __WXMAC__
315 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
316 // Replace it now.
317 txt.Replace( "\r", "\n" );
318#elif defined( __WINDOWS__ )
319 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
320 // drawing routines so strip the \r char.
321 txt.Replace( "\r", "" );
322#endif
323
325 m_textBox->SetLocked( m_cbLocked->GetValue() );
327
329 {
331 m_italic->IsChecked() ) );
332 }
333
336
337 // Test for acceptable values for thickness and size and clamp if fails
339
340 if( m_textBox->GetTextThickness() > maxPenWidth )
341 {
342 DisplayError( this, _( "The text thickness is too large for the text size.\n"
343 "It will be clamped." ) );
344 m_textBox->SetTextThickness( maxPenWidth );
345 }
346
350
351 if( m_alignLeft->IsChecked() )
353 else if( m_alignCenter->IsChecked() )
355 else
357
359
362
364 stroke.SetWidth( m_borderWidth.GetValue() );
365
366 auto it = lineTypeNames.begin();
367 std::advance( it, m_borderStyleCombo->GetSelection() );
368
369 if( it == lineTypeNames.end() )
370 stroke.SetLineStyle( LINE_STYLE::SOLID );
371 else
372 stroke.SetLineStyle( it->first );
373
374 m_textBox->SetStroke( stroke );
375
378
379 if( pushCommit )
380 commit.Push( _( "Edit Text Box Properties" ) );
381
382 return true;
383}
384
385
387{
390
391 event.Skip();
392}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
Definition: bitmap_button.h:42
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=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
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 void SetLocked(bool aLocked)
Definition: board_item.h:330
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:298
virtual bool IsLocked() const
Definition: board_item.cpp:75
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:295
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:843
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1594
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:934
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1648
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:102
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:221
EDA_ANGLE Normalize180()
Definition: eda_angle.h:260
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
bool IsItalic() const
Definition: eda_text.h:156
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:524
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
KIFONT::FONT * GetFont() const
Definition: eda_text.h:234
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:384
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:187
void SetBoldFlag(bool aBold)
Set only the italic flag, without changing the font.
Definition: eda_text.cpp:369
virtual void ClearBoundingBoxCache()
Definition: eda_text.cpp:655
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:282
virtual void ClearRenderCache()
Definition: eda_text.cpp:649
void SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
Definition: eda_text.cpp:318
bool IsMirrored() const
Definition: eda_text.h:177
bool IsBold() const
Definition: eda_text.h:171
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:268
int GetTextThickness() const
Definition: eda_text.h:126
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:490
VECTOR2I GetTextSize() const
Definition: eda_text.h:248
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:400
void SetFontSelection(KIFONT::FONT *aFont, bool aSilentMode=false)
Set the selection in wxChoice widget.
Definition: font_choice.cpp:73
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic, bool aForDrawingSheet=false) const
bool HaveFontSelection() const
Definition: font_choice.cpp:95
virtual bool IsStroke() const
Definition: font.h:138
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)
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_shape.cpp:170
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:89
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:90
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:69
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void SetBorderEnabled(bool enabled)
void SetTextAngle(const EDA_ANGLE &aAngle) override
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoTextVarAutocomplete(const std::function< void(const wxString &xRef, wxArrayString *tokens)> &getTokensFn)
Simple container to manage line stroke parameters.
Definition: stroke_params.h:93
int GetWidth() const
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
LINE_STYLE GetLineStyle() const
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:170
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_MM
Minimum text size (1 micron).
Definition: eda_text.h:47
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition: eda_text.h:48
int GetPenSizeForBold(int aTextSize)
Definition: gr_text.cpp:36
int GetPenSizeForNormal(int aTextSize)
Definition: gr_text.cpp:60
int ClampTextPenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition: gr_text.cpp:72
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:699
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:57
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames
Conversion map between LINE_STYLE values and style names displayed.
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:46
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695