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#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 // onAccept handler
60 [this]( wxKeyEvent& aEvent )
61 {
62 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
63 },
64 // onCharAdded handler
65 [this]( wxStyledTextEvent& aEvent )
66 {
68 [this]( const wxString& crossRef, wxArrayString* tokens )
69 {
70 m_frame->GetContextualTextVars( m_textBox, crossRef, tokens );
71 } );
72 } );
73
74 // A hack which causes Scintilla to auto-size the text editor canvas
75 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
76 m_MultiLineText->SetScrollWidth( 1 );
77 m_MultiLineText->SetScrollWidthTracking( true );
78
80 {
81 // Do not allow locking items in the footprint editor
82 m_cbLocked->Show( false );
83 }
84
86
88
90 m_bold->SetBitmap( KiBitmapBundle( BITMAPS::text_bold ) );
92 m_italic->SetBitmap( KiBitmapBundle( BITMAPS::text_italic ) );
93
95
97 m_alignLeft->SetBitmap( KiBitmapBundle( BITMAPS::text_align_left ) );
99 m_alignCenter->SetBitmap( KiBitmapBundle( BITMAPS::text_align_center ) );
101 m_alignRight->SetBitmap( KiBitmapBundle( BITMAPS::text_align_right ) );
102
104
106 m_mirrored->SetBitmap( KiBitmapBundle( BITMAPS::text_mirrored ) );
107
109
110 // Configure the layers list selector. Note that footprints are built outside the current
111 // board and so we may need to show all layers if the text is on an unactivated layer.
114
118
119 m_orientation.SetUnits( EDA_UNITS::DEGREES );
121
122 // Set predefined rotations in combo dropdown, according to the locale floating point
123 // separator notation
124 double rot_list[] = { 0.0, 90.0, -90.0, 180.0 };
125
126 for( size_t ii = 0; ii < m_OrientCtrl->GetCount() && ii < 4; ++ii )
127 m_OrientCtrl->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) );
128
129 for( const auto& [ lineStyle, lineStyleDesc ] : lineTypeNames )
130 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
131
133
135
136 // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
137 // so we have to listen to wxEVT_CHAR_HOOK events instead.
138 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
139 nullptr, this );
140
142}
143
144
146{
147 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
148 nullptr, this );
149
150 delete m_scintillaTricks;
151}
152
153
155{
156 DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
157
158 // QuasiModal required for Scintilla auto-complete
159 return dlg.ShowQuasiModal();
160}
161
162
164{
165 BOARD* board = m_frame->GetBoard();
166 wxString converted = board->ConvertKIIDsToCrossReferences(
168
169 m_MultiLineText->SetValue( converted );
170 m_MultiLineText->SetSelection( -1, -1 );
171 m_MultiLineText->EmptyUndoBuffer();
172
173 m_cbLocked->SetValue( m_textBox->IsLocked() );
174
176
178
182
185
186 switch ( m_textBox->GetHorizJustify() )
187 {
188 case GR_TEXT_H_ALIGN_LEFT: m_alignLeft->Check( true ); break;
189 case GR_TEXT_H_ALIGN_CENTER: m_alignCenter->Check( true ); break;
190 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.MilsToIU( TEXT_MAX_SIZE_MILS );
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::DEFAULT );
371 else
372 stroke.SetLineStyle( it->first );
373
374 m_textBox->SetStroke( stroke );
375
378
379 if( pushCommit )
380 commit.Push( _( "Change 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:109
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
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:104
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=wxEmptyString, 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 void SetLocked(bool aLocked)
Definition: board_item.h:299
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:45
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:247
virtual bool IsLocked() const
Definition: board_item.cpp:73
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
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:675
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1270
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:766
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1324
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
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
void SetTextSize(VECTOR2I aNewSize)
Definition: eda_text.cpp:358
bool IsItalic() const
Definition: eda_text.h:141
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:131
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
KIFONT::FONT * GetFont() const
Definition: eda_text.h:207
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:236
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
virtual void ClearBoundingBoxCache()
Definition: eda_text.cpp:487
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
virtual void ClearRenderCache()
Definition: eda_text.cpp:481
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsMirrored() const
Definition: eda_text.h:150
bool IsBold() const
Definition: eda_text.h:144
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
int GetTextThickness() const
Definition: eda_text.h:123
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:342
VECTOR2I GetTextSize() const
Definition: eda_text.h:218
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: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:97
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:82
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:83
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:67
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(std::function< void(const wxString &crossRef, wxArrayString *tokens)> aTokenProvider)
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
int GetWidth() const
Definition: stroke_params.h:91
void SetLineStyle(LINE_STYLE aLineStyle)
Definition: stroke_params.h:95
void SetWidth(int aWidth)
Definition: stroke_params.h:92
LINE_STYLE GetLineStyle() const
Definition: stroke_params.h:94
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:280
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:941
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
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
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