PCB Editor: Add User Background Images
This commit is contained in:
parent
1f4079802c
commit
3669cb4673
|
@ -512,6 +512,7 @@ set( PCB_COMMON_SRCS
|
|||
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_list.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pad.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_target.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_bitmap.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_text.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_textbox.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/board_stackup_manager/board_stackup.cpp
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#include <wx/dcclient.h>
|
||||
#include <confirm.h>
|
||||
#include <bitmap_base.h>
|
||||
#include <pcb_base_edit_frame.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/actions.h>
|
||||
|
||||
#include <dialogs/dialog_image_editor.h>
|
||||
|
||||
|
@ -129,3 +133,24 @@ void DIALOG_IMAGE_EDITOR::TransferToImage( BITMAP_BASE* aItem )
|
|||
m_workingImage->SetScale( scale );
|
||||
aItem->ImportData( m_workingImage );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::ShowBitmapPropertiesDialog( BOARD_ITEM* aBitmap )
|
||||
{
|
||||
PCB_BITMAP* bitmap = static_cast<PCB_BITMAP*>( aBitmap );
|
||||
DIALOG_IMAGE_EDITOR dlg( this, bitmap->GetImage() );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
// save old image in undo list if not already in edit
|
||||
if( bitmap->GetEditFlags() == 0 )
|
||||
SaveCopyInUndoList( bitmap, UNDO_REDO::CHANGED );
|
||||
|
||||
dlg.TransferToImage( bitmap->GetImage() );
|
||||
|
||||
// The bitmap is cached in Opengl: clear the cache in case it has become invalid
|
||||
GetCanvas()->GetView()->RecacheAllItems();
|
||||
m_toolManager->PostEvent( EVENTS::SelectedItemsModified );
|
||||
this->OnModify();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,6 +315,7 @@ static struct EDA_ITEM_DESC
|
|||
.Map( PCB_FOOTPRINT_T, _HKI( "Footprint" ) )
|
||||
.Map( PCB_PAD_T, _HKI( "Pad" ) )
|
||||
.Map( PCB_SHAPE_T, _HKI( "Graphic" ) )
|
||||
.Map( PCB_BITMAP_T, _HKI( "Bitmap" ) )
|
||||
.Map( PCB_TEXT_T, _HKI( "Text" ) )
|
||||
.Map( PCB_TEXTBOX_T, _HKI( "Text Box" ) )
|
||||
.Map( PCB_FP_TEXT_T, _HKI( "Text" ) )
|
||||
|
|
|
@ -480,10 +480,12 @@ void CAIRO_GAL_BASE::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aCo
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
|
||||
void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
{
|
||||
cairo_save( m_currentContext );
|
||||
|
||||
alphaBlend = std::clamp( alphaBlend, 0.0, 1.0 );
|
||||
|
||||
// We have to calculate the pixel size in users units to draw the image.
|
||||
// m_worldUnitLength is a factor used for converting IU to inches
|
||||
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
||||
|
@ -537,7 +539,7 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
|
|||
|
||||
cairo_surface_mark_dirty( image );
|
||||
cairo_set_source_surface( m_currentContext, image, 0, 0 );
|
||||
cairo_paint( m_currentContext );
|
||||
cairo_paint_with_alpha( m_currentContext, alphaBlend );
|
||||
|
||||
// store the image handle so it can be destroyed later
|
||||
m_imageSurfaces.push_back( image );
|
||||
|
|
|
@ -1232,8 +1232,10 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
||||
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
{
|
||||
GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
|
||||
|
||||
// We have to calculate the pixel size in users units to draw the image.
|
||||
// m_worldUnitLength is a factor used for converting IU to inches
|
||||
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
||||
|
@ -1259,16 +1261,16 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
|||
glBindTexture( GL_TEXTURE_2D, texture_id );
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( 0.0, 0.0 );
|
||||
glVertex3f( v0.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( 1.0, 0.0 );
|
||||
glVertex3f( v1.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( 1.0, 1.0 );
|
||||
glVertex3f( v1.x, v1.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( 0.0, 1.0 );
|
||||
glVertex3f( v0.x, v1.y, m_layerDepth );
|
||||
glEnd();
|
||||
|
|
|
@ -74,6 +74,7 @@ convexhull
|
|||
copper_line_width
|
||||
copper_text_dims
|
||||
courtyard_line_width
|
||||
data
|
||||
date
|
||||
defaults
|
||||
descr
|
||||
|
@ -148,6 +149,7 @@ hide
|
|||
hole_to_hole_min
|
||||
host
|
||||
id
|
||||
image
|
||||
island
|
||||
island_removal_mode
|
||||
island_area_min
|
||||
|
|
|
@ -157,6 +157,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
|||
m_params.emplace_back( new PARAM<double>( "board.opacity.vias", &m_ViaOpacity, 1.0 ) );
|
||||
m_params.emplace_back( new PARAM<double>( "board.opacity.pads", &m_PadOpacity, 1.0 ) );
|
||||
m_params.emplace_back( new PARAM<double>( "board.opacity.zones", &m_ZoneOpacity, 0.6 ) );
|
||||
m_params.emplace_back( new PARAM<double>( "board.opacity.background_images", &m_BgImageOpacity, 0.6 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_LIST<wxString>( "board.hidden_nets", &m_HiddenNets, {} ) );
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ enum KICAD_T
|
|||
PCB_FOOTPRINT_T, ///< class FOOTPRINT, a footprint
|
||||
PCB_PAD_T, ///< class PAD, a pad in a footprint
|
||||
PCB_SHAPE_T, ///< class PCB_SHAPE, a segment not on copper layers
|
||||
PCB_BITMAP_T, ///< class PCB_BITMAP, bitmap on a layer
|
||||
PCB_TEXT_T, ///< class PCB_TEXT, text on a layer
|
||||
PCB_TEXTBOX_T, ///< class PCB_TEXTBOX, wrapped text on a layer
|
||||
PCB_FP_TEXT_T, ///< class FP_TEXT, text in a footprint
|
||||
|
@ -111,7 +112,7 @@ enum KICAD_T
|
|||
PCB_DIM_ORTHOGONAL_T, ///< class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
|
||||
PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item)
|
||||
PCB_ZONE_T, ///< class ZONE, a copper pour area
|
||||
PCB_ITEM_LIST_T , ///< class BOARD_ITEM_LIST, a list of board items
|
||||
PCB_ITEM_LIST_T, ///< class BOARD_ITEM_LIST, a list of board items
|
||||
PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net
|
||||
PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs
|
||||
|
||||
|
@ -406,6 +407,7 @@ constexpr bool IsPcbnewType( const KICAD_T aType )
|
|||
case PCB_FOOTPRINT_T:
|
||||
case PCB_PAD_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_FP_TEXT_T:
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
double aFilterValue = 0.0 ) override;
|
||||
|
||||
/// @copydoc GAL::DrawBitmap()
|
||||
void DrawBitmap( const BITMAP_BASE& aBitmap ) override;
|
||||
void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) override;
|
||||
|
||||
// --------------
|
||||
// Screen methods
|
||||
|
|
|
@ -206,7 +206,7 @@ public:
|
|||
/**
|
||||
* Draw a bitmap image.
|
||||
*/
|
||||
virtual void DrawBitmap( const BITMAP_BASE& aBitmap ) {};
|
||||
virtual void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) {};
|
||||
|
||||
// --------------
|
||||
// Screen methods
|
||||
|
|
|
@ -157,7 +157,7 @@ public:
|
|||
double aFilterValue = 0.0 ) override;
|
||||
|
||||
/// @copydoc GAL::DrawBitmap()
|
||||
void DrawBitmap( const BITMAP_BASE& aBitmap ) override;
|
||||
void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) override;
|
||||
|
||||
/// @copydoc GAL::BitmapText()
|
||||
void BitmapText( const wxString& aText, const VECTOR2I& aPosition,
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
m_ViaOpacity = 1.0;
|
||||
m_PadOpacity = 1.0;
|
||||
m_ZoneOpacity = 1.0;
|
||||
m_BgImageOpacity = 1.0;
|
||||
}
|
||||
|
||||
/// @see ZONE_DISPLAY_MODE - stored in the project
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
double m_ViaOpacity; ///< Opacity override for all types of via
|
||||
double m_PadOpacity; ///< Opacity override for SMD pads and PTHs
|
||||
double m_ZoneOpacity; ///< Opacity override for filled zone areas
|
||||
double m_BgImageOpacity; ///< Opacity override for background images
|
||||
};
|
||||
|
||||
#endif // PCBSTRUCT_H_
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
double m_ViaOpacity; ///< Opacity override for all types of via
|
||||
double m_PadOpacity; ///< Opacity override for SMD pads and PTH
|
||||
double m_ZoneOpacity; ///< Opacity override for filled zones
|
||||
double m_BgImageOpacity; ///< Opacity override for filled zones
|
||||
|
||||
/**
|
||||
* A list of netnames that have been manually hidden in the board editor.
|
||||
|
|
|
@ -478,6 +478,7 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
|
|||
DEPENDS python/swig/netinfo.i
|
||||
DEPENDS python/swig/pad.i
|
||||
DEPENDS python/swig/pcb_group.i
|
||||
DEPENDS python/swig/pcb_bitmap.i
|
||||
DEPENDS python/swig/pcb_text.i
|
||||
DEPENDS python/swig/pcb_group.i
|
||||
DEPENDS python/swig/plugins.i
|
||||
|
|
|
@ -112,6 +112,7 @@ void ARRAY_CREATOR::Invoke()
|
|||
{
|
||||
case PCB_FOOTPRINT_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TRACE_T:
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <pcb_group.h>
|
||||
#include <pcb_target.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pgm_base.h>
|
||||
|
@ -307,6 +308,7 @@ void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
|
|||
// @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
|
||||
static const KICAD_T top_level_board_stuff[] = {
|
||||
PCB_MARKER_T,
|
||||
PCB_BITMAP_T,
|
||||
PCB_TEXT_T,
|
||||
PCB_TEXTBOX_T,
|
||||
PCB_SHAPE_T,
|
||||
|
@ -739,6 +741,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
|
|||
case PCB_DIM_ORTHOGONAL_T:
|
||||
case PCB_DIM_LEADER_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TARGET_T:
|
||||
|
@ -851,6 +854,7 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
|
|||
case PCB_DIM_ORTHOGONAL_T:
|
||||
case PCB_DIM_LEADER_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TARGET_T:
|
||||
|
@ -1334,6 +1338,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
|
|||
break;
|
||||
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
|
@ -1350,6 +1355,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
|
|||
switch( stype = *++p )
|
||||
{
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
|
|
|
@ -341,6 +341,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
|
||||
// Board items
|
||||
case PCB_SHAPE_T: // a shape (normally not on copper layers)
|
||||
case PCB_BITMAP_T: // a bitmap on a user layer
|
||||
case PCB_TEXT_T: // a text on a layer
|
||||
case PCB_TEXTBOX_T: // a wrapped text on a layer
|
||||
case PCB_TRACE_T: // a track segment (segment on a copper layer)
|
||||
|
|
|
@ -49,6 +49,7 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
|
|||
// *** all items in a same list (shown here) must be contiguous ****
|
||||
PCB_MARKER_T, // in m_markers
|
||||
PCB_TEXT_T, // in m_drawings
|
||||
PCB_BITMAP_T, // in m_drawings
|
||||
PCB_TEXTBOX_T, // in m_drawings
|
||||
PCB_SHAPE_T, // in m_drawings
|
||||
PCB_DIM_ALIGNED_T, // in m_drawings
|
||||
|
@ -72,6 +73,7 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
|
|||
|
||||
const KICAD_T GENERAL_COLLECTOR::BoardLevelItems[] = {
|
||||
PCB_MARKER_T,
|
||||
PCB_BITMAP_T,
|
||||
PCB_TEXT_T,
|
||||
PCB_TEXTBOX_T,
|
||||
PCB_SHAPE_T,
|
||||
|
@ -118,6 +120,7 @@ const KICAD_T GENERAL_COLLECTOR::FootprintItems[] = {
|
|||
PCB_PAD_T,
|
||||
PCB_FP_ZONE_T,
|
||||
PCB_GROUP_T,
|
||||
PCB_BITMAP_T,
|
||||
EOT
|
||||
};
|
||||
|
||||
|
|
|
@ -119,6 +119,10 @@ void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
|
|||
{
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case PCB_BITMAP_T:
|
||||
ShowBitmapPropertiesDialog( aItem);
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
case PCB_FP_TEXT_T:
|
||||
ShowTextPropertiesDialog( aItem );
|
||||
|
|
|
@ -532,6 +532,7 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv
|
|||
case PCB_FP_DIM_ORTHOGONAL_T:
|
||||
case PCB_FP_SHAPE_T:
|
||||
case PCB_FP_TEXTBOX_T:
|
||||
case PCB_BITMAP_T:
|
||||
if( aMode == ADD_MODE::APPEND )
|
||||
m_drawings.push_back( aBoardItem );
|
||||
else
|
||||
|
@ -786,7 +787,10 @@ const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisi
|
|||
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
||||
// We want the bitmap bounding box just in the footprint editor
|
||||
// so it will start with the correct initial zoom
|
||||
if( !isFPEdit
|
||||
&& ( m_privateLayers.test( item->GetLayer() ) || item->Type() != PCB_BITMAP_T ) )
|
||||
continue;
|
||||
|
||||
if( item->Type() != PCB_FP_TEXT_T )
|
||||
|
@ -893,7 +897,7 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
|
|||
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
||||
continue;
|
||||
|
||||
if( item->Type() != PCB_FP_TEXT_T )
|
||||
if( item->Type() != PCB_FP_TEXT_T && item->Type() != PCB_BITMAP_T )
|
||||
{
|
||||
item->TransformShapeWithClearanceToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF,
|
||||
ERROR_OUTSIDE );
|
||||
|
@ -1096,9 +1100,12 @@ bool FOOTPRINT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
|
|||
{
|
||||
// Text items are selectable on their own, and are therefore excluded from this
|
||||
// test. TextBox items are NOT selectable on their own, and so MUST be included
|
||||
// here.
|
||||
if( item->Type() != PCB_FP_TEXT_T && item->HitTest( arect, false, 0 ) )
|
||||
// here. Bitmaps aren't selectable since they aren't displayed.
|
||||
if( item->Type() != PCB_FP_TEXT_T && item->Type() != PCB_FP_TEXT_T
|
||||
&& item->HitTest( arect, false, 0 ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Groups are not hit-tested; only their members
|
||||
|
@ -1689,6 +1696,7 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos )
|
|||
case PCB_FP_DIM_ORTHOGONAL_T:
|
||||
case PCB_FP_DIM_RADIAL_T:
|
||||
case PCB_FP_DIM_LEADER_T:
|
||||
case PCB_BITMAP_T:
|
||||
item->Move( delta );
|
||||
break;
|
||||
|
||||
|
|
|
@ -1181,6 +1181,7 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions()
|
|||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawRuleArea );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeImage );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
||||
|
|
|
@ -185,6 +185,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
||||
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
||||
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
||||
placeMenu->Add( PCB_ACTIONS::placeImage );
|
||||
placeMenu->Add( PCB_ACTIONS::placeText );
|
||||
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
||||
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
||||
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
||||
placeMenu->Add( PCB_ACTIONS::placeImage );
|
||||
placeMenu->Add( PCB_ACTIONS::placeText );
|
||||
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
*/
|
||||
//void SetRotationAngle( EDA_ANGLE aRotationAngle );
|
||||
|
||||
void ShowBitmapPropertiesDialog( BOARD_ITEM* aBitmap );
|
||||
void ShowTextPropertiesDialog( BOARD_ITEM* aText );
|
||||
int ShowTextBoxPropertiesDialog( BOARD_ITEM* aText );
|
||||
void ShowGraphicItemPropertiesDialog( BOARD_ITEM* aItem );
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2011 jean-pierre.charras
|
||||
* Copyright (C) 2022 Mike Williams
|
||||
* Copyright (C) 2011-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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pcb_bitmap.cpp
|
||||
*/
|
||||
|
||||
#include <pcb_draw_panel_gal.h>
|
||||
#include <plotters/plotter.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <bitmaps.h>
|
||||
#include <base_units.h>
|
||||
#include <common.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <core/mirror.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <trigo.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <convert_to_biu.h>
|
||||
|
||||
#include <wx/mstream.h>
|
||||
|
||||
|
||||
PCB_BITMAP::PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos ) :
|
||||
BOARD_ITEM( aParent, PCB_BITMAP_T )
|
||||
{
|
||||
m_pos = pos;
|
||||
m_layer = PCB_LAYER_ID::Dwgs_User; // used only to draw/plot a rectangle,
|
||||
// when a bitmap cannot be drawn or plotted
|
||||
m_image = new BITMAP_BASE();
|
||||
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||
}
|
||||
|
||||
|
||||
PCB_BITMAP::PCB_BITMAP( const PCB_BITMAP& aPCBBitmap ) : BOARD_ITEM( aPCBBitmap )
|
||||
{
|
||||
m_pos = aPCBBitmap.m_pos;
|
||||
m_layer = aPCBBitmap.m_layer;
|
||||
m_image = new BITMAP_BASE( *aPCBBitmap.m_image );
|
||||
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||
}
|
||||
|
||||
|
||||
PCB_BITMAP& PCB_BITMAP::operator=( const BOARD_ITEM& aItem )
|
||||
{
|
||||
wxCHECK_MSG( Type() == aItem.Type(), *this,
|
||||
wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " )
|
||||
+ GetClass() );
|
||||
|
||||
if( &aItem != this )
|
||||
{
|
||||
BOARD_ITEM::operator=( aItem );
|
||||
|
||||
PCB_BITMAP* bitmap = (PCB_BITMAP*) &aItem;
|
||||
|
||||
delete m_image;
|
||||
m_image = new BITMAP_BASE( *bitmap->m_image );
|
||||
m_pos = bitmap->m_pos;
|
||||
m_image->SetPixelSizeIu( Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename )
|
||||
{
|
||||
return m_image->ReadImageFile( aFullFilename );
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* PCB_BITMAP::Clone() const
|
||||
{
|
||||
return new PCB_BITMAP( *this );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BITMAP::SwapData( BOARD_ITEM* aItem )
|
||||
{
|
||||
wxCHECK_RET( aItem->Type() == PCB_BITMAP_T,
|
||||
wxString::Format( wxT( "PCB_BITMAP object cannot swap data with %s object." ),
|
||||
aItem->GetClass() ) );
|
||||
|
||||
PCB_BITMAP* item = (PCB_BITMAP*) aItem;
|
||||
std::swap( m_pos, item->m_pos );
|
||||
std::swap( m_image, item->m_image );
|
||||
}
|
||||
|
||||
|
||||
const EDA_RECT PCB_BITMAP::GetBoundingBox() const
|
||||
{
|
||||
// Bitmaps are center origin, EDA_RECTs need top-left origin
|
||||
VECTOR2I size = m_image->GetSize();
|
||||
VECTOR2I topLeft = { m_pos.x - size.x / 2, m_pos.y - size.y / 2 };
|
||||
|
||||
return EDA_RECT( topLeft, size );
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<SHAPE> PCB_BITMAP::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
|
||||
{
|
||||
EDA_RECT box = GetBoundingBox();
|
||||
return std::shared_ptr<SHAPE_RECT>(
|
||||
new SHAPE_RECT( box.GetCenter(), box.GetWidth(), box.GetHeight() ) );
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I PCB_BITMAP::GetSize() const
|
||||
{
|
||||
return m_image->GetSize();
|
||||
}
|
||||
|
||||
|
||||
void PCB_BITMAP::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
if( aFlipLeftRight )
|
||||
{
|
||||
MIRROR( m_pos.x, aCentre.x );
|
||||
m_image->Mirror( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
MIRROR( m_pos.y, aCentre.y );
|
||||
m_image->Mirror( true );
|
||||
}
|
||||
}
|
||||
|
||||
void PCB_BITMAP::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
|
||||
{
|
||||
RotatePoint( m_pos, aCenter, aAngle );
|
||||
m_image->Rotate( false );
|
||||
}
|
||||
|
||||
|
||||
#if defined( DEBUG )
|
||||
void PCB_BITMAP::Show( int nestLevel, std::ostream& os ) const
|
||||
{
|
||||
// XML output:
|
||||
wxString s = GetClass();
|
||||
|
||||
NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool PCB_BITMAP::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
{
|
||||
EDA_RECT rect = GetBoundingBox();
|
||||
|
||||
rect.Inflate( aAccuracy );
|
||||
|
||||
return rect.Contains( aPosition );
|
||||
}
|
||||
|
||||
|
||||
bool PCB_BITMAP::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() );
|
||||
}
|
||||
|
||||
|
||||
BITMAPS PCB_BITMAP::GetMenuImage() const
|
||||
{
|
||||
return BITMAPS::image;
|
||||
}
|
||||
|
||||
|
||||
void PCB_BITMAP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
aList.emplace_back( _( "Bitmap" ), wxEmptyString );
|
||||
|
||||
aList.emplace_back( _( "Width" ), MessageTextFromValue( aFrame->GetUserUnits(), GetSize().x ) );
|
||||
aList.emplace_back( _( "Height" ),
|
||||
MessageTextFromValue( aFrame->GetUserUnits(), GetSize().y ) );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BITMAP::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
aCount = 1;
|
||||
aLayers[0] = LAYER_DRAW_BITMAPS;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2011 jean-pierre.charras
|
||||
* Copyright (C) 2022 Mike Williams
|
||||
* Copyright (C) 2011-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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pcb_bitmap.h
|
||||
*/
|
||||
|
||||
#ifndef _PCB_BITMAP_H_
|
||||
#define _PCB_BITMAP_H_
|
||||
|
||||
|
||||
#include <board_item.h>
|
||||
#include <bitmap_base.h>
|
||||
|
||||
|
||||
/**
|
||||
* Object to handle a bitmap image that can be inserted in a PCB.
|
||||
*/
|
||||
class PCB_BITMAP : public BOARD_ITEM
|
||||
{
|
||||
public:
|
||||
PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos = VECTOR2I( 0, 0 ) );
|
||||
|
||||
PCB_BITMAP( const PCB_BITMAP& aPcbBitmap );
|
||||
|
||||
~PCB_BITMAP() { delete m_image; }
|
||||
|
||||
PCB_BITMAP& operator=( const BOARD_ITEM& aItem );
|
||||
|
||||
BITMAP_BASE* GetImage() const
|
||||
{
|
||||
wxCHECK_MSG( m_image != nullptr, nullptr, "Invalid PCB_BITMAP init, m_image is NULL." );
|
||||
return m_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the image "zoom" value.
|
||||
* scale = 1.0 = original size of bitmap.
|
||||
* scale < 1.0 = the bitmap is drawn smaller than its original size.
|
||||
* scale > 1.0 = the bitmap is drawn bigger than its original size.
|
||||
*/
|
||||
double GetImageScale() const { return m_image->GetScale(); }
|
||||
|
||||
void SetImageScale( double aScale ) { m_image->SetScale( aScale ); }
|
||||
|
||||
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||
{
|
||||
return aItem && PCB_BITMAP_T == aItem->Type();
|
||||
}
|
||||
|
||||
wxString GetClass() const override { return wxT( "PCB_BITMAP" ); }
|
||||
|
||||
/**
|
||||
* @return the actual size (in user units, not in pixels) of the image.
|
||||
*/
|
||||
const VECTOR2I GetSize() const;
|
||||
|
||||
const EDA_RECT GetBoundingBox() const override;
|
||||
|
||||
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
|
||||
FLASHING aFlash = FLASHING::DEFAULT ) const override;
|
||||
|
||||
void SwapData( BOARD_ITEM* aItem ) override;
|
||||
|
||||
//void Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) override;
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
/**
|
||||
* Read and store an image file.
|
||||
*
|
||||
* Initialize the bitmap used to draw this item format.
|
||||
*
|
||||
* @param aFullFilename is the full filename of the image file to read.
|
||||
* @return true if success reading else false.
|
||||
*/
|
||||
bool ReadImageFile( const wxString& aFullFilename );
|
||||
|
||||
void Move( const VECTOR2I& aMoveVector ) override { m_pos += aMoveVector; }
|
||||
|
||||
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
|
||||
void Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle ) override;
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override
|
||||
{
|
||||
return wxString( _( "Image" ) );
|
||||
}
|
||||
|
||||
BITMAPS GetMenuImage() const override;
|
||||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
VECTOR2I GetPosition() const override { return m_pos; }
|
||||
void SetPosition( const VECTOR2I& aPosition ) override { m_pos = aPosition; }
|
||||
|
||||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
||||
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
||||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
#if defined( DEBUG )
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
VECTOR2I m_pos; // XY coordinates of center of the bitmap
|
||||
BITMAP_BASE* m_image; // the BITMAP_BASE item
|
||||
};
|
||||
|
||||
#endif // _PCB_BITMAP_H_
|
|
@ -560,6 +560,8 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
|||
}
|
||||
}
|
||||
|
||||
m_view->SetLayerTarget( LAYER_DRAW_BITMAPS, KIGFX::TARGET_NONCACHED );
|
||||
|
||||
m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED );
|
||||
m_view->SetLayerDisplayOnly( LAYER_ANCHOR );
|
||||
|
||||
|
|
|
@ -828,6 +828,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
|||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawCircle );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeImage );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <pcb_shape.h>
|
||||
#include <string_utils.h>
|
||||
#include <zone.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_marker.h>
|
||||
|
@ -72,10 +73,11 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
|
|||
m_netColorMode = NET_COLOR_MODE::RATSNEST;
|
||||
m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
|
||||
|
||||
m_trackOpacity = 1.0;
|
||||
m_viaOpacity = 1.0;
|
||||
m_padOpacity = 1.0;
|
||||
m_zoneOpacity = 1.0;
|
||||
m_trackOpacity = 1.0;
|
||||
m_viaOpacity = 1.0;
|
||||
m_padOpacity = 1.0;
|
||||
m_zoneOpacity = 1.0;
|
||||
m_bgImageOpacity = 1.0;
|
||||
|
||||
m_ForcePadSketchModeOff = false;
|
||||
m_ForcePadSketchModeOn = false;
|
||||
|
@ -143,10 +145,11 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption
|
|||
m_ContrastModeDisplay = aOptions.m_ContrastModeDisplay;
|
||||
m_netColorMode = aOptions.m_NetColorMode;
|
||||
|
||||
m_trackOpacity = aOptions.m_TrackOpacity;
|
||||
m_viaOpacity = aOptions.m_ViaOpacity;
|
||||
m_padOpacity = aOptions.m_PadOpacity;
|
||||
m_zoneOpacity = aOptions.m_ZoneOpacity;
|
||||
m_trackOpacity = aOptions.m_TrackOpacity;
|
||||
m_viaOpacity = aOptions.m_ViaOpacity;
|
||||
m_padOpacity = aOptions.m_PadOpacity;
|
||||
m_zoneOpacity = aOptions.m_ZoneOpacity;
|
||||
m_bgImageOpacity = aOptions.m_BgImageOpacity;
|
||||
}
|
||||
|
||||
|
||||
|
@ -341,6 +344,8 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
|
|||
color.a *= m_padOpacity;
|
||||
else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
|
||||
color.a *= m_zoneOpacity;
|
||||
else if( item->Type() == PCB_BITMAP_T )
|
||||
color.a *= m_bgImageOpacity;
|
||||
|
||||
// No special modifiers enabled
|
||||
return color;
|
||||
|
@ -414,7 +419,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
|||
{
|
||||
FOOTPRINT* parentFP = static_cast<FOOTPRINT*>( item->GetParentFootprint() );
|
||||
|
||||
if( item->GetLayerSet().count() > 1 )
|
||||
// Never draw footprint bitmaps on board
|
||||
if( item->Type() == PCB_BITMAP_T )
|
||||
return false;
|
||||
else if( item->GetLayerSet().count() > 1 )
|
||||
{
|
||||
// For multi-layer objects, exclude only those layers that are private
|
||||
if( IsPcbLayer( aLayer ) && parentFP->GetPrivateLayers().test( aLayer ) )
|
||||
|
@ -461,6 +469,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
|||
draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
|
||||
break;
|
||||
|
||||
case PCB_BITMAP_T:
|
||||
draw( static_cast<const PCB_BITMAP*>( item ), aLayer );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
draw( static_cast<const PCB_TEXT*>( item ), aLayer );
|
||||
break;
|
||||
|
@ -1633,6 +1645,45 @@ void PCB_PAINTER::strokeText( const wxString& aText, const VECTOR2I& aPosition,
|
|||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const PCB_BITMAP* aBitmap, int aLayer )
|
||||
{
|
||||
m_gal->Save();
|
||||
m_gal->Translate( aBitmap->GetPosition() );
|
||||
|
||||
// When the image scale factor is not 1.0, we need to modify the actual as the image scale
|
||||
// factor is similar to a local zoom
|
||||
double img_scale = aBitmap->GetImageScale();
|
||||
|
||||
if( img_scale != 1.0 )
|
||||
m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
|
||||
|
||||
m_gal->DrawBitmap( *aBitmap->GetImage(), m_pcbSettings.m_bgImageOpacity );
|
||||
|
||||
if( aBitmap->IsSelected() || aBitmap->IsBrightened() )
|
||||
{
|
||||
COLOR4D color = m_pcbSettings.GetColor( aBitmap, LAYER_ANCHOR );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth * 2.0f );
|
||||
m_gal->SetIsFill( false );
|
||||
|
||||
// Draws a bounding box.
|
||||
VECTOR2D bm_size( aBitmap->GetSize() );
|
||||
// bm_size is the actual image size in UI.
|
||||
// but m_gal scale was previously set to img_scale
|
||||
// so recalculate size relative to this image size.
|
||||
bm_size.x /= img_scale;
|
||||
bm_size.y /= img_scale;
|
||||
VECTOR2D origin( -bm_size.x / 2.0, -bm_size.y / 2.0 );
|
||||
VECTOR2D end = origin + bm_size;
|
||||
|
||||
m_gal->DrawRectangle( origin, end );
|
||||
}
|
||||
|
||||
m_gal->Restore();
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
|
||||
{
|
||||
wxString resolvedText( aText->GetShownText() );
|
||||
|
|
|
@ -46,6 +46,7 @@ class PCB_SHAPE;
|
|||
class PCB_GROUP;
|
||||
class FOOTPRINT;
|
||||
class ZONE;
|
||||
class PCB_BITMAP;
|
||||
class PCB_TEXT;
|
||||
class PCB_TEXTBOX;
|
||||
class FP_TEXT;
|
||||
|
@ -142,6 +143,7 @@ protected:
|
|||
double m_viaOpacity; ///< Opacity override for all types of via
|
||||
double m_padOpacity; ///< Opacity override for SMD pads and PTHs
|
||||
double m_zoneOpacity; ///< Opacity override for filled zones
|
||||
double m_bgImageOpacity; ///< Opacity override for background images
|
||||
};
|
||||
|
||||
|
||||
|
@ -169,6 +171,7 @@ protected:
|
|||
void draw( const PCB_VIA* aVia, int aLayer );
|
||||
void draw( const PAD* aPad, int aLayer );
|
||||
void draw( const PCB_SHAPE* aSegment, int aLayer );
|
||||
void draw( const PCB_BITMAP* aBitmap, int aLayer );
|
||||
void draw( const PCB_TEXT* aText, int aLayer );
|
||||
void draw( const PCB_TEXTBOX* aText, int aLayer );
|
||||
void draw( const FP_TEXT* aText, int aLayer );
|
||||
|
|
|
@ -106,6 +106,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
|
|||
opts.m_PadOpacity = localSettings.m_PadOpacity;
|
||||
opts.m_ZoneOpacity = localSettings.m_ZoneOpacity;
|
||||
opts.m_ZoneDisplayMode = localSettings.m_ZoneDisplayMode;
|
||||
opts.m_BgImageOpacity = localSettings.m_BgImageOpacity;
|
||||
|
||||
// No refresh here: callers of LoadProjectSettings refresh later
|
||||
SetDisplayOptions( opts, false );
|
||||
|
@ -159,6 +160,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings()
|
|||
localSettings.m_PadOpacity = displayOpts.m_PadOpacity;
|
||||
localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity;
|
||||
localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode;
|
||||
localSettings.m_BgImageOpacity = displayOpts.m_BgImageOpacity;
|
||||
|
||||
// Save Design settings
|
||||
const BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <fp_textbox.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_target.h>
|
||||
#include <pcb_track.h>
|
||||
|
@ -63,6 +64,12 @@
|
|||
#include <progress_reporter.h>
|
||||
#include <board_stackup_manager/stackup_predefined_prms.h>
|
||||
|
||||
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||
// base64 code. Needed for PCB_BITMAP
|
||||
#define wxUSE_BASE64 1
|
||||
#include <wx/base64.h>
|
||||
#include <wx/mstream.h>
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
||||
|
@ -851,6 +858,12 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
bulkAddedItems.push_back( item );
|
||||
break;
|
||||
|
||||
case T_image:
|
||||
item = parsePCB_BITMAP( m_board );
|
||||
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||
bulkAddedItems.push_back( item );
|
||||
break;
|
||||
|
||||
case T_gr_text:
|
||||
item = parsePCB_TEXT();
|
||||
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||
|
@ -2836,6 +2849,80 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
|
|||
}
|
||||
|
||||
|
||||
PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_image, nullptr,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an image." ) );
|
||||
|
||||
T token;
|
||||
std::unique_ptr<PCB_BITMAP> bitmap = std::make_unique<PCB_BITMAP>( aParent );
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_at:
|
||||
{
|
||||
VECTOR2I pos;
|
||||
pos.x = parseBoardUnits( "X coordinate" );
|
||||
pos.y = parseBoardUnits( "Y coordinate" );
|
||||
bitmap->SetPosition( pos );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
|
||||
case T_scale:
|
||||
bitmap->GetImage()->SetScale( parseDouble( "image scale factor" ) );
|
||||
|
||||
if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
|
||||
bitmap->GetImage()->SetScale( 1.0 );
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_data:
|
||||
{
|
||||
token = NextTok();
|
||||
|
||||
wxString data;
|
||||
|
||||
// Reserve 128K because most image files are going to be larger than the default
|
||||
// 1K that wxString reserves.
|
||||
data.reserve( 1 << 17 );
|
||||
|
||||
while( token != T_RIGHT )
|
||||
{
|
||||
if( !IsSymbol( token ) )
|
||||
Expecting( "base64 image data" );
|
||||
|
||||
data += FromUTF8();
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
wxMemoryBuffer buffer = wxBase64Decode( data );
|
||||
wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
|
||||
wxImage* image = new wxImage();
|
||||
wxMemoryInputStream istream( stream );
|
||||
image->LoadFile( istream, wxBITMAP_TYPE_PNG );
|
||||
bitmap->GetImage()->SetImage( image );
|
||||
bitmap->GetImage()->SetBitmap( new wxBitmap( *image ) );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Expecting( "at, scale, data" );
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap.release();
|
||||
}
|
||||
|
||||
|
||||
PCB_TEXT* PCB_PARSER::parsePCB_TEXT()
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_gr_text, nullptr,
|
||||
|
@ -3784,6 +3871,13 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||
break;
|
||||
}
|
||||
|
||||
case T_image:
|
||||
{
|
||||
PCB_BITMAP* image = parsePCB_BITMAP( footprint.get() );
|
||||
footprint->Add( image, ADD_MODE::APPEND, true );
|
||||
break;
|
||||
}
|
||||
|
||||
case T_dimension:
|
||||
{
|
||||
PCB_DIMENSION_BASE* dimension = parseDIMENSION( footprint.get(), true );
|
||||
|
|
|
@ -49,6 +49,7 @@ class PAD;
|
|||
class BOARD_DESIGN_SETTINGS;
|
||||
class PCB_DIMENSION_BASE;
|
||||
class PCB_SHAPE;
|
||||
class PCB_BITMAP;
|
||||
class EDA_TEXT;
|
||||
class FP_SHAPE;
|
||||
class FP_TEXT;
|
||||
|
@ -176,6 +177,7 @@ private:
|
|||
|
||||
PCB_SHAPE* parsePCB_SHAPE();
|
||||
PCB_TEXT* parsePCB_TEXT();
|
||||
PCB_BITMAP* parsePCB_BITMAP( BOARD_ITEM* aParent );
|
||||
PCB_TEXTBOX* parsePCB_TEXTBOX();
|
||||
PCB_DIMENSION_BASE* parseDIMENSION( BOARD_ITEM* aParent, bool aInFP );
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <pad.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_target.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
|
@ -57,6 +58,13 @@
|
|||
#include <zone.h>
|
||||
#include <zones.h>
|
||||
|
||||
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||
// base64 code. Needed for PCB_BITMAP
|
||||
#define wxUSE_BASE64 1
|
||||
#include <wx/base64.h>
|
||||
#include <wx/mstream.h>
|
||||
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
||||
|
@ -418,6 +426,10 @@ void PCB_PLUGIN::Format( const BOARD_ITEM* aItem, int aNestLevel ) const
|
|||
format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
||||
case PCB_BITMAP_T:
|
||||
format( static_cast<const PCB_BITMAP*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
||||
case PCB_FP_SHAPE_T:
|
||||
format( static_cast<const FP_SHAPE*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
@ -996,6 +1008,52 @@ void PCB_PLUGIN::format( const PCB_SHAPE* aShape, int aNestLevel ) const
|
|||
}
|
||||
|
||||
|
||||
void PCB_PLUGIN::format( const PCB_BITMAP* aBitmap, int aNestLevel ) const
|
||||
{
|
||||
wxCHECK_RET( aBitmap != nullptr && m_out != nullptr, "" );
|
||||
|
||||
const wxImage* image = aBitmap->GetImage()->GetImageData();
|
||||
|
||||
wxCHECK_RET( image != nullptr, "wxImage* is NULL" );
|
||||
|
||||
m_out->Print( aNestLevel, "(image (at %s %s)",
|
||||
FormatInternalUnits( aBitmap->GetPosition().x ).c_str(),
|
||||
FormatInternalUnits( aBitmap->GetPosition().y ).c_str() );
|
||||
|
||||
if( aBitmap->GetImage()->GetScale() != 1.0 )
|
||||
m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() );
|
||||
|
||||
m_out->Print( 0, "\n" );
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(data" );
|
||||
|
||||
wxMemoryOutputStream stream;
|
||||
|
||||
image->SaveFile( stream, wxBITMAP_TYPE_PNG );
|
||||
|
||||
// Write binary data in hexadecimal form (ASCII)
|
||||
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||
wxString out = wxBase64Encode( buffer->GetBufferStart(), buffer->GetBufferSize() );
|
||||
|
||||
// Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed)
|
||||
// so use it in a vein attempt to be standard like.
|
||||
#define MIME_BASE64_LENGTH 76
|
||||
|
||||
size_t first = 0;
|
||||
|
||||
while( first < out.Length() )
|
||||
{
|
||||
m_out->Print( 0, "\n" );
|
||||
m_out->Print( aNestLevel + 2, "%s", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) );
|
||||
first += MIME_BASE64_LENGTH;
|
||||
}
|
||||
|
||||
m_out->Print( 0, "\n" );
|
||||
m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token.
|
||||
m_out->Print( aNestLevel, ")\n" ); // Closes image token.
|
||||
}
|
||||
|
||||
|
||||
void PCB_PLUGIN::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
||||
{
|
||||
std::string locked = aFPShape->IsLocked() ? " locked" : "";
|
||||
|
|
|
@ -39,6 +39,7 @@ class BOARD_DESIGN_SETTINGS;
|
|||
class PCB_DIMENSION_BASE;
|
||||
class FP_SHAPE;
|
||||
class PCB_SHAPE;
|
||||
class PCB_BITMAP;
|
||||
class PCB_TARGET;
|
||||
class PAD;
|
||||
class FP_TEXT;
|
||||
|
@ -122,7 +123,8 @@ class SHAPE_LINE_CHAIN;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20220331 // Plot on all layers selection setting
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220417 // Automatic dimension precisions
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220427 // Exclude Edge.Cuts & Margin from fp private layers
|
||||
#define SEXPR_BOARD_FILE_VERSION 20220609 // Add teardrop keywords to identify teardrop zones
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220609 // Add teardrop keywords to identify teardrop zones
|
||||
#define SEXPR_BOARD_FILE_VERSION 20220621 // Add Image support
|
||||
|
||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
|
||||
|
@ -281,6 +283,8 @@ private:
|
|||
|
||||
void format( const FP_SHAPE* aFPShape, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_BITMAP* aBitmap, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_GROUP* aGroup, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_SHAPE* aSegment, int aNestLevel = 0 ) const;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
|
||||
%include pcb_bitmap.h
|
||||
%{
|
||||
#include <pcb_bitmap.h>
|
||||
%}
|
||||
|
|
@ -185,6 +185,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
|||
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeImage, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||
|
|
|
@ -458,6 +458,7 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
|||
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeImage, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <view/view.h>
|
||||
#include <widgets/appearance_controls.h>
|
||||
#include <widgets/infobar.h>
|
||||
#include <wx/filedlg.h>
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <board.h>
|
||||
|
@ -61,6 +62,7 @@
|
|||
#include <painter.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_dimension.h>
|
||||
|
@ -524,6 +526,237 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
|
||||
REENTRANCY_GUARD guard( &m_inDrawingTool );
|
||||
|
||||
PCB_BITMAP* image = aEvent.Parameter<PCB_BITMAP*>();
|
||||
bool immediateMode = image != nullptr;
|
||||
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||
bool ignorePrimePosition = false;
|
||||
COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
|
||||
|
||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
||||
auto selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
// Add all the drawable symbols to preview
|
||||
if( image )
|
||||
{
|
||||
image->SetPosition( cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
}
|
||||
|
||||
std::string tool = aEvent.GetCommandStr().get();
|
||||
m_frame->PushTool( tool );
|
||||
auto setCursor =
|
||||
[&]()
|
||||
{
|
||||
if( image )
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
|
||||
else
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
|
||||
};
|
||||
|
||||
auto cleanup =
|
||||
[&] ()
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
m_view->ClearPreview();
|
||||
delete image;
|
||||
image = nullptr;
|
||||
};
|
||||
|
||||
Activate();
|
||||
|
||||
// Must be done after Activate() so that it gets set into the correct context
|
||||
getViewControls()->ShowCursor( true );
|
||||
|
||||
// Set initial cursor
|
||||
setCursor();
|
||||
|
||||
// Prime the pump
|
||||
if( image )
|
||||
{
|
||||
m_toolMgr->RunAction( ACTIONS::refreshPreview );
|
||||
}
|
||||
else if( aEvent.HasPosition() )
|
||||
{
|
||||
m_toolMgr->PrimeTool( aEvent.Position() );
|
||||
}
|
||||
else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
|
||||
{
|
||||
m_toolMgr->PrimeTool( { 0, 0 } );
|
||||
ignorePrimePosition = true;
|
||||
}
|
||||
|
||||
// Main loop: keep receiving events
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
setCursor();
|
||||
cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
|
||||
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
if( image )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->PopTool( tool );
|
||||
break;
|
||||
}
|
||||
|
||||
if( immediateMode )
|
||||
{
|
||||
m_frame->PopTool( tool );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( evt->IsActivate() )
|
||||
{
|
||||
if( image && evt->IsMoveTool() )
|
||||
{
|
||||
// We're already moving our own item; ignore the move tool
|
||||
evt->SetPassEvent( false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( image )
|
||||
{
|
||||
m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel image creation." ) );
|
||||
evt->SetPassEvent( false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( evt->IsMoveTool() )
|
||||
{
|
||||
// Leave ourselves on the stack so we come back after the move
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->PopTool( tool );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
|
||||
{
|
||||
if( !image )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
|
||||
_( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(),
|
||||
wxFD_OPEN );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
continue;
|
||||
|
||||
// If we started with a hotkey which has a position then warp back to that.
|
||||
// Otherwise update to the current mouse position pinned inside the autoscroll
|
||||
// boundaries.
|
||||
if( evt->IsPrime() && !ignorePrimePosition )
|
||||
{
|
||||
cursorPos = grid.Align( evt->Position() );
|
||||
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
getViewControls()->PinCursorInsideNonAutoscrollArea( true );
|
||||
cursorPos = getViewControls()->GetMousePosition();
|
||||
}
|
||||
|
||||
cursorPos = getViewControls()->GetMousePosition( true );
|
||||
|
||||
wxString fullFilename = dlg.GetPath();
|
||||
|
||||
if( wxFileExists( fullFilename ) )
|
||||
image = new PCB_BITMAP( m_frame->GetModel(), cursorPos );
|
||||
|
||||
if( !image || !image->ReadImageFile( fullFilename ) )
|
||||
{
|
||||
wxMessageBox( _( "Could not load image from '%s'." ), fullFilename );
|
||||
delete image;
|
||||
image = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
image->SetFlags( IS_NEW | IS_MOVING );
|
||||
image->SetLayer( m_frame->GetActiveLayer() );
|
||||
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
|
||||
selectionTool->AddItemToSel( image, false );
|
||||
|
||||
getViewControls()->SetCursorPosition( cursorPos, false );
|
||||
setCursor();
|
||||
m_view->ShowPreview( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Add( image );
|
||||
commit.Push( _( "Place an image" ) );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, image );
|
||||
|
||||
image = nullptr;
|
||||
m_toolMgr->RunAction( ACTIONS::activatePointEditor );
|
||||
|
||||
m_view->ClearPreview();
|
||||
|
||||
if( immediateMode )
|
||||
{
|
||||
m_frame->PopTool( tool );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
// Warp after context menu only if dragging...
|
||||
if( !image )
|
||||
m_toolMgr->VetoContextMenuMouseWarp();
|
||||
|
||||
m_menu.ShowContextMenu( selectionTool->GetSelection() );
|
||||
}
|
||||
else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||
{
|
||||
image->SetPosition( cursorPos );
|
||||
m_view->ClearPreview();
|
||||
m_view->AddToPreview( image->Clone() );
|
||||
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
|
||||
}
|
||||
else if( image && evt->IsAction( &ACTIONS::doDelete ) )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is an image to be placed
|
||||
getViewControls()->SetAutoPan( image != nullptr );
|
||||
getViewControls()->CaptureCursor( image != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||
|
@ -3004,6 +3237,7 @@ void DRAWING_TOOL::setTransitions()
|
|||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceImage, PCB_ACTIONS::placeImage.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawRectangle, PCB_ACTIONS::drawTextBox.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceImportedGraphics, PCB_ACTIONS::placeImportedGraphics.MakeEvent() );
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
RECTANGLE,
|
||||
CIRCLE,
|
||||
ARC,
|
||||
IMAGE,
|
||||
TEXT,
|
||||
ANCHOR,
|
||||
DXF,
|
||||
|
@ -135,6 +136,12 @@ public:
|
|||
*/
|
||||
int DrawArc( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Display a dialog that allows one to select and image then decide where to place the
|
||||
* image in the editor.
|
||||
*/
|
||||
int PlaceImage( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Display a dialog that allows one to input text and its settings and then lets the user
|
||||
* decide where to place the text in editor.
|
||||
|
|
|
@ -1757,6 +1757,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
case PCB_FOOTPRINT_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_BITMAP_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TRACE_T:
|
||||
case PCB_ARC_T:
|
||||
|
|
|
@ -117,6 +117,11 @@ TOOL_ACTION PCB_ACTIONS::placeStackup( "pcbnew.InteractiveDrawing.placeStackup",
|
|||
_( "Add a board stackup table on a graphic layer" ),
|
||||
BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::placeImage( "pcbnew.InteractiveDrawing.placeImage",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Add Image" ), _( "Add bitmap image" ),
|
||||
BITMAPS::image, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
|
||||
AS_GLOBAL,
|
||||
MD_SHIFT + MD_CTRL + 'T', LEGACY_HK_NAME( "Add Text" ),
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
static TOOL_ACTION drawRectangle;
|
||||
static TOOL_ACTION drawCircle;
|
||||
static TOOL_ACTION drawArc;
|
||||
static TOOL_ACTION placeImage;
|
||||
static TOOL_ACTION placeText;
|
||||
static TOOL_ACTION drawTextBox;
|
||||
static TOOL_ACTION drawAlignedDimension;
|
||||
|
|
|
@ -41,6 +41,7 @@ using namespace std::placeholders;
|
|||
#include <pcb_edit_frame.h>
|
||||
#include <fp_shape.h>
|
||||
#include <fp_textbox.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pad.h>
|
||||
|
@ -191,6 +192,20 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
|||
// Generate list of edit points basing on the item type
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case PCB_BITMAP_T:
|
||||
{
|
||||
PCB_BITMAP* bitmap = (PCB_BITMAP*) aItem;
|
||||
VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
|
||||
VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
|
||||
|
||||
points->AddPoint( topLeft );
|
||||
points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
|
||||
points->AddPoint( botRight );
|
||||
points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_FP_TEXTBOX_T:
|
||||
case PCB_SHAPE_T:
|
||||
|
@ -1076,6 +1091,29 @@ void PCB_POINT_EDITOR::updateItem() const
|
|||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_BITMAP_T:
|
||||
{
|
||||
PCB_BITMAP* bitmap = (PCB_BITMAP*) item;
|
||||
VECTOR2I topLeft = m_editPoints->Point( RECT_TOP_LEFT ).GetPosition();
|
||||
VECTOR2I topRight = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition();
|
||||
VECTOR2I botLeft = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition();
|
||||
VECTOR2I botRight = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition();
|
||||
|
||||
pinEditedCorner( topLeft, topRight, botLeft, botRight );
|
||||
|
||||
double oldWidth = bitmap->GetSize().x;
|
||||
double newWidth = std::max( topRight.x - topLeft.x, Mils2iu( 50 ) );
|
||||
double widthRatio = newWidth / oldWidth;
|
||||
|
||||
double oldHeight = bitmap->GetSize().y;
|
||||
double newHeight = std::max( botLeft.y - topLeft.y, Mils2iu( 50 ) );
|
||||
double heightRatio = newHeight / oldHeight;
|
||||
|
||||
bitmap->SetImageScale( bitmap->GetImageScale() * std::min( widthRatio, heightRatio ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_FP_TEXTBOX_T:
|
||||
case PCB_SHAPE_T:
|
||||
|
@ -1646,6 +1684,20 @@ void PCB_POINT_EDITOR::updatePoints()
|
|||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_BITMAP_T:
|
||||
{
|
||||
PCB_BITMAP* bitmap = (PCB_BITMAP*) item;
|
||||
VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
|
||||
VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
|
||||
|
||||
m_editPoints->Point( RECT_TOP_LEFT ).SetPosition( topLeft );
|
||||
m_editPoints->Point( RECT_TOP_RIGHT ).SetPosition( botRight.x, topLeft.y );
|
||||
m_editPoints->Point( RECT_BOT_LEFT ).SetPosition( topLeft.x, botRight.y );
|
||||
m_editPoints->Point( RECT_BOT_RIGHT ).SetPosition( botRight );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_FP_TEXTBOX_T:
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ using namespace std::placeholders;
|
|||
#include <board_design_settings.h>
|
||||
#include <board_item.h>
|
||||
#include <clipper.hpp>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_track.h>
|
||||
#include <footprint.h>
|
||||
#include <pad.h>
|
||||
|
@ -2720,6 +2721,11 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
|
|||
// segments underneath them -- so artificially reduce their size from πr² to 1.5r².
|
||||
area = SEG::Square( static_cast<PCB_VIA*>( item )->GetDrill() / 2 ) * 1.5;
|
||||
}
|
||||
else if( item->Type() == PCB_BITMAP_T )
|
||||
{
|
||||
VECTOR2I size = static_cast<const PCB_BITMAP*>( item )->GetSize();
|
||||
area = size.x * size.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
|
|
|
@ -336,6 +336,7 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti
|
|||
RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
|
||||
RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
|
||||
RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
|
||||
RR( _HKI( "Background Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user background images" ), true ),
|
||||
RR(),
|
||||
RR( _HKI( "Footprints Front" ), LAYER_MOD_FR, _HKI( "Show footprints that are on board's front" ) ),
|
||||
RR( _HKI( "Footprints Back" ), LAYER_MOD_BK, _HKI( "Show footprints that are on board's back" ) ),
|
||||
|
@ -371,6 +372,7 @@ static std::set<int> s_allowedInFpEditor =
|
|||
LAYER_MOD_REFERENCES,
|
||||
LAYER_MOD_TEXT,
|
||||
LAYER_MOD_TEXT_INVISIBLE,
|
||||
LAYER_DRAW_BITMAPS,
|
||||
LAYER_GRID
|
||||
};
|
||||
|
||||
|
@ -2204,12 +2206,14 @@ void APPEARANCE_CONTROLS::syncObjectSettings()
|
|||
wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
|
||||
&& m_objectSettingsMap.count( LAYER_VIAS )
|
||||
&& m_objectSettingsMap.count( LAYER_PADS )
|
||||
&& m_objectSettingsMap.count( LAYER_ZONES ) );
|
||||
&& m_objectSettingsMap.count( LAYER_ZONES )
|
||||
&& m_objectSettingsMap.count( LAYER_DRAW_BITMAPS ) );
|
||||
|
||||
m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
|
||||
m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
|
||||
m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
|
||||
m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
|
||||
m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_BgImageOpacity * 100 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2838,10 +2842,11 @@ void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
|
|||
|
||||
switch( aLayer )
|
||||
{
|
||||
case static_cast<int>( LAYER_TRACKS ): options.m_TrackOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_TRACKS ): options.m_TrackOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
|
||||
case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_BgImageOpacity = aOpacity; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue