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, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <wx/hyperlink.h>
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#include <string_utils.h>
38
39
42 m_frame( aParent ),
43 m_textBox( aTextBox ),
47 m_orientation( aParent, m_OrientLabel, m_OrientCtrl, nullptr ),
49{
50 m_MultiLineText->SetEOLMode( wxSTC_EOL_LF );
51
52 // Wrapping is display-only and does not insert newlines into the stored text.
53 m_MultiLineText->SetWrapMode( wxSTC_WRAP_WORD );
54 m_MultiLineText->SetWrapVisualFlags( wxSTC_WRAPVISUALFLAG_END );
55 m_MultiLineText->SetWrapIndentMode( wxSTC_WRAPINDENT_INDENT );
56
57#ifdef _WIN32
58 // Without this setting, on Windows, some esoteric unicode chars create display issue
59 // in a wxStyledTextCtrl.
60 // for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
61 m_MultiLineText->SetTechnology( wxSTC_TECHNOLOGY_DIRECTWRITE );
62#endif
63
65 m_MultiLineText, wxT( "{}" ), false,
66 // onAcceptFn
67 [this]( wxKeyEvent& aEvent )
68 {
69 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
70 },
71 // onCharFn
72 [this]( wxStyledTextEvent& aEvent )
73 {
74 m_scintillaTricks->DoTextVarAutocomplete(
75 // getTokensFn
76 [this]( const wxString& xRef, wxArrayString* tokens )
77 {
78 m_frame->GetContextualTextVars( m_textBox, xRef, tokens );
79 } );
80 } );
81
82 // A hack which causes Scintilla to auto-size the text editor canvas
83 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
84 m_MultiLineText->SetScrollWidth( 1 );
85 m_MultiLineText->SetScrollWidthTracking( true );
86
87 // Add syntax help hyperlink
88 m_syntaxHelp = new wxHyperlinkCtrl( this, wxID_ANY, _( "Syntax help" ), wxEmptyString, wxDefaultPosition,
89 wxDefaultSize, wxHL_DEFAULT_STYLE );
90 m_syntaxHelp->SetToolTip( _( "Show syntax help window" ) );
91 m_MultiLineSizer->Add( m_syntaxHelp, 0, wxBOTTOM | wxRIGHT | wxLEFT, 3 );
92
93 m_syntaxHelp->Bind( wxEVT_HYPERLINK, &DIALOG_TEXTBOX_PROPERTIES::onSyntaxHelp, this );
94
95 m_helpWindow = nullptr;
96
97 if( m_textBox->GetParentFootprint() )
98 {
99 // Do not allow locking items in the footprint editor
100 m_cbLocked->Show( false );
101 }
102
104
105 m_separator0->SetIsSeparator();
106
107 m_bold->SetIsCheckButton();
109 m_italic->SetIsCheckButton();
111
112 m_separator1->SetIsSeparator();
113
114 m_hAlignLeft->SetIsRadioButton();
116 m_hAlignCenter->SetIsRadioButton();
118 m_hAlignRight->SetIsRadioButton();
120
121 m_separator2->SetIsSeparator();
122
123 m_mirrored->SetIsCheckButton();
125
126 m_separator3->SetIsSeparator();
127
128 m_vAlignTop->SetIsRadioButton();
130 m_vAlignCenter->SetIsRadioButton();
132 m_vAlignBottom->SetIsRadioButton();
134
135 m_separator4->SetIsSeparator();
136
137 m_autoTextThickness->SetIsCheckButton();
139
140 // Configure the layers list selector. Note that footprints are built outside the current
141 // board and so we may need to show all layers if the text is on an unactivated layer.
142 if( !m_frame->GetBoard()->IsLayerEnabled( m_textBox->GetLayer() ) )
143 m_LayerSelectionCtrl->ShowNonActivatedLayers( true );
144
145 m_LayerSelectionCtrl->SetLayersHotkeys( false );
146 m_LayerSelectionCtrl->SetBoardFrame( m_frame );
147 m_LayerSelectionCtrl->Resync();
148
150 m_orientation.SetPrecision( 3 );
151
152 // Set predefined rotations in combo dropdown, according to the locale floating point
153 // separator notation
154 double rot_list[] = { 0.0, 90.0, -90.0, 180.0 };
155
156 for( size_t ii = 0; ii < m_OrientCtrl->GetCount() && ii < 4; ++ii )
157 m_OrientCtrl->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) );
158
159 for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
160 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmapBundle( lineStyleDesc.bitmap ) );
161
163
164 // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
165 // so we have to listen to wxEVT_CHAR_HOOK events instead.
166 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ), nullptr, this );
167
169 Layout();
170 bMainSizer->Fit( this );
171}
172
173
175{
176 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ), nullptr, this );
177
178 delete m_scintillaTricks;
179 m_scintillaTricks = nullptr;
180
181 if( m_helpWindow )
182 m_helpWindow->Destroy();
183}
184
185
187{
188 DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
189
190 // QuasiModal required for Scintilla auto-complete
191 return dlg.ShowQuasiModal();
192}
193
194
196{
197 BOARD* board = m_frame->GetBoard();
198 wxString converted = board->ConvertKIIDsToCrossReferences( UnescapeString( m_textBox->GetText() ) );
199
200 m_MultiLineText->SetValue( converted );
201 m_MultiLineText->SetSelection( -1, -1 );
202 m_MultiLineText->EmptyUndoBuffer();
203
204 m_cbLocked->SetValue( m_textBox->IsLocked() );
205
206 m_LayerSelectionCtrl->SetLayerSelection( m_textBox->GetLayer() );
207
208 m_fontCtrl->SetFontSelection( m_textBox->GetFont() );
209
210 m_textWidth.SetValue( m_textBox->GetTextSize().x );
211 m_textHeight.SetValue( m_textBox->GetTextSize().y );
212
213 if( m_textBox->GetAutoThickness() )
214 {
215 m_autoTextThickness->Check( m_textBox->GetAutoThickness() );
216 m_thickness.SetValue( m_textBox->GetEffectiveTextPenWidth() );
217 m_thickness.Enable( false );
218 }
219 else
220 {
221 m_thickness.SetValue( m_textBox->GetTextThickness() );
222 }
223
224 m_bold->Check( m_textBox->IsBold() );
225 m_italic->Check( m_textBox->IsItalic() );
226
227 switch( m_textBox->GetHorizJustify() )
228 {
229 case GR_TEXT_H_ALIGN_LEFT: m_hAlignLeft->Check( true ); break;
230 case GR_TEXT_H_ALIGN_CENTER: m_hAlignCenter->Check( true ); break;
231 case GR_TEXT_H_ALIGN_RIGHT: m_hAlignRight->Check( true ); break;
233 }
234
235 switch( m_textBox->GetVertJustify() )
236 {
237 case GR_TEXT_V_ALIGN_TOP: m_vAlignTop->Check( true ); break;
238 case GR_TEXT_V_ALIGN_CENTER: m_vAlignCenter->Check( true ); break;
239 case GR_TEXT_V_ALIGN_BOTTOM: m_vAlignBottom->Check( true ); break;
241 }
242
243 m_mirrored->Check( m_textBox->IsMirrored() );
244
245 EDA_ANGLE orientation = m_textBox->GetTextAngle();
246 m_orientation.SetAngleValue( orientation.Normalize180() );
247
248 STROKE_PARAMS stroke = m_textBox->GetStroke();
249 m_borderCheckbox->SetValue( m_textBox->IsBorderEnabled() );
250
251 if( m_textBox->IsBorderEnabled() )
252 m_borderWidth.SetValue( stroke.GetWidth() );
253
254 LINE_STYLE style = stroke.GetLineStyle();
255
256 if( style == LINE_STYLE::DEFAULT )
257 style = LINE_STYLE::SOLID;
258
259 if( (int) style < (int) lineTypeNames.size() )
260 m_borderStyleCombo->SetSelection( (int) style );
261
262 m_borderWidth.Enable( m_textBox->IsBorderEnabled() );
263 m_borderStyleLabel->Enable( m_textBox->IsBorderEnabled() );
264 m_borderStyleCombo->Enable( m_textBox->IsBorderEnabled() );
265
266 return DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataToWindow();
267}
268
269void DIALOG_TEXTBOX_PROPERTIES::onValignButton( wxCommandEvent& aEvent )
270{
272 {
273 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
274 btn->Check( false );
275 }
276}
277
278void DIALOG_TEXTBOX_PROPERTIES::onFontSelected( wxCommandEvent& aEvent )
279{
280 if( KIFONT::FONT::IsStroke( aEvent.GetString() ) )
281 {
282 m_thickness.Show( true );
283
284 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
285 int thickness = m_thickness.GetValue();
286
287 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
288 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
289 }
290 else
291 {
292 m_thickness.Show( false );
293 }
294}
295
296
297void DIALOG_TEXTBOX_PROPERTIES::onBoldToggle( wxCommandEvent& aEvent )
298{
299 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
300
301 if( aEvent.IsChecked() )
302 m_thickness.ChangeValue( GetPenSizeForBold( textSize ) );
303 else
304 m_thickness.ChangeValue( GetPenSizeForNormal( textSize ) );
305
306 aEvent.Skip();
307}
308
309
310void DIALOG_TEXTBOX_PROPERTIES::onHalignButton( wxCommandEvent& aEvent )
311{
313 {
314 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
315 btn->Check( false );
316 }
317}
318
319
320void DIALOG_TEXTBOX_PROPERTIES::onThickness( wxCommandEvent& event )
321{
322 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
323 int thickness = m_thickness.GetValue();
324
325 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
326 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
327}
328
329
330void DIALOG_TEXTBOX_PROPERTIES::onTextSize( wxCommandEvent& aEvent )
331{
332 if( m_autoTextThickness->IsChecked() )
333 {
334 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
335 int thickness;
336
337 // Calculate the "best" thickness from text size and bold option:
338 if( m_bold->IsChecked() )
339 thickness = GetPenSizeForBold( textSize );
340 else
341 thickness = GetPenSizeForNormal( textSize );
342
343 m_thickness.SetValue( thickness );
344 }
345}
346
347
349{
350 if( aEvent.IsChecked() )
351 {
352 m_autoTextThickness->Check( true );
353
354 wxCommandEvent dummy;
355 onTextSize( dummy );
356
357 m_thickness.Enable( false );
358 }
359 else
360 {
361 m_thickness.Enable( true );
362 }
363}
364
365
367{
368 bool border = m_borderCheckbox->GetValue();
369
370 if( border && m_borderWidth.GetValue() <= 0 )
371 {
372 BOARD_DESIGN_SETTINGS& bds = m_textBox->GetBoard()->GetDesignSettings();
373 m_borderWidth.SetValue( bds.GetLineThickness( m_textBox->GetLayer() ) );
374 }
375
376 m_borderWidth.Enable( border );
377 m_borderStyleLabel->Enable( border );
378 m_borderStyleCombo->Enable( border );
379}
380
381
383{
384 if( !DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataFromWindow() )
385 return false;
386
387 int minSize = pcbIUScale.mmToIU( TEXT_MIN_SIZE_MM );
388 int maxSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
389
390 if( !m_textWidth.Validate( minSize, maxSize ) || !m_textHeight.Validate( minSize, maxSize ) )
391 return false;
392
393 BOARD_COMMIT commit( m_frame );
394 commit.Modify( m_textBox );
395
396 // If no other command in progress, prepare undo command
397 // (for a command in progress, will be made later, at the completion of command)
398 bool pushCommit = ( m_textBox->GetEditFlags() == 0 );
399
400 // Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
401 // SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
402 if( !pushCommit )
403 m_textBox->SetFlags( IN_EDIT );
404
405 BOARD* board = m_frame->GetBoard();
406 wxString txt = board->ConvertCrossReferencesToKIIDs( m_MultiLineText->GetValue() );
407
408#ifdef __WXMAC__
409 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
410 // Replace it now.
411 txt.Replace( "\r", "\n" );
412#elif defined( __WINDOWS__ )
413 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
414 // drawing routines so strip the \r char.
415 txt.Replace( "\r", "" );
416#endif
417
418 m_textBox->SetText( EscapeString( txt, CTX_QUOTED_STR ) );
419 m_textBox->SetLocked( m_cbLocked->GetValue() );
420 m_textBox->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
421
422 if( m_fontCtrl->HaveFontSelection() )
423 {
424 m_textBox->SetFont( m_fontCtrl->GetFontSelection( m_bold->IsChecked(), m_italic->IsChecked() ) );
425 }
426
427 m_textBox->SetTextSize( VECTOR2I( m_textWidth.GetValue(), m_textHeight.GetValue() ) );
428
429 if( m_autoTextThickness->IsChecked() )
430 {
431 m_textBox->SetAutoThickness( true );
432 }
433 else
434 {
435 m_textBox->SetTextThickness( m_thickness.GetValue() );
436
437 // Test for acceptable values for thickness and size and clamp if fails
438 int maxPenWidth = ClampTextPenSize( m_textBox->GetTextThickness(), m_textBox->GetTextSize() );
439
440 if( m_textBox->GetTextThickness() > maxPenWidth )
441 {
442 DisplayError( this, _( "The text thickness is too large for the text size.\n"
443 "It will be clamped." ) );
444 m_textBox->SetTextThickness( maxPenWidth );
445 }
446 }
447
448 m_textBox->SetTextAngle( m_orientation.GetAngleValue().Normalize() );
449 m_textBox->SetBoldFlag( m_bold->IsChecked() );
450 m_textBox->SetItalicFlag( m_italic->IsChecked() );
451
452 if( m_hAlignLeft->IsChecked() )
453 m_textBox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
454 else if( m_hAlignCenter->IsChecked() )
455 m_textBox->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
456 else
457 m_textBox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
458
459 if( m_vAlignTop->IsChecked() )
460 m_textBox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
461 else if( m_vAlignCenter->IsChecked() )
462 m_textBox->SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
463 else
464 m_textBox->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
465
466 m_textBox->SetMirrored( m_mirrored->IsChecked() );
467
468 m_textBox->SetBorderEnabled( m_borderCheckbox->GetValue() );
469 STROKE_PARAMS stroke = m_textBox->GetStroke();
470
471 if( !m_borderWidth.IsIndeterminate() )
472 stroke.SetWidth( m_borderWidth.GetValue() );
473
474 auto it = lineTypeNames.begin();
475 std::advance( it, m_borderStyleCombo->GetSelection() );
476
477 if( it == lineTypeNames.end() )
479 else
480 stroke.SetLineStyle( it->first );
481
482 m_textBox->SetStroke( stroke );
483
484 m_textBox->ClearBoundingBoxCache();
485 m_textBox->ClearRenderCache();
486
487 VECTOR2I minBoxSize = m_textBox->GetMinSize();
488 VECTOR2I start = m_textBox->GetStart();
489 VECTOR2I end = m_textBox->GetEnd();
490 bool expanded = false;
491
492 if( minBoxSize.x > 0 && std::abs( end.x - start.x ) < minBoxSize.x )
493 {
494 end.x = ( end.x >= start.x ) ? start.x + minBoxSize.x : start.x - minBoxSize.x;
495 expanded = true;
496 }
497
498 if( minBoxSize.y > 0 && std::abs( end.y - start.y ) < minBoxSize.y )
499 {
500 end.y = ( end.y >= start.y ) ? start.y + minBoxSize.y : start.y - minBoxSize.y;
501 expanded = true;
502 }
503
504 if( expanded )
505 m_textBox->SetEnd( end );
506
507 if( pushCommit )
508 commit.Push( _( "Edit Text Box Properties" ) );
509
510 return true;
511}
512
513
515{
517 m_scintillaTricks->CancelAutocomplete();
518
519 event.Skip();
520}
521
522
523void DIALOG_TEXTBOX_PROPERTIES::onSyntaxHelp( wxHyperlinkEvent& aEvent )
524{
526}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
@ text_align_right
@ text_valign_top
@ text_align_left
@ text_valign_center
@ text_align_center
@ text_valign_bottom
@ edit_cmp_symb_links
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
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.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition board.cpp:2229
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition board.cpp:2309
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition dialog_shim.h:79
void SetupStandardButtons(std::map< int, wxString > aLabels={})
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)
DIALOG_TEXTBOX_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Text Box Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU)
void onHalignButton(wxCommandEvent &aEvent) override
void onTextSize(wxCommandEvent &aEvent) override
void onThickness(wxCommandEvent &aEvent) override
void onBoldToggle(wxCommandEvent &aEvent) override
void onAutoTextThickness(wxCommandEvent &aEvent) override
DIALOG_TEXTBOX_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, PCB_TEXTBOX *aTextBox)
void onMultiLineTCLostFocus(wxFocusEvent &event) override
void onSyntaxHelp(wxHyperlinkEvent &aEvent)
void onFontSelected(wxCommandEvent &aEvent) override
void onValignButton(wxCommandEvent &aEvent) override
void onBorderChecked(wxCommandEvent &event) override
EDA_ANGLE Normalize180()
Definition eda_angle.h:268
virtual bool IsStroke() const
Definition font.h:101
Common, abstract interface for edit frames.
int ShowTextBoxPropertiesDialog(PCB_TEXTBOX *aTextBox)
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Display a syntax help window for text variables and expressions.
Definition pcb_text.cpp:873
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
Simple container to manage line stroke parameters.
int GetWidth() const
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
LINE_STYLE GetLineStyle() const
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
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:56
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition eda_text.h:57
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:33
int GetPenSizeForNormal(int aTextSize)
Definition gr_text.cpp:57
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:69
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:750
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
std::vector< FAB_LAYER_COLOR > dummy
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
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.
VECTOR2I end
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683