91 changed files with 5597 additions and 560 deletions
-
133d-viewer/3d_canvas/board_adapter.h
-
3773d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
-
433d-viewer/3d_canvas/create_layer_items.cpp
-
113d-viewer/3d_rendering/raytracing/shapes2D/object_2d.cpp
-
2common/CMakeLists.txt
-
2common/eda_item.cpp
-
2common/eda_shape.cpp
-
32common/eda_text.cpp
-
3common/font/font.cpp
-
14common/font/outline_font.cpp
-
43common/hash_eda.cpp
-
4common/pcb.keywords
-
2eeschema/dialogs/dialog_field_properties_base.cpp
-
2eeschema/dialogs/dialog_field_properties_base.fbp
-
2eeschema/dialogs/dialog_lib_text_properties_base.cpp
-
4eeschema/dialogs/dialog_lib_text_properties_base.fbp
-
24eeschema/dialogs/dialog_lib_textbox_properties_base.cpp
-
26eeschema/dialogs/dialog_lib_textbox_properties_base.fbp
-
12eeschema/lib_textbox.cpp
-
18eeschema/sch_field.cpp
-
3eeschema/sch_field.h
-
12eeschema/sch_textbox.cpp
-
4include/core/typeinfo.h
-
3include/eda_text.h
-
3include/font/outline_font.h
-
2pcbnew/CMakeLists.txt
-
1pcbnew/array_creator.cpp
-
25pcbnew/board.cpp
-
56pcbnew/board_commit.cpp
-
49pcbnew/collectors.cpp
-
7pcbnew/cross-probing.cpp
-
2pcbnew/dialogs/dialog_global_deletion.cpp
-
7pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp
-
340pcbnew/dialogs/dialog_textbox_properties.cpp
-
73pcbnew/dialogs/dialog_textbox_properties.h
-
274pcbnew/dialogs/dialog_textbox_properties_base.cpp
-
2436pcbnew/dialogs/dialog_textbox_properties_base.fbp
-
105pcbnew/dialogs/dialog_textbox_properties_base.h
-
2pcbnew/drc/drc_engine.cpp
-
6pcbnew/drc/drc_test_provider.cpp
-
4pcbnew/drc/drc_test_provider_disallow.cpp
-
37pcbnew/drc/drc_test_provider_text_dims.cpp
-
10pcbnew/edit.cpp
-
1pcbnew/exporters/export_gencad.cpp
-
12pcbnew/exporters/gen_drill_report_files.cpp
-
4pcbnew/exporters/gerber_placefile_writer.cpp
-
79pcbnew/footprint.cpp
-
3pcbnew/footprint_edit_frame.cpp
-
4pcbnew/footprint_editor_utils.cpp
-
11pcbnew/footprint_libraries_utils.cpp
-
4pcbnew/fp_shape.cpp
-
7pcbnew/fp_shape.h
-
406pcbnew/fp_textbox.cpp
-
144pcbnew/fp_textbox.h
-
16pcbnew/kicad_clipboard.cpp
-
3pcbnew/menubar_footprint_editor.cpp
-
3pcbnew/menubar_pcb_editor.cpp
-
1pcbnew/pcb_base_edit_frame.h
-
2pcbnew/pcb_base_frame.cpp
-
1pcbnew/pcb_edit_frame.cpp
-
135pcbnew/pcb_painter.cpp
-
6pcbnew/pcb_painter.h
-
35pcbnew/pcb_shape.cpp
-
12pcbnew/pcb_shape.h
-
1pcbnew/pcb_text.cpp
-
4pcbnew/pcb_text.h
-
340pcbnew/pcb_textbox.cpp
-
127pcbnew/pcb_textbox.h
-
4pcbnew/pcbplot.h
-
2pcbnew/plot_board_layers.cpp
-
63pcbnew/plot_brditems_plotter.cpp
-
236pcbnew/plugins/kicad/pcb_parser.cpp
-
2pcbnew/plugins/kicad/pcb_parser.h
-
107pcbnew/plugins/kicad/pcb_plugin.cpp
-
4pcbnew/plugins/kicad/pcb_plugin.h
-
4pcbnew/router/pns_kicad_iface.cpp
-
2pcbnew/router/pns_router.cpp
-
3pcbnew/toolbars_footprint_editor.cpp
-
3pcbnew/toolbars_pcb_editor.cpp
-
124pcbnew/tools/drawing_tool.cpp
-
21pcbnew/tools/edit_tool.cpp
-
1pcbnew/tools/group_tool.cpp
-
5pcbnew/tools/pcb_actions.cpp
-
1pcbnew/tools/pcb_actions.h
-
18pcbnew/tools/pcb_control.cpp
-
3pcbnew/tools/pcb_grid_helper.cpp
-
60pcbnew/tools/pcb_point_editor.cpp
-
23pcbnew/tools/pcb_selection_tool.cpp
-
2pcbnew/tools/pcb_viewer_tools.cpp
-
5pcbnew/zone_filler.cpp
-
6qa/pcbnew/test_board_item.cpp
@ -0,0 +1,340 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include <widgets/bitmap_button.h>
|
|||
#include <widgets/font_choice.h>
|
|||
#include <dialog_textbox_properties.h>
|
|||
#include <confirm.h>
|
|||
#include <widgets/unit_binder.h>
|
|||
#include <board_commit.h>
|
|||
#include <board.h>
|
|||
#include <footprint.h>
|
|||
#include <string_utils.h>
|
|||
#include <pcb_textbox.h>
|
|||
#include <fp_textbox.h>
|
|||
#include <pcbnew.h>
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <pcb_layer_box_selector.h>
|
|||
#include <wx/valnum.h>
|
|||
#include <math/util.h> // for KiROUND
|
|||
#include <scintilla_tricks.h>
|
|||
#include "macros.h"
|
|||
|
|||
DIALOG_TEXTBOX_PROPERTIES::DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, |
|||
BOARD_ITEM* aItem ) : |
|||
DIALOG_TEXTBOX_PROPERTIES_BASE( aParent ), |
|||
m_frame( aParent ), |
|||
m_item( aItem ), |
|||
m_edaText( nullptr ), |
|||
m_fpTextBox( nullptr ), |
|||
m_pcbTextBox( nullptr ), |
|||
m_textWidth( aParent, m_SizeXLabel, m_SizeXCtrl, m_SizeXUnits ), |
|||
m_textHeight( aParent, m_SizeYLabel, m_SizeYCtrl, m_SizeYUnits ), |
|||
m_thickness( aParent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnits ), |
|||
m_orientation( aParent, m_OrientLabel, m_OrientCtrl, nullptr ) |
|||
{ |
|||
m_MultiLineText->SetEOLMode( wxSTC_EOL_LF ); |
|||
|
|||
m_scintillaTricks = new SCINTILLA_TRICKS( m_MultiLineText, wxT( "{}" ), false, |
|||
[this]() |
|||
{ |
|||
wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) ); |
|||
} ); |
|||
|
|||
// A hack which causes Scintilla to auto-size the text editor canvas
|
|||
// See: https://github.com/jacobslusser/ScintillaNET/issues/216
|
|||
m_MultiLineText->SetScrollWidth( 1 ); |
|||
m_MultiLineText->SetScrollWidthTracking( true ); |
|||
|
|||
if( m_item->Type() == PCB_FP_TEXTBOX_T ) |
|||
{ |
|||
m_fpTextBox = static_cast<FP_TEXTBOX*>( m_item ); |
|||
m_edaText = m_fpTextBox; |
|||
|
|||
// Do not allow locking items in the footprint editor
|
|||
m_cbLocked->Show( false ); |
|||
} |
|||
else if( m_item->Type() == PCB_TEXTBOX_T ) |
|||
{ |
|||
m_pcbTextBox = static_cast<PCB_TEXTBOX*>( m_item ); |
|||
m_edaText = m_pcbTextBox; |
|||
} |
|||
else |
|||
{ |
|||
UNIMPLEMENTED_FOR( m_item->GetClass() ); |
|||
} |
|||
|
|||
SetInitialFocus( m_MultiLineText ); |
|||
|
|||
m_separator0->SetIsSeparator(); |
|||
|
|||
m_bold->SetIsCheckButton(); |
|||
m_bold->SetBitmap( KiBitmap( BITMAPS::text_bold ) ); |
|||
m_italic->SetIsCheckButton(); |
|||
m_italic->SetBitmap( KiBitmap( BITMAPS::text_italic ) ); |
|||
|
|||
m_separator1->SetIsSeparator(); |
|||
|
|||
m_alignLeft->SetIsCheckButton(); |
|||
m_alignLeft->SetBitmap( KiBitmap( BITMAPS::text_align_left ) ); |
|||
m_alignCenter->SetIsCheckButton(); |
|||
m_alignCenter->SetBitmap( KiBitmap( BITMAPS::text_align_center ) ); |
|||
m_alignRight->SetIsCheckButton(); |
|||
m_alignRight->SetBitmap( KiBitmap( BITMAPS::text_align_right ) ); |
|||
|
|||
m_separator2->SetIsSeparator(); |
|||
|
|||
m_mirrored->SetIsCheckButton(); |
|||
m_mirrored->SetBitmap( KiBitmap( BITMAPS::text_mirrored ) ); |
|||
|
|||
m_separator3->SetIsSeparator(); |
|||
|
|||
// Configure the layers list selector. Note that footprints are built outside the current
|
|||
// board and so we may need to show all layers if the text is on an unactivated layer.
|
|||
if( !m_frame->GetBoard()->IsLayerEnabled( m_item->GetLayer() ) ) |
|||
m_LayerSelectionCtrl->ShowNonActivatedLayers( true ); |
|||
|
|||
m_LayerSelectionCtrl->SetLayersHotkeys( false ); |
|||
m_LayerSelectionCtrl->SetBoardFrame( m_frame ); |
|||
m_LayerSelectionCtrl->Resync(); |
|||
|
|||
m_orientation.SetUnits( EDA_UNITS::DEGREES ); |
|||
m_orientation.SetPrecision( 3 ); |
|||
|
|||
// Set predefined rotations in combo dropdown, according to the locale floating point
|
|||
// separator notation
|
|||
double rot_list[] = { 0.0, 90.0, -90.0, 180.0 }; |
|||
|
|||
for( size_t ii = 0; ii < m_OrientCtrl->GetCount() && ii < 4; ++ii ) |
|||
m_OrientCtrl->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) ); |
|||
|
|||
SetupStandardButtons(); |
|||
|
|||
// wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
|
|||
// so we have to listen to wxEVT_CHAR_HOOK events instead.
|
|||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ), |
|||
nullptr, this ); |
|||
|
|||
finishDialogSettings(); |
|||
} |
|||
|
|||
|
|||
DIALOG_TEXTBOX_PROPERTIES::~DIALOG_TEXTBOX_PROPERTIES() |
|||
{ |
|||
Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ), |
|||
nullptr, this ); |
|||
|
|||
delete m_scintillaTricks; |
|||
} |
|||
|
|||
|
|||
int PCB_BASE_EDIT_FRAME::ShowTextBoxPropertiesDialog( BOARD_ITEM* aText ) |
|||
{ |
|||
DIALOG_TEXTBOX_PROPERTIES dlg( this, aText ); |
|||
return dlg.ShowQuasiModal(); |
|||
} |
|||
|
|||
|
|||
bool DIALOG_TEXTBOX_PROPERTIES::TransferDataToWindow() |
|||
{ |
|||
BOARD* board = m_frame->GetBoard(); |
|||
wxString converted = board->ConvertKIIDsToCrossReferences( |
|||
UnescapeString( m_edaText->GetText() ) ); |
|||
|
|||
m_MultiLineText->SetValue( converted ); |
|||
m_MultiLineText->SetSelection( -1, -1 ); |
|||
|
|||
m_cbLocked->SetValue( m_item->IsLocked() ); |
|||
|
|||
m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ); |
|||
|
|||
m_fontCtrl->SetFontSelection( m_edaText->GetFont() ); |
|||
|
|||
m_textWidth.SetValue( m_edaText->GetTextSize().x ); |
|||
m_textHeight.SetValue( m_edaText->GetTextSize().y ); |
|||
m_thickness.SetValue( m_edaText->GetTextThickness() ); |
|||
|
|||
m_bold->Check( m_edaText->IsBold() ); |
|||
m_italic->Check( m_edaText->IsItalic() ); |
|||
|
|||
switch ( m_edaText->GetHorizJustify() ) |
|||
{ |
|||
case GR_TEXT_H_ALIGN_LEFT: m_alignLeft->Check( true ); break; |
|||
case GR_TEXT_H_ALIGN_CENTER: m_alignCenter->Check( true ); break; |
|||
case GR_TEXT_H_ALIGN_RIGHT: m_alignRight->Check( true ); break; |
|||
} |
|||
|
|||
m_mirrored->Check( m_edaText->IsMirrored() ); |
|||
|
|||
m_orientation.SetAngleValue( m_edaText->GetTextAngle() ); |
|||
|
|||
return DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataToWindow(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_TEXTBOX_PROPERTIES::onFontSelected( wxCommandEvent & aEvent ) |
|||
{ |
|||
if( KIFONT::FONT::IsStroke( aEvent.GetString() ) ) |
|||
{ |
|||
m_thickness.Show( true ); |
|||
|
|||
int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() ); |
|||
int thickness = m_thickness.GetValue(); |
|||
|
|||
m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) ) |
|||
< abs( thickness - GetPenSizeForNormal( textSize ) ) ); |
|||
} |
|||
else |
|||
{ |
|||
m_thickness.Show( false ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_TEXTBOX_PROPERTIES::onBoldToggle( wxCommandEvent & aEvent ) |
|||
{ |
|||
int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() ); |
|||
|
|||
if( aEvent.IsChecked() ) |
|||
m_thickness.ChangeValue( GetPenSizeForBold( textSize ) ); |
|||
else |
|||
m_thickness.ChangeValue( GetPenSizeForNormal( textSize ) ); |
|||
|
|||
aEvent.Skip(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_TEXTBOX_PROPERTIES::onAlignButton( wxCommandEvent& aEvent ) |
|||
{ |
|||
for( BITMAP_BUTTON* btn : { m_alignLeft, m_alignCenter, m_alignRight } ) |
|||
{ |
|||
if( btn->IsChecked() && btn != aEvent.GetEventObject() ) |
|||
btn->Check( false ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_TEXTBOX_PROPERTIES::onThickness( wxCommandEvent& event ) |
|||
{ |
|||
int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() ); |
|||
int thickness = m_thickness.GetValue(); |
|||
|
|||
m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) ) |
|||
< abs( thickness - GetPenSizeForNormal( textSize ) ) ); |
|||
} |
|||
|
|||
|
|||
bool DIALOG_TEXTBOX_PROPERTIES::TransferDataFromWindow() |
|||
{ |
|||
if( !DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataFromWindow() ) |
|||
return false; |
|||
|
|||
if( !m_textWidth.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) |
|||
|| !m_textHeight.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) ) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
BOARD_COMMIT commit( m_frame ); |
|||
commit.Modify( m_item ); |
|||
|
|||
// If no other command in progress, prepare undo command
|
|||
// (for a command in progress, will be made later, at the completion of command)
|
|||
bool pushCommit = ( m_item->GetEditFlags() == 0 ); |
|||
|
|||
// Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
|
|||
// SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
|
|||
if( !pushCommit ) |
|||
m_item->SetFlags( IN_EDIT ); |
|||
|
|||
// Set the new text content
|
|||
if( !m_MultiLineText->GetValue().IsEmpty() ) |
|||
{ |
|||
BOARD* board = m_frame->GetBoard(); |
|||
wxString txt = board->ConvertCrossReferencesToKIIDs( m_MultiLineText->GetValue() ); |
|||
|
|||
#ifdef __WXMAC__
|
|||
// On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
|
|||
// Replace it now.
|
|||
txt.Replace( "\r", "\n" ); |
|||
#elif defined( __WINDOWS__ )
|
|||
// On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
|
|||
// drawing routines so strip the \r char.
|
|||
txt.Replace( "\r", "" ); |
|||
#endif
|
|||
m_edaText->SetText( EscapeString( txt, CTX_QUOTED_STR ) ); |
|||
} |
|||
|
|||
m_item->SetLocked( m_cbLocked->GetValue() ); |
|||
|
|||
m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) ); |
|||
|
|||
if( m_fontCtrl->HaveFontSelection() ) |
|||
{ |
|||
m_edaText->SetFont( m_fontCtrl->GetFontSelection( m_bold->IsChecked(), |
|||
m_italic->IsChecked() ) ); |
|||
} |
|||
|
|||
m_edaText->SetTextSize( wxSize( m_textWidth.GetValue(), m_textHeight.GetValue() ) ); |
|||
m_edaText->SetTextThickness( m_thickness.GetValue() ); |
|||
|
|||
if( m_fpTextBox ) |
|||
m_fpTextBox->SetLocalCoord(); |
|||
|
|||
// Test for acceptable values for thickness and size and clamp if fails
|
|||
int maxPenWidth = Clamp_Text_PenSize( m_edaText->GetTextThickness(), m_edaText->GetTextSize() ); |
|||
|
|||
if( m_edaText->GetTextThickness() > maxPenWidth ) |
|||
{ |
|||
DisplayError( this, _( "The text thickness is too large for the text size.\n" |
|||
"It will be clamped." ) ); |
|||
m_edaText->SetTextThickness( maxPenWidth ); |
|||
} |
|||
|
|||
m_edaText->SetTextAngle( m_orientation.GetAngleValue() ); |
|||
m_edaText->SetBold( m_bold->IsChecked() ); |
|||
m_edaText->SetItalic( m_italic->IsChecked() ); |
|||
|
|||
if( m_alignLeft->IsChecked() ) |
|||
m_edaText->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT ); |
|||
else if( m_alignCenter->IsChecked() ) |
|||
m_edaText->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER ); |
|||
else |
|||
m_edaText->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT ); |
|||
|
|||
m_edaText->SetMirrored( m_mirrored->IsChecked() ); |
|||
|
|||
if( pushCommit ) |
|||
commit.Push( _( "Change text box properties" ) ); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void DIALOG_TEXTBOX_PROPERTIES::onMultiLineTCLostFocus( wxFocusEvent& event ) |
|||
{ |
|||
if( m_scintillaTricks ) |
|||
m_scintillaTricks->CancelAutocomplete(); |
|||
|
|||
event.Skip(); |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#ifndef DIALOG_TEXTBOX_PROPERTIES_H |
|||
#define DIALOG_TEXTBOX_PROPERTIES_H |
|||
|
|||
#include <widgets/unit_binder.h> |
|||
#include <wx/valnum.h> |
|||
|
|||
#include <dialog_textbox_properties_base.h> |
|||
|
|||
|
|||
class PCB_BASE_EDIT_FRAME; |
|||
class BOARD_ITEM; |
|||
class EDA_TEXT; |
|||
class FP_TEXTBOX; |
|||
class PCB_TEXTBOX; |
|||
class SCINTILLA_TRICKS; |
|||
|
|||
|
|||
class DIALOG_TEXTBOX_PROPERTIES : public DIALOG_TEXTBOX_PROPERTIES_BASE |
|||
{ |
|||
public: |
|||
DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem ); |
|||
~DIALOG_TEXTBOX_PROPERTIES(); |
|||
|
|||
private: |
|||
void onFontSelected( wxCommandEvent &aEvent ) override; |
|||
void onBoldToggle( wxCommandEvent &aEvent ) override; |
|||
void onAlignButton( wxCommandEvent &aEvent ) override; |
|||
void onThickness( wxCommandEvent &aEvent ) override; |
|||
|
|||
bool TransferDataToWindow() override; |
|||
bool TransferDataFromWindow() override; |
|||
void onMultiLineTCLostFocus( wxFocusEvent& event ) override; |
|||
|
|||
private: |
|||
PCB_BASE_EDIT_FRAME* m_frame; |
|||
BOARD_ITEM* m_item; // FP_TEXTBOX or PCB_TEXTBOX |
|||
EDA_TEXT* m_edaText; // always non-null |
|||
FP_TEXTBOX* m_fpTextBox; // only non-null for FP_TEXTBOXes |
|||
PCB_TEXTBOX* m_pcbTextBox; // only non-null for PCB_TEXTBOXes |
|||
|
|||
UNIT_BINDER m_textWidth; |
|||
UNIT_BINDER m_textHeight; |
|||
UNIT_BINDER m_thickness; |
|||
UNIT_BINDER m_orientation; // rotation in degrees |
|||
|
|||
SCINTILLA_TRICKS* m_scintillaTricks; |
|||
}; |
|||
|
|||
|
|||
#endif //DIALOG_TEXTBOX_PROPERTIES_H |
|||
@ -0,0 +1,274 @@ |
|||
///////////////////////////////////////////////////////////////////////////
|
|||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
|||
// http://www.wxformbuilder.org/
|
|||
//
|
|||
// PLEASE DO *NOT* EDIT THIS FILE!
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#include "pcb_layer_box_selector.h"
|
|||
#include "widgets/bitmap_button.h"
|
|||
#include "widgets/font_choice.h"
|
|||
|
|||
#include "dialog_textbox_properties_base.h"
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
DIALOG_TEXTBOX_PROPERTIES_BASE::DIALOG_TEXTBOX_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) |
|||
{ |
|||
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); |
|||
|
|||
wxBoxSizer* bMainSizer; |
|||
bMainSizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_MultiLineSizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
wxStaticText* textLabel; |
|||
textLabel = new wxStaticText( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
textLabel->Wrap( -1 ); |
|||
m_MultiLineSizer->Add( textLabel, 0, wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
m_MultiLineText = new wxStyledTextCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString ); |
|||
m_MultiLineText->SetUseTabs( true ); |
|||
m_MultiLineText->SetTabWidth( 4 ); |
|||
m_MultiLineText->SetIndent( 4 ); |
|||
m_MultiLineText->SetTabIndents( false ); |
|||
m_MultiLineText->SetBackSpaceUnIndents( false ); |
|||
m_MultiLineText->SetViewEOL( false ); |
|||
m_MultiLineText->SetViewWhiteSpace( false ); |
|||
m_MultiLineText->SetMarginWidth( 2, 0 ); |
|||
m_MultiLineText->SetIndentationGuides( true ); |
|||
m_MultiLineText->SetMarginWidth( 1, 0 ); |
|||
m_MultiLineText->SetMarginWidth( 0, 0 ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS ); |
|||
m_MultiLineText->MarkerSetBackground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("BLACK") ) ); |
|||
m_MultiLineText->MarkerSetForeground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("WHITE") ) ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS ); |
|||
m_MultiLineText->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("BLACK") ) ); |
|||
m_MultiLineText->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("WHITE") ) ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUS ); |
|||
m_MultiLineText->MarkerSetBackground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("BLACK") ) ); |
|||
m_MultiLineText->MarkerSetForeground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("WHITE") ) ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUS ); |
|||
m_MultiLineText->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("BLACK") ) ); |
|||
m_MultiLineText->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("WHITE") ) ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY ); |
|||
m_MultiLineText->MarkerDefine( wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY ); |
|||
m_MultiLineText->SetSelBackground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) ); |
|||
m_MultiLineText->SetSelForeground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); |
|||
m_MultiLineText->SetToolTip( _("Enter the text placed on selected layer.") ); |
|||
m_MultiLineText->SetMinSize( wxSize( -1,150 ) ); |
|||
|
|||
m_MultiLineSizer->Add( m_MultiLineText, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
|
|||
bMainSizer->Add( m_MultiLineSizer, 20, wxEXPAND|wxALL, 10 ); |
|||
|
|||
wxGridBagSizer* gbSizer1; |
|||
gbSizer1 = new wxGridBagSizer( 3, 5 ); |
|||
gbSizer1->SetFlexibleDirection( wxBOTH ); |
|||
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); |
|||
gbSizer1->SetEmptyCellSize( wxSize( 20,8 ) ); |
|||
|
|||
m_cbLocked = new wxCheckBox( this, wxID_ANY, _("Locked"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
gbSizer1->Add( m_cbLocked, wxGBPosition( 0, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
m_LayerLabel = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_LayerLabel->Wrap( -1 ); |
|||
gbSizer1->Add( m_LayerLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); |
|||
|
|||
m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
gbSizer1->Add( m_LayerSelectionCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); |
|||
|
|||
m_fontLabel = new wxStaticText( this, wxID_ANY, _("Font:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_fontLabel->Wrap( -1 ); |
|||
gbSizer1->Add( m_fontLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); |
|||
|
|||
wxString m_fontCtrlChoices[] = { _("KiCad Font") }; |
|||
int m_fontCtrlNChoices = sizeof( m_fontCtrlChoices ) / sizeof( wxString ); |
|||
m_fontCtrl = new FONT_CHOICE( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_fontCtrlNChoices, m_fontCtrlChoices, 0 ); |
|||
m_fontCtrl->SetSelection( 0 ); |
|||
gbSizer1->Add( m_fontCtrl, wxGBPosition( 3, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
wxBoxSizer* bSizerButtonBar; |
|||
bSizerButtonBar = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_separator0 = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
m_separator0->Enable( false ); |
|||
|
|||
bSizerButtonBar->Add( m_separator0, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_bold = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_bold, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_italic = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_italic, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_separator1 = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
m_separator1->Enable( false ); |
|||
|
|||
bSizerButtonBar->Add( m_separator1, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_alignLeft = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_alignLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_alignCenter = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_alignCenter, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_alignRight = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_alignRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_separator2 = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
m_separator2->Enable( false ); |
|||
|
|||
bSizerButtonBar->Add( m_separator2, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_mirrored = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
bSizerButtonBar->Add( m_mirrored, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_separator3 = new BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE ); |
|||
m_separator3->Enable( false ); |
|||
|
|||
bSizerButtonBar->Add( m_separator3, 0, wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
|
|||
gbSizer1->Add( bSizerButtonBar, wxGBPosition( 3, 4 ), wxGBSpan( 1, 3 ), wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT, 8 ); |
|||
|
|||
m_SizeXLabel = new wxStaticText( this, wxID_ANY, _("Text Width:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_SizeXLabel->Wrap( -1 ); |
|||
m_SizeXLabel->SetToolTip( _("Text width") ); |
|||
|
|||
gbSizer1->Add( m_SizeXLabel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_SizeXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); |
|||
gbSizer1->Add( m_SizeXCtrl, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); |
|||
|
|||
m_SizeXUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_SizeXUnits->Wrap( -1 ); |
|||
gbSizer1->Add( m_SizeXUnits, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_SizeYLabel = new wxStaticText( this, wxID_ANY, _("Text Height:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_SizeYLabel->Wrap( -1 ); |
|||
m_SizeYLabel->SetToolTip( _("Text height") ); |
|||
|
|||
gbSizer1->Add( m_SizeYLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_SizeYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); |
|||
gbSizer1->Add( m_SizeYCtrl, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); |
|||
|
|||
m_SizeYUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_SizeYUnits->Wrap( -1 ); |
|||
gbSizer1->Add( m_SizeYUnits, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_ThicknessLabel = new wxStaticText( this, wxID_ANY, _("Thickness:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_ThicknessLabel->Wrap( -1 ); |
|||
m_ThicknessLabel->SetToolTip( _("Text thickness") ); |
|||
|
|||
gbSizer1->Add( m_ThicknessLabel, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_ThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); |
|||
gbSizer1->Add( m_ThicknessCtrl, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); |
|||
|
|||
m_ThicknessUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_ThicknessUnits->Wrap( -1 ); |
|||
gbSizer1->Add( m_ThicknessUnits, wxGBPosition( 6, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_OrientLabel = new wxStaticText( this, wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_OrientLabel->Wrap( -1 ); |
|||
m_OrientLabel->SetToolTip( _("Text orientation") ); |
|||
|
|||
gbSizer1->Add( m_OrientLabel, wxGBPosition( 1, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_OrientCtrl = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
m_OrientCtrl->Append( _("0.0") ); |
|||
m_OrientCtrl->Append( _("90.0") ); |
|||
m_OrientCtrl->Append( _("-90.0") ); |
|||
m_OrientCtrl->Append( _("180.0") ); |
|||
gbSizer1->Add( m_OrientCtrl, wxGBPosition( 1, 5 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT, 5 ); |
|||
|
|||
m_borderWidthLabel = new wxStaticText( this, wxID_ANY, _("Border Width:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_borderWidthLabel->Wrap( -1 ); |
|||
gbSizer1->Add( m_borderWidthLabel, wxGBPosition( 5, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_borderWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); |
|||
gbSizer1->Add( m_borderWidthCtrl, wxGBPosition( 5, 5 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_borderWidthUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_borderWidthUnits->Wrap( -1 ); |
|||
gbSizer1->Add( m_borderWidthUnits, wxGBPosition( 5, 6 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
m_borderStyleLabel = new wxStaticText( this, wxID_ANY, _("Border Style:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_borderStyleLabel->Wrap( -1 ); |
|||
gbSizer1->Add( m_borderStyleLabel, wxGBPosition( 6, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); |
|||
|
|||
m_borderStyleCombo = new wxBitmapComboBox( this, wxID_ANY, _("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ); |
|||
m_borderStyleCombo->SetMinSize( wxSize( 240,-1 ) ); |
|||
|
|||
gbSizer1->Add( m_borderStyleCombo, wxGBPosition( 6, 5 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); |
|||
|
|||
|
|||
gbSizer1->AddGrowableCol( 1 ); |
|||
gbSizer1->AddGrowableCol( 5 ); |
|||
|
|||
bMainSizer->Add( gbSizer1, 0, wxRIGHT|wxLEFT|wxEXPAND, 10 ); |
|||
|
|||
m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); |
|||
bMainSizer->Add( m_staticline, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); |
|||
|
|||
wxBoxSizer* lowerSizer; |
|||
lowerSizer = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
|
|||
lowerSizer->Add( 0, 0, 1, wxEXPAND, 5 ); |
|||
|
|||
m_sdbSizer = new wxStdDialogButtonSizer(); |
|||
m_sdbSizerOK = new wxButton( this, wxID_OK ); |
|||
m_sdbSizer->AddButton( m_sdbSizerOK ); |
|||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); |
|||
m_sdbSizer->AddButton( m_sdbSizerCancel ); |
|||
m_sdbSizer->Realize(); |
|||
|
|||
lowerSizer->Add( m_sdbSizer, 0, wxALL, 5 ); |
|||
|
|||
|
|||
bMainSizer->Add( lowerSizer, 0, wxEXPAND, 5 ); |
|||
|
|||
|
|||
this->SetSizer( bMainSizer ); |
|||
this->Layout(); |
|||
bMainSizer->Fit( this ); |
|||
|
|||
this->Centre( wxBOTH ); |
|||
|
|||
// Connect Events
|
|||
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnInitDlg ) ); |
|||
m_MultiLineText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this ); |
|||
m_fontCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onFontSelected ), NULL, this ); |
|||
m_bold->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onBoldToggle ), NULL, this ); |
|||
m_alignLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_alignCenter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_alignRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_SizeXCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_SizeYCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_ThicknessCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onThickness ), NULL, this ); |
|||
m_OrientCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
} |
|||
|
|||
DIALOG_TEXTBOX_PROPERTIES_BASE::~DIALOG_TEXTBOX_PROPERTIES_BASE() |
|||
{ |
|||
// Disconnect Events
|
|||
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnInitDlg ) ); |
|||
m_MultiLineText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this ); |
|||
m_fontCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onFontSelected ), NULL, this ); |
|||
m_bold->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onBoldToggle ), NULL, this ); |
|||
m_alignLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_alignCenter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_alignRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onAlignButton ), NULL, this ); |
|||
m_SizeXCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_SizeYCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_ThicknessCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::onThickness ), NULL, this ); |
|||
m_OrientCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEXTBOX_PROPERTIES_BASE::OnOkClick ), NULL, this ); |
|||
|
|||
} |
|||
2436
pcbnew/dialogs/dialog_textbox_properties_base.fbp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,105 @@ |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
// C++ code generated with wxFormBuilder (version Oct 26 2018) |
|||
// http://www.wxformbuilder.org/ |
|||
// |
|||
// PLEASE DO *NOT* EDIT THIS FILE! |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#pragma once |
|||
|
|||
#include <wx/artprov.h> |
|||
#include <wx/xrc/xmlres.h> |
|||
#include <wx/intl.h> |
|||
class BITMAP_BUTTON; |
|||
class FONT_CHOICE; |
|||
class PCB_LAYER_BOX_SELECTOR; |
|||
|
|||
#include "dialog_shim.h" |
|||
#include <wx/string.h> |
|||
#include <wx/stattext.h> |
|||
#include <wx/gdicmn.h> |
|||
#include <wx/font.h> |
|||
#include <wx/colour.h> |
|||
#include <wx/settings.h> |
|||
#include <wx/stc/stc.h> |
|||
#include <wx/sizer.h> |
|||
#include <wx/checkbox.h> |
|||
#include <wx/bmpcbox.h> |
|||
#include <wx/choice.h> |
|||
#include <wx/bmpbuttn.h> |
|||
#include <wx/bitmap.h> |
|||
#include <wx/image.h> |
|||
#include <wx/icon.h> |
|||
#include <wx/button.h> |
|||
#include <wx/textctrl.h> |
|||
#include <wx/combobox.h> |
|||
#include <wx/gbsizer.h> |
|||
#include <wx/statline.h> |
|||
#include <wx/dialog.h> |
|||
|
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class DIALOG_TEXTBOX_PROPERTIES_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class DIALOG_TEXTBOX_PROPERTIES_BASE : public DIALOG_SHIM |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxBoxSizer* m_MultiLineSizer; |
|||
wxStyledTextCtrl* m_MultiLineText; |
|||
wxCheckBox* m_cbLocked; |
|||
wxStaticText* m_LayerLabel; |
|||
PCB_LAYER_BOX_SELECTOR* m_LayerSelectionCtrl; |
|||
wxStaticText* m_fontLabel; |
|||
FONT_CHOICE* m_fontCtrl; |
|||
BITMAP_BUTTON* m_separator0; |
|||
BITMAP_BUTTON* m_bold; |
|||
BITMAP_BUTTON* m_italic; |
|||
BITMAP_BUTTON* m_separator1; |
|||
BITMAP_BUTTON* m_alignLeft; |
|||
BITMAP_BUTTON* m_alignCenter; |
|||
BITMAP_BUTTON* m_alignRight; |
|||
BITMAP_BUTTON* m_separator2; |
|||
BITMAP_BUTTON* m_mirrored; |
|||
BITMAP_BUTTON* m_separator3; |
|||
wxStaticText* m_SizeXLabel; |
|||
wxTextCtrl* m_SizeXCtrl; |
|||
wxStaticText* m_SizeXUnits; |
|||
wxStaticText* m_SizeYLabel; |
|||
wxTextCtrl* m_SizeYCtrl; |
|||
wxStaticText* m_SizeYUnits; |
|||
wxStaticText* m_ThicknessLabel; |
|||
wxTextCtrl* m_ThicknessCtrl; |
|||
wxStaticText* m_ThicknessUnits; |
|||
wxStaticText* m_OrientLabel; |
|||
wxComboBox* m_OrientCtrl; |
|||
wxStaticText* m_borderWidthLabel; |
|||
wxTextCtrl* m_borderWidthCtrl; |
|||
wxStaticText* m_borderWidthUnits; |
|||
wxStaticText* m_borderStyleLabel; |
|||
wxBitmapComboBox* m_borderStyleCombo; |
|||
wxStaticLine* m_staticline; |
|||
wxStdDialogButtonSizer* m_sdbSizer; |
|||
wxButton* m_sdbSizerOK; |
|||
wxButton* m_sdbSizerCancel; |
|||
|
|||
// Virtual event handlers, overide them in your derived class |
|||
virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); } |
|||
virtual void onMultiLineTCLostFocus( wxFocusEvent& event ) { event.Skip(); } |
|||
virtual void onFontSelected( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void onBoldToggle( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void onAlignButton( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); } |
|||
virtual void onThickness( wxCommandEvent& event ) { event.Skip(); } |
|||
|
|||
|
|||
public: |
|||
|
|||
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 ); |
|||
~DIALOG_TEXTBOX_PROPERTIES_BASE(); |
|||
|
|||
}; |
|||
|
|||
@ -0,0 +1,406 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <base_units.h>
|
|||
#include <bitmaps.h>
|
|||
#include <board.h>
|
|||
#include <board_design_settings.h>
|
|||
#include <core/mirror.h>
|
|||
#include <footprint.h>
|
|||
#include <fp_textbox.h>
|
|||
#include <settings/settings_manager.h>
|
|||
#include <trigo.h>
|
|||
#include <string_utils.h>
|
|||
#include <painter.h>
|
|||
#include <geometry/shape_compound.h>
|
|||
#include <callback_gal.h>
|
|||
#include <convert_basic_shapes_to_polygon.h>
|
|||
|
|||
FP_TEXTBOX::FP_TEXTBOX( FOOTPRINT* aParentFootprint ) : |
|||
FP_SHAPE( aParentFootprint, SHAPE_T::RECT, PCB_FP_TEXTBOX_T ), |
|||
EDA_TEXT() |
|||
{ |
|||
SetHorizJustify( GR_TEXT_H_ALIGN_LEFT ); |
|||
SetVertJustify( GR_TEXT_V_ALIGN_TOP ); |
|||
SetMultilineAllowed( true ); |
|||
|
|||
SetDrawCoord(); |
|||
} |
|||
|
|||
|
|||
FP_TEXTBOX::~FP_TEXTBOX() |
|||
{ |
|||
} |
|||
|
|||
|
|||
int FP_TEXTBOX::GetTextMargin() const |
|||
{ |
|||
return KiROUND( GetTextSize().y * 0.8 ); |
|||
} |
|||
|
|||
|
|||
EDA_ANGLE FP_TEXTBOX::GetDrawRotation() const |
|||
{ |
|||
FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent ); |
|||
EDA_ANGLE rotation = GetTextAngle(); |
|||
|
|||
if( parentFootprint ) |
|||
rotation += parentFootprint->GetOrientation(); |
|||
|
|||
rotation.Normalize(); |
|||
|
|||
return rotation; |
|||
} |
|||
|
|||
|
|||
std::vector<VECTOR2I> FP_TEXTBOX::GetAnchorAndOppositeCorner() const |
|||
{ |
|||
std::vector<VECTOR2I> pts; |
|||
std::vector<VECTOR2I> corners = GetCorners(); |
|||
|
|||
EDA_ANGLE toCorner1( corners[0] - corners[1] ); |
|||
EDA_ANGLE toCorner3( corners[0] - corners[3] ); |
|||
EDA_ANGLE textAngle( GetDrawRotation() ); |
|||
toCorner1.Normalize(); |
|||
toCorner3.Normalize(); |
|||
textAngle.Normalize(); |
|||
|
|||
pts.emplace_back( corners[0] ); |
|||
|
|||
if( std::abs( toCorner1 - textAngle ) < std::abs( toCorner3 - textAngle ) ) |
|||
pts.emplace_back( corners[1] ); |
|||
else |
|||
pts.emplace_back( corners[3] ); |
|||
|
|||
return pts; |
|||
} |
|||
|
|||
|
|||
VECTOR2I FP_TEXTBOX::GetDrawPos() const |
|||
{ |
|||
std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner(); |
|||
GR_TEXT_H_ALIGN_T effectiveAlignment = GetHorizJustify(); |
|||
VECTOR2I textAnchor; |
|||
VECTOR2I offset; |
|||
|
|||
if( IsMirrored() ) |
|||
{ |
|||
switch( GetHorizJustify() ) |
|||
{ |
|||
case GR_TEXT_H_ALIGN_LEFT: effectiveAlignment = GR_TEXT_H_ALIGN_RIGHT; break; |
|||
case GR_TEXT_H_ALIGN_CENTER: effectiveAlignment = GR_TEXT_H_ALIGN_CENTER; break; |
|||
case GR_TEXT_H_ALIGN_RIGHT: effectiveAlignment = GR_TEXT_H_ALIGN_LEFT; break; |
|||
} |
|||
} |
|||
|
|||
switch( effectiveAlignment ) |
|||
{ |
|||
case GR_TEXT_H_ALIGN_LEFT: |
|||
textAnchor = corners[0]; |
|||
offset = VECTOR2I( GetTextMargin(), GetTextMargin() ); |
|||
break; |
|||
case GR_TEXT_H_ALIGN_CENTER: |
|||
textAnchor = ( corners[0] + corners[1] ) / 2; |
|||
offset = VECTOR2I( 0, GetTextMargin() ); |
|||
break; |
|||
case GR_TEXT_H_ALIGN_RIGHT: |
|||
textAnchor = corners[1]; |
|||
offset = VECTOR2I( -GetTextMargin(), GetTextMargin() ); |
|||
break; |
|||
} |
|||
|
|||
RotatePoint( offset, GetDrawRotation() ); |
|||
return textAnchor + offset; |
|||
} |
|||
|
|||
|
|||
bool FP_TEXTBOX::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const |
|||
{ |
|||
EDA_RECT rect = GetBoundingBox(); |
|||
|
|||
rect.Inflate( aAccuracy ); |
|||
|
|||
return rect.Contains( aPosition ); |
|||
} |
|||
|
|||
|
|||
bool FP_TEXTBOX::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const |
|||
{ |
|||
EDA_RECT rect = aRect; |
|||
|
|||
rect.Inflate( aAccuracy ); |
|||
|
|||
if( aContained ) |
|||
return rect.Contains( GetBoundingBox() ); |
|||
|
|||
return rect.Intersects( GetBoundingBox() ); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) |
|||
{ |
|||
FP_SHAPE::Rotate( aRotCentre, aAngle ); |
|||
SetTextAngle( GetTextAngle() + aAngle ); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) |
|||
{ |
|||
// flipping the footprint is relative to the X axis
|
|||
if( aFlipLeftRight ) |
|||
{ |
|||
SetTextX( MIRRORVAL( GetTextPos().x, aCentre.x ) ); |
|||
SetTextAngle( -GetTextAngle() ); |
|||
} |
|||
else |
|||
{ |
|||
SetTextY( MIRRORVAL( GetTextPos().y, aCentre.y ) ); |
|||
SetTextAngle( ANGLE_180 - GetTextAngle() ); |
|||
} |
|||
|
|||
SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) ); |
|||
SetMirrored( IsBackLayer( GetLayer() ) ); |
|||
SetLocalCoord(); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis ) |
|||
{ |
|||
// the position is mirrored, but the text itself is not mirrored
|
|||
|
|||
if( aMirrorAroundXAxis ) |
|||
SetTextY( ::MIRRORVAL( GetTextPos().y, aCentre.y ) ); |
|||
else |
|||
SetTextX( ::MIRRORVAL( GetTextPos().x, aCentre.x ) ); |
|||
|
|||
SetLocalCoord(); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) |
|||
{ |
|||
EDA_UNITS units = aFrame->GetUserUnits(); |
|||
|
|||
// Don't use GetShownText() here; we want to show the user the variable references
|
|||
aList.emplace_back( _( "Text Box" ), UnescapeString( GetText() ) ); |
|||
|
|||
if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() ) |
|||
aList.emplace_back( _( "Status" ), _( "Locked" ) ); |
|||
|
|||
aList.emplace_back( _( "Layer" ), GetLayerName() ); |
|||
aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) ); |
|||
aList.emplace_back( _( "Angle" ), wxString::Format( "%g", GetTextAngle().AsDegrees() ) ); |
|||
|
|||
aList.emplace_back( _( "Thickness" ), MessageTextFromValue( units, GetTextThickness() ) ); |
|||
aList.emplace_back( _( "Width" ), MessageTextFromValue( units, GetTextWidth() ) ); |
|||
aList.emplace_back( _( "Height" ), MessageTextFromValue( units, GetTextHeight() ) ); |
|||
} |
|||
|
|||
|
|||
wxString FP_TEXTBOX::GetSelectMenuText( EDA_UNITS aUnits ) const |
|||
{ |
|||
return wxString::Format( _( "Footprint Text Box of %s" ), |
|||
static_cast<FOOTPRINT*>( GetParent() )->GetReference() ); |
|||
} |
|||
|
|||
|
|||
BITMAPS FP_TEXTBOX::GetMenuImage() const |
|||
{ |
|||
return BITMAPS::add_textbox; |
|||
} |
|||
|
|||
|
|||
EDA_ITEM* FP_TEXTBOX::Clone() const |
|||
{ |
|||
return new FP_TEXTBOX( *this ); |
|||
} |
|||
|
|||
|
|||
const BOX2I FP_TEXTBOX::ViewBBox() const |
|||
{ |
|||
EDA_ANGLE angle = GetDrawRotation(); |
|||
EDA_RECT text_area = GetTextBox(); |
|||
|
|||
if( !angle.IsZero() ) |
|||
text_area = text_area.GetBoundingBoxRotated( GetDrawPos(), angle ); |
|||
|
|||
return BOX2I( text_area.GetPosition(), text_area.GetSize() ); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::ViewGetLayers( int aLayers[], int& aCount ) const |
|||
{ |
|||
if( IsVisible() ) |
|||
aLayers[0] = GetLayer(); |
|||
else |
|||
aLayers[0] = LAYER_MOD_TEXT_INVISIBLE; |
|||
|
|||
aCount = 1; |
|||
} |
|||
|
|||
|
|||
double FP_TEXTBOX::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const |
|||
{ |
|||
constexpr double HIDE = (double)std::numeric_limits<double>::max(); |
|||
|
|||
if( !aView ) |
|||
return 0.0; |
|||
|
|||
// Hidden text gets put on the LAYER_MOD_TEXT_INVISIBLE for rendering, but
|
|||
// should only render if its native layer is visible.
|
|||
if( !aView->IsLayerVisible( GetLayer() ) ) |
|||
return HIDE; |
|||
|
|||
RENDER_SETTINGS* renderSettings = aView->GetPainter()->GetSettings(); |
|||
COLOR4D backgroundColor = renderSettings->GetLayerColor( LAYER_PCB_BACKGROUND ); |
|||
|
|||
// Handle Render tab switches
|
|||
if( renderSettings->GetLayerColor( LAYER_MOD_TEXT ) == backgroundColor ) |
|||
return HIDE; |
|||
|
|||
if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) ) |
|||
return HIDE; |
|||
|
|||
if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) ) |
|||
return HIDE; |
|||
|
|||
if( !aView->IsLayerVisible( LAYER_MOD_TEXT ) ) |
|||
return HIDE; |
|||
|
|||
// Other layers are shown without any conditions
|
|||
return 0.0; |
|||
} |
|||
|
|||
|
|||
wxString FP_TEXTBOX::GetShownText( int aDepth ) const |
|||
{ |
|||
const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() ); |
|||
wxASSERT( parentFootprint ); |
|||
const BOARD* board = parentFootprint->GetBoard(); |
|||
|
|||
std::function<bool( wxString* )> footprintResolver = |
|||
[&]( wxString* token ) -> bool |
|||
{ |
|||
return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth ); |
|||
}; |
|||
|
|||
std::function<bool( wxString* )> boardTextResolver = |
|||
[&]( wxString* token ) -> bool |
|||
{ |
|||
return board->ResolveTextVar( token, aDepth + 1 ); |
|||
}; |
|||
|
|||
wxString text = EDA_TEXT::GetShownText(); |
|||
|
|||
if( HasTextVars() ) |
|||
{ |
|||
PROJECT* project = nullptr; |
|||
|
|||
if( parentFootprint && parentFootprint->GetParent() ) |
|||
project = static_cast<BOARD*>( parentFootprint->GetParent() )->GetProject(); |
|||
|
|||
if( aDepth < 10 ) |
|||
text = ExpandTextVars( text, &footprintResolver, &boardTextResolver, project ); |
|||
} |
|||
|
|||
KIFONT::FONT* font = GetDrawFont(); |
|||
std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner(); |
|||
int colWidth = ( corners[1] - corners[0] ).EuclideanNorm(); |
|||
|
|||
colWidth -= GetTextMargin() * 2; |
|||
font->LinebreakText( text, colWidth, GetTextSize(), GetTextThickness(), IsBold(), IsItalic() ); |
|||
|
|||
return text; |
|||
} |
|||
|
|||
|
|||
std::shared_ptr<SHAPE> FP_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer ) const |
|||
{ |
|||
return GetEffectiveTextShape(); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearance, |
|||
int aError, ERROR_LOC aErrorLoc ) const |
|||
{ |
|||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts; |
|||
KIFONT::FONT* font = GetDrawFont(); |
|||
int penWidth = GetEffectiveTextPenWidth(); |
|||
|
|||
CALLBACK_GAL callback_gal( empty_opts, |
|||
// Stroke callback
|
|||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) |
|||
{ |
|||
TransformOvalToPolygon( aCornerBuffer, aPt1, aPt2, penWidth + ( 2 * aClearance ), |
|||
aError, ERROR_INSIDE ); |
|||
}, |
|||
// Triangulation callback
|
|||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) |
|||
{ |
|||
aCornerBuffer.NewOutline(); |
|||
|
|||
for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) |
|||
aCornerBuffer.Append( point.x, point.y ); |
|||
} ); |
|||
|
|||
TEXT_ATTRIBUTES attrs = GetAttributes(); |
|||
attrs.m_Angle = GetDrawRotation(); |
|||
|
|||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs ); |
|||
} |
|||
|
|||
|
|||
void FP_TEXTBOX::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearance, |
|||
int aError, ERROR_LOC aErrorLoc, |
|||
bool aIgnoreLineWidth ) const |
|||
{ |
|||
if( PCB_SHAPE::GetStroke().GetWidth() >= 0 ) |
|||
{ |
|||
FP_SHAPE::TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, aClearance, |
|||
aError, aErrorLoc ); |
|||
} |
|||
else |
|||
{ |
|||
EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance ); |
|||
} |
|||
} |
|||
|
|||
|
|||
static struct FP_TEXTBOX_DESC |
|||
{ |
|||
FP_TEXTBOX_DESC() |
|||
{ |
|||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); |
|||
REGISTER_TYPE( FP_TEXTBOX ); |
|||
propMgr.AddTypeCast( new TYPE_CAST<FP_TEXTBOX, FP_SHAPE> ); |
|||
propMgr.AddTypeCast( new TYPE_CAST<FP_TEXTBOX, EDA_TEXT> ); |
|||
propMgr.InheritsAfter( TYPE_HASH( FP_TEXTBOX ), TYPE_HASH( FP_SHAPE ) ); |
|||
propMgr.InheritsAfter( TYPE_HASH( FP_TEXTBOX ), TYPE_HASH( EDA_TEXT ) ); |
|||
|
|||
propMgr.AddProperty( new PROPERTY<FP_TEXTBOX, wxString>( _HKI( "Parent" ), |
|||
NO_SETTER( FP_TEXTBOX, wxString ), &FP_TEXTBOX::GetParentAsString ) ); |
|||
} |
|||
} _FP_TEXTBOX_DESC; |
|||
@ -0,0 +1,144 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#ifndef FP_TEXTBOX_H |
|||
#define FP_TEXTBOX_H |
|||
|
|||
#include <eda_text.h> |
|||
#include <fp_shape.h> |
|||
|
|||
class LINE_READER; |
|||
class EDA_RECT; |
|||
class FOOTPRINT; |
|||
class MSG_PANEL_ITEM; |
|||
class PCB_BASE_FRAME; |
|||
class SHAPE; |
|||
|
|||
|
|||
class FP_TEXTBOX : public FP_SHAPE, public EDA_TEXT |
|||
{ |
|||
public: |
|||
FP_TEXTBOX( FOOTPRINT* aParentFootprint ); |
|||
|
|||
// Do not create a copy constructor & operator=. |
|||
// The ones generated by the compiler are adequate. |
|||
|
|||
~FP_TEXTBOX(); |
|||
|
|||
static inline bool ClassOf( const EDA_ITEM* aItem ) |
|||
{ |
|||
return aItem && aItem->Type() == PCB_FP_TEXT_T; |
|||
} |
|||
|
|||
bool IsType( const KICAD_T aScanTypes[] ) const override |
|||
{ |
|||
if( BOARD_ITEM::IsType( aScanTypes ) ) |
|||
return true; |
|||
|
|||
for( const KICAD_T* p = aScanTypes; *p != EOT; ++p ) |
|||
{ |
|||
if( *p == PCB_LOCATE_TEXT_T ) |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
wxString GetParentAsString() const { return m_parent->m_Uuid.AsString(); } |
|||
|
|||
bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override |
|||
{ |
|||
return BOARD_ITEM::Matches( GetShownText(), aSearchData ); |
|||
} |
|||
|
|||
int GetTextMargin() const; |
|||
|
|||
virtual EDA_ANGLE GetDrawRotation() const override; |
|||
|
|||
VECTOR2I GetDrawPos() const override; |
|||
|
|||
std::vector<VECTOR2I> GetAnchorAndOppositeCorner() const; |
|||
|
|||
/// Rotate text, in footprint editor |
|||
/// (for instance in footprint rotation transform) |
|||
void Rotate( const VECTOR2I& aOffset, const EDA_ANGLE& aAngle ) override; |
|||
|
|||
/// Flip entity during footprint flip |
|||
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override; |
|||
|
|||
/// Mirror text position in footprint editing |
|||
/// the text itself is not mirrored, and the layer not modified, |
|||
/// only position is mirrored. |
|||
/// (use Flip to change layer to its paired and mirror the text in fp editor). |
|||
void Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis ); |
|||
|
|||
// The Pos0 accessors are for footprint-relative coordinates. |
|||
void SetPos0( const VECTOR2I& aPos ) { m_Pos0 = aPos; SetDrawCoord(); } |
|||
const VECTOR2I& GetPos0() const { return m_Pos0; } |
|||
|
|||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override; |
|||
|
|||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy ) const override; |
|||
|
|||
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; |
|||
|
|||
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, |
|||
int aClearance, int aError, ERROR_LOC aErrorLoc, |
|||
bool aIgnoreLineWidth ) const override; |
|||
|
|||
void TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearanceValue, |
|||
int aError, ERROR_LOC aErrorLoc ) const; |
|||
|
|||
// @copydoc BOARD_ITEM::GetEffectiveShape |
|||
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override; |
|||
|
|||
wxString GetClass() const override |
|||
{ |
|||
return wxT( "MTEXT" ); |
|||
} |
|||
|
|||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; |
|||
|
|||
BITMAPS GetMenuImage() const override; |
|||
|
|||
EDA_ITEM* Clone() const override; |
|||
|
|||
virtual wxString GetShownText( int aDepth = 0 ) const override; |
|||
|
|||
virtual const BOX2I ViewBBox() const override; |
|||
|
|||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; |
|||
|
|||
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; |
|||
|
|||
#if defined(DEBUG) |
|||
virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } |
|||
#endif |
|||
|
|||
private: |
|||
VECTOR2I m_Pos0; ///< text coordinates relative to the footprint anchor, orient 0. |
|||
///< text coordinate ref point is the text center |
|||
}; |
|||
|
|||
#endif // FP_TEXTBOX_H |
|||
@ -0,0 +1,340 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include <pcb_edit_frame.h>
|
|||
#include <base_units.h>
|
|||
#include <bitmaps.h>
|
|||
#include <board.h>
|
|||
#include <board_design_settings.h>
|
|||
#include <footprint.h>
|
|||
#include <pcb_textbox.h>
|
|||
#include <pcb_painter.h>
|
|||
#include <trigo.h>
|
|||
#include <string_utils.h>
|
|||
#include <geometry/shape_compound.h>
|
|||
#include <callback_gal.h>
|
|||
#include <convert_basic_shapes_to_polygon.h>
|
|||
#include "macros.h"
|
|||
|
|||
using KIGFX::PCB_RENDER_SETTINGS; |
|||
|
|||
|
|||
PCB_TEXTBOX::PCB_TEXTBOX( BOARD_ITEM* parent ) : |
|||
PCB_SHAPE( parent, PCB_TEXTBOX_T, SHAPE_T::RECT ), |
|||
EDA_TEXT() |
|||
{ |
|||
SetHorizJustify( GR_TEXT_H_ALIGN_LEFT ); |
|||
SetVertJustify( GR_TEXT_V_ALIGN_TOP ); |
|||
SetMultilineAllowed( true ); |
|||
} |
|||
|
|||
|
|||
PCB_TEXTBOX::~PCB_TEXTBOX() |
|||
{ |
|||
} |
|||
|
|||
|
|||
int PCB_TEXTBOX::GetTextMargin() const |
|||
{ |
|||
return KiROUND( GetTextSize().y * 0.8 ); |
|||
} |
|||
|
|||
|
|||
std::vector<VECTOR2I> PCB_TEXTBOX::GetAnchorAndOppositeCorner() const |
|||
{ |
|||
EDA_ANGLE epsilon( 1.0, DEGREES_T ); // Yeah, it's a pretty coarse epsilon, but anything
|
|||
// under 45° will work for our purposes.
|
|||
|
|||
std::vector<VECTOR2I> pts; |
|||
std::vector<VECTOR2I> corners = GetCorners(); |
|||
|
|||
EDA_ANGLE textAngle = GetDrawRotation().Normalize(); |
|||
EDA_ANGLE toCorner1 = EDA_ANGLE( corners[1] - corners[0] ).Normalize(); |
|||
EDA_ANGLE fromCorner1 = ( toCorner1 + ANGLE_180 ).Normalize(); |
|||
|
|||
pts.emplace_back( corners[0] ); |
|||
|
|||
if( std::abs( toCorner1 - textAngle ) < epsilon || std::abs( fromCorner1 - textAngle ) < epsilon ) |
|||
pts.emplace_back( corners[1] ); |
|||
else |
|||
pts.emplace_back( corners[3] ); |
|||
|
|||
return pts; |
|||
} |
|||
|
|||
|
|||
VECTOR2I PCB_TEXTBOX::GetDrawPos() const |
|||
{ |
|||
std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner(); |
|||
GR_TEXT_H_ALIGN_T effectiveAlignment = GetHorizJustify(); |
|||
VECTOR2I textAnchor; |
|||
VECTOR2I offset; |
|||
|
|||
if( IsMirrored() ) |
|||
{ |
|||
switch( GetHorizJustify() ) |
|||
{ |
|||
case GR_TEXT_H_ALIGN_LEFT: effectiveAlignment = GR_TEXT_H_ALIGN_RIGHT; break; |
|||
case GR_TEXT_H_ALIGN_CENTER: effectiveAlignment = GR_TEXT_H_ALIGN_CENTER; break; |
|||
case GR_TEXT_H_ALIGN_RIGHT: effectiveAlignment = GR_TEXT_H_ALIGN_LEFT; break; |
|||
} |
|||
} |
|||
|
|||
switch( effectiveAlignment ) |
|||
{ |
|||
case GR_TEXT_H_ALIGN_LEFT: |
|||
textAnchor = corners[0]; |
|||
offset = VECTOR2I( GetTextMargin(), GetTextMargin() ); |
|||
break; |
|||
case GR_TEXT_H_ALIGN_CENTER: |
|||
textAnchor = ( corners[0] + corners[1] ) / 2; |
|||
offset = VECTOR2I( 0, GetTextMargin() ); |
|||
break; |
|||
case GR_TEXT_H_ALIGN_RIGHT: |
|||
textAnchor = corners[1]; |
|||
offset = VECTOR2I( -GetTextMargin(), GetTextMargin() ); |
|||
break; |
|||
} |
|||
|
|||
RotatePoint( offset, GetDrawRotation() ); |
|||
return textAnchor + offset; |
|||
} |
|||
|
|||
|
|||
wxString PCB_TEXTBOX::GetShownText( int aDepth ) const |
|||
{ |
|||
BOARD* board = dynamic_cast<BOARD*>( GetParent() ); |
|||
|
|||
std::function<bool( wxString* )> pcbTextResolver = |
|||
[&]( wxString* token ) -> bool |
|||
{ |
|||
if( token->IsSameAs( wxT( "LAYER" ) ) ) |
|||
{ |
|||
*token = GetLayerName(); |
|||
return true; |
|||
} |
|||
|
|||
if( token->Contains( ':' ) ) |
|||
{ |
|||
wxString remainder; |
|||
wxString ref = token->BeforeFirst( ':', &remainder ); |
|||
BOARD_ITEM* refItem = board->GetItem( KIID( ref ) ); |
|||
|
|||
if( refItem && refItem->Type() == PCB_FOOTPRINT_T ) |
|||
{ |
|||
FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem ); |
|||
|
|||
if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) ) |
|||
{ |
|||
*token = remainder; |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
std::function<bool( wxString* )> boardTextResolver = |
|||
[&]( wxString* token ) -> bool |
|||
{ |
|||
return board->ResolveTextVar( token, aDepth + 1 ); |
|||
}; |
|||
|
|||
wxString text = EDA_TEXT::GetShownText(); |
|||
|
|||
if( board && HasTextVars() && aDepth < 10 ) |
|||
text = ExpandTextVars( text, &pcbTextResolver, &boardTextResolver, board->GetProject() ); |
|||
|
|||
KIFONT::FONT* font = GetDrawFont(); |
|||
std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner(); |
|||
int colWidth = ( corners[1] - corners[0] ).EuclideanNorm(); |
|||
|
|||
colWidth -= GetTextMargin() * 2; |
|||
font->LinebreakText( text, colWidth, GetTextSize(), GetTextThickness(), IsBold(), IsItalic() ); |
|||
|
|||
return text; |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) |
|||
{ |
|||
EDA_UNITS units = aFrame->GetUserUnits(); |
|||
|
|||
// Don't use GetShownText() here; we want to show the user the variable references
|
|||
aList.emplace_back( _( "Text Box" ), UnescapeString( GetText() ) ); |
|||
|
|||
if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() ) |
|||
aList.emplace_back( _( "Status" ), _( "Locked" ) ); |
|||
|
|||
aList.emplace_back( _( "Layer" ), GetLayerName() ); |
|||
aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) ); |
|||
aList.emplace_back( _( "Angle" ), wxString::Format( "%g", GetTextAngle().AsDegrees() ) ); |
|||
|
|||
aList.emplace_back( _( "Thickness" ), MessageTextFromValue( units, GetTextThickness() ) ); |
|||
aList.emplace_back( _( "Width" ), MessageTextFromValue( units, GetTextWidth() ) ); |
|||
aList.emplace_back( _( "Height" ), MessageTextFromValue( units, GetTextHeight() ) ); |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) |
|||
{ |
|||
PCB_SHAPE::Rotate( aRotCentre, aAngle ); |
|||
SetTextAngle( GetTextAngle() + aAngle ); |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) |
|||
{ |
|||
if( aFlipLeftRight ) |
|||
{ |
|||
m_start.x = aCentre.x - ( m_start.x - aCentre.x ); |
|||
m_end.x = aCentre.x - ( m_end.x - aCentre.x ); |
|||
SetTextAngle( -GetTextAngle() ); |
|||
} |
|||
else |
|||
{ |
|||
m_start.y = aCentre.y - ( m_start.y - aCentre.y ); |
|||
m_end.y = aCentre.y - ( m_end.y - aCentre.y ); |
|||
SetTextAngle( ANGLE_180 - GetTextAngle() ); |
|||
} |
|||
|
|||
SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) ); |
|||
SetMirrored( !IsMirrored() ); |
|||
} |
|||
|
|||
|
|||
bool PCB_TEXTBOX::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const |
|||
{ |
|||
EDA_RECT rect = GetBoundingBox(); |
|||
|
|||
rect.Inflate( aAccuracy ); |
|||
|
|||
return rect.Contains( aPosition ); |
|||
} |
|||
|
|||
|
|||
bool PCB_TEXTBOX::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const |
|||
{ |
|||
EDA_RECT rect = aRect; |
|||
|
|||
rect.Inflate( aAccuracy ); |
|||
|
|||
if( aContained ) |
|||
return rect.Contains( GetBoundingBox() ); |
|||
|
|||
return rect.Intersects( GetBoundingBox() ); |
|||
} |
|||
|
|||
|
|||
wxString PCB_TEXTBOX::GetSelectMenuText( EDA_UNITS aUnits ) const |
|||
{ |
|||
return wxString::Format( _( "PCB Text Box on %s"), GetLayerName() ); |
|||
} |
|||
|
|||
|
|||
BITMAPS PCB_TEXTBOX::GetMenuImage() const |
|||
{ |
|||
return BITMAPS::add_textbox; |
|||
} |
|||
|
|||
|
|||
EDA_ITEM* PCB_TEXTBOX::Clone() const |
|||
{ |
|||
return new PCB_TEXTBOX( *this ); |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::SwapData( BOARD_ITEM* aImage ) |
|||
{ |
|||
assert( aImage->Type() == PCB_TEXTBOX_T ); |
|||
|
|||
std::swap( *((PCB_TEXTBOX*) this), *((PCB_TEXTBOX*) aImage) ); |
|||
} |
|||
|
|||
|
|||
std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer ) const |
|||
{ |
|||
if( PCB_SHAPE::GetStroke().GetWidth() >= 0 ) |
|||
return PCB_SHAPE::GetEffectiveShape( aLayer ); |
|||
else |
|||
return GetEffectiveTextShape(); |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearance, |
|||
int aError, ERROR_LOC aErrorLoc ) const |
|||
{ |
|||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts; |
|||
KIFONT::FONT* font = GetDrawFont(); |
|||
int penWidth = GetEffectiveTextPenWidth(); |
|||
|
|||
CALLBACK_GAL callback_gal( empty_opts, |
|||
// Stroke callback
|
|||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) |
|||
{ |
|||
TransformOvalToPolygon( aCornerBuffer, aPt1, aPt2, penWidth+ ( 2 * aClearance ), |
|||
aError, ERROR_INSIDE ); |
|||
}, |
|||
// Triangulation callback
|
|||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 ) |
|||
{ |
|||
aCornerBuffer.NewOutline(); |
|||
|
|||
for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } ) |
|||
aCornerBuffer.Append( point.x, point.y ); |
|||
} ); |
|||
|
|||
font->Draw( &callback_gal, GetShownText(), GetTextPos(), GetAttributes() ); |
|||
} |
|||
|
|||
|
|||
void PCB_TEXTBOX::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearance, |
|||
int aError, ERROR_LOC aErrorLoc, |
|||
bool aIgnoreLineWidth ) const |
|||
{ |
|||
if( PCB_SHAPE::GetStroke().GetWidth() >= 0 ) |
|||
{ |
|||
PCB_SHAPE::TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, aClearance, |
|||
aError, aErrorLoc ); |
|||
} |
|||
else |
|||
{ |
|||
EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance ); |
|||
} |
|||
} |
|||
|
|||
|
|||
static struct PCB_TEXTBOX_DESC |
|||
{ |
|||
PCB_TEXTBOX_DESC() |
|||
{ |
|||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); |
|||
REGISTER_TYPE( PCB_TEXTBOX ); |
|||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TEXTBOX, PCB_SHAPE> ); |
|||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TEXTBOX, EDA_TEXT> ); |
|||
propMgr.InheritsAfter( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( PCB_SHAPE ) ); |
|||
propMgr.InheritsAfter( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ) ); |
|||
} |
|||
} _PCB_TEXTBOX_DESC; |
|||
@ -0,0 +1,127 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com |
|||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#ifndef PCB_TEXTBOX_H |
|||
#define PCB_TEXTBOX_H |
|||
|
|||
#include <eda_text.h> |
|||
#include <pcb_shape.h> |
|||
|
|||
|
|||
class LINE_READER; |
|||
class MSG_PANEL_ITEM; |
|||
|
|||
|
|||
class PCB_TEXTBOX : public PCB_SHAPE, public EDA_TEXT |
|||
{ |
|||
public: |
|||
PCB_TEXTBOX( BOARD_ITEM* parent ); |
|||
|
|||
// Do not create a copy constructor & operator=. |
|||
// The ones generated by the compiler are adequate. |
|||
|
|||
~PCB_TEXTBOX(); |
|||
|
|||
static inline bool ClassOf( const EDA_ITEM* aItem ) |
|||
{ |
|||
return aItem && PCB_TEXTBOX_T == aItem->Type(); |
|||
} |
|||
|
|||
bool IsType( const KICAD_T aScanTypes[] ) const override |
|||
{ |
|||
if( BOARD_ITEM::IsType( aScanTypes ) ) |
|||
return true; |
|||
|
|||
for( const KICAD_T* p = aScanTypes; *p != EOT; ++p ) |
|||
{ |
|||
if( *p == PCB_LOCATE_TEXT_T ) |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
int GetTextMargin() const; |
|||
|
|||
VECTOR2I GetDrawPos() const override; |
|||
|
|||
wxString GetShownText( int aDepth = 0 ) const override; |
|||
|
|||
/// PCB_TEXTBOXes are always visible: |
|||
void SetVisible( bool aVisible ) override { /* do nothing */} |
|||
bool IsVisible() const override { return true; } |
|||
|
|||
bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override |
|||
{ |
|||
return BOARD_ITEM::Matches( GetShownText(), aSearchData ); |
|||
} |
|||
|
|||
std::vector<VECTOR2I> GetAnchorAndOppositeCorner() const; |
|||
|
|||
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override; |
|||
|
|||
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override; |
|||
|
|||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override; |
|||
|
|||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy ) const override; |
|||
|
|||
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; |
|||
|
|||
wxString GetClass() const override |
|||
{ |
|||
return wxT( "PCB_TEXTBOX" ); |
|||
} |
|||
|
|||
/** |
|||
* Function TransformTextShapeWithClearanceToPolygon |
|||
* Convert the text to a polygonSet describing the actual character strokes (one per segment). |
|||
* Used in 3D viewer |
|||
* Circles and arcs are approximated by segments |
|||
* @aCornerBuffer = SHAPE_POLY_SET to store the polygon corners |
|||
* @aClearanceValue = the clearance around the text |
|||
* @aError = the maximum error to allow when approximating curves |
|||
*/ |
|||
void TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, |
|||
PCB_LAYER_ID aLayer, int aClearanceValue, |
|||
int aError, ERROR_LOC aErrorLoc ) const; |
|||
|
|||
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, |
|||
int aClearanceValue, int aError, ERROR_LOC aErrorLoc, |
|||
bool aIgnoreLineWidth = false ) const override; |
|||
|
|||
// @copydoc BOARD_ITEM::GetEffectiveShape |
|||
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override; |
|||
|
|||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; |
|||
|
|||
BITMAPS GetMenuImage() const override; |
|||
|
|||
// Virtual function |
|||
EDA_ITEM* Clone() const override; |
|||
|
|||
virtual void SwapData( BOARD_ITEM* aImage ) override; |
|||
}; |
|||
|
|||
#endif // #define PCB_TEXTBOX_H |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue