Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76e224e0af |
@@ -1,20 +0,0 @@
|
||||
<!-- --------Before Creating a New Issue-----------
|
||||
* Limit report to a single issue.
|
||||
* Search the issue tracker to verify the issue has not already been reported.
|
||||
* Complete all instructions between `template comment markers <>.
|
||||
* Keep report contents limited to the necessary information required to fix the issue.
|
||||
* When creating an issue against the stable version of KiCad, make sure the latest available stable version is installed as issues may have already been resolved in later stable versions. -->
|
||||
# Description
|
||||
<!-- What is the current behavior and what is the expected behavior? -->
|
||||
<!-- If the issue is visual/graphical, please attach screenshots of the problem. -->
|
||||
<!-- Add the issue details below this line and before the "Steps to reproduce" heading. -->
|
||||
|
||||
# Steps to reproduce
|
||||
<!-- If there are multiple steps to reproduce it or it is a visual issue, then providing a screen recording as an attachment to this report is recommended. -->
|
||||
<!-- If this issue is specific to a project, please attach the necessary files to this issue. -->
|
||||
<!-- Add the steps to reproduce using the numbers below -->
|
||||
<!-- Add new step numbers before the "KiCad Version" heading. -->
|
||||
1.
|
||||
|
||||
# KiCad Version
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* 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
|
||||
@@ -671,8 +671,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
return false;
|
||||
}
|
||||
|
||||
// max dist from one endPt to next startPt
|
||||
int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
|
||||
int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
|
||||
|
||||
success = BuildFootprintPolygonOutlines( m_board, m_board_poly,
|
||||
m_board->GetDesignSettings().m_MaxError,
|
||||
|
||||
@@ -342,7 +342,8 @@ private:
|
||||
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
|
||||
|
||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
|
||||
bool aSkipNonPlatedPads );
|
||||
|
||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
@@ -145,7 +145,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner )
|
||||
{
|
||||
addText( aDimension, aContainer, aDimension );
|
||||
addText( &aDimension->Text(), aContainer, aDimension );
|
||||
|
||||
const int linewidth = aDimension->GetLineThickness();
|
||||
|
||||
@@ -275,10 +275,6 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
|
||||
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle );
|
||||
int circlesegcount;
|
||||
|
||||
// Avoid arcs that cannot be drawn
|
||||
if( radius < std::numeric_limits<double>::min() || arc_angle.IsZero() )
|
||||
break;
|
||||
|
||||
// We need a circle to segment count. However, the arc angle can be small, and the
|
||||
// radius very big. so we calculate a reasonable value for circlesegcount.
|
||||
if( arcsegcount <= 1 ) // The arc will be approximated by a segment
|
||||
@@ -492,24 +488,41 @@ OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
|
||||
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
{
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
if( !pad->IsOnLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
if( IsCopperLayer( aLayerId ) )
|
||||
{
|
||||
// Skip pad annulus when there isn't one (note: this is more discerning than
|
||||
// pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
|
||||
// the entire pad).
|
||||
if( !pad->IsOnCopperLayer() )
|
||||
continue;
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) )
|
||||
continue;
|
||||
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
|
||||
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
|
||||
{
|
||||
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
|
||||
{
|
||||
switch( pad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE::CIRCLE:
|
||||
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE::OVAL:
|
||||
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2I margin( 0, 0 );
|
||||
|
||||
@@ -525,7 +525,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// ADD PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, renderPlatedPadsAsPlated, false );
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad has the same shape
|
||||
// as its hole
|
||||
addPads( footprint, layerContainer, layer, true, renderPlatedPadsAsPlated, false );
|
||||
|
||||
// Micro-wave footprints may have items on copper layers
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
@@ -537,8 +539,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
// ADD PLATED PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, true, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, true, false, true );
|
||||
}
|
||||
|
||||
m_platedPadsFront->BuildBVH();
|
||||
@@ -993,7 +995,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
else
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, false, false );
|
||||
addPads( footprint, layerContainer, layer, false, false, false );
|
||||
}
|
||||
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
|
||||
@@ -383,15 +383,6 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
if( m_glRC == nullptr )
|
||||
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
|
||||
|
||||
// CreateCtx could and does fail per sentry crash events, lets be graceful
|
||||
if( m_glRC == nullptr )
|
||||
{
|
||||
warningReporter.Report( _( "OpenGL context creation error" ), RPT_SEVERITY_ERROR );
|
||||
warningReporter.Finalize();
|
||||
m_is_currently_painting.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
|
||||
|
||||
// Set the OpenGL viewport according to the client size of this canvas.
|
||||
|
||||
@@ -257,13 +257,6 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
|
||||
if( m_glRC == nullptr )
|
||||
m_glRC = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
|
||||
|
||||
// CreateCtx could and does fail per sentry crash events, lets be graceful
|
||||
if( m_glRC == nullptr )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::OnPaint creating gl context failed" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );
|
||||
|
||||
// Set the OpenGL viewport according to the client size of this canvas.
|
||||
@@ -330,16 +323,8 @@ void EDA_3D_MODEL_VIEWER::OnPaint( wxPaintEvent& event )
|
||||
m_ogl_3dmodel->BeginDrawMulti( true );
|
||||
|
||||
m_ogl_3dmodel->DrawOpaque( false );
|
||||
|
||||
glDepthMask( GL_FALSE );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
m_ogl_3dmodel->DrawTransparent( 1.0f, false );
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glDepthMask( GL_TRUE );
|
||||
|
||||
m_ogl_3dmodel->EndDrawMulti();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
@@ -27,14 +27,13 @@
|
||||
* @file c_ogl_3dmodel.cpp
|
||||
* @brief
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
|
||||
#include "3d_model.h"
|
||||
#include "opengl_utils.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include "../3d_math.h"
|
||||
#include <utility>
|
||||
#include <wx/debug.h>
|
||||
#include <wx/log.h>
|
||||
#include <chrono>
|
||||
@@ -178,11 +177,9 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
// use material color for mesh bounding box or some sort of average vertex color.
|
||||
glm::vec3 avg_color = material.m_Diffuse;
|
||||
|
||||
BBOX_3D &mesh_bbox = m_meshes_bbox[mesh_i];
|
||||
|
||||
for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
|
||||
{
|
||||
mesh_bbox.Union( mesh.m_Positions[vtx_i] );
|
||||
m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
|
||||
|
||||
VERTEX& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
|
||||
|
||||
@@ -225,19 +222,16 @@ MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
|
||||
}
|
||||
}
|
||||
|
||||
if( mesh_bbox.IsInitialized() )
|
||||
if( m_meshes_bbox[mesh_i].IsInitialized() )
|
||||
{
|
||||
// generate geometry for the bounding box
|
||||
MakeBbox( mesh_bbox, ( mesh_i + 1 ) * bbox_vtx_count,
|
||||
MakeBbox( m_meshes_bbox[mesh_i], ( mesh_i + 1 ) * bbox_vtx_count,
|
||||
&bbox_tmp_vertices[( mesh_i + 1 ) * bbox_vtx_count],
|
||||
&bbox_tmp_indices[( mesh_i + 1 ) * bbox_idx_count],
|
||||
{ avg_color, 1.0f } );
|
||||
|
||||
// bump the outer bounding box
|
||||
m_model_bbox.Union( mesh_bbox );
|
||||
|
||||
// add to the material group
|
||||
material.m_bbox.Union( mesh_bbox );
|
||||
m_model_bbox.Union( m_meshes_bbox[mesh_i] );
|
||||
}
|
||||
|
||||
|
||||
@@ -416,9 +410,7 @@ void MODEL_3D::EndDrawMulti()
|
||||
|
||||
|
||||
void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
const SFVEC3F& aSelectionColor,
|
||||
const glm::mat4 *aModelWorldMatrix,
|
||||
const SFVEC3F *aCameraWorldPos ) const
|
||||
SFVEC3F& aSelectionColor ) const
|
||||
{
|
||||
if( aOpacity <= FLT_EPSILON )
|
||||
return;
|
||||
@@ -447,102 +439,27 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
|
||||
|
||||
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)¶m.x );
|
||||
|
||||
std::vector<const MODEL_3D::MATERIAL *> materialsToRender;
|
||||
|
||||
materialsToRender.reserve( m_materials.size() );
|
||||
|
||||
if( aModelWorldMatrix && aCameraWorldPos )
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
// Sort Material groups
|
||||
|
||||
std::vector<std::pair<const MODEL_3D::MATERIAL*, float>> materialsSorted;
|
||||
|
||||
// Calculate the distance to the camera for each material group
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
if( mat.m_render_idx_count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
&& ( aOpacity >= 1.0f )
|
||||
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const BBOX_3D& bBox = mat.m_bbox;
|
||||
const SFVEC3F& bBoxCenter = bBox.GetCenter();
|
||||
const SFVEC3F bBoxWorld = *aModelWorldMatrix * glm::vec4( bBoxCenter, 1.0f );
|
||||
|
||||
const float distanceToCamera = glm::length( *aCameraWorldPos - bBoxWorld );
|
||||
|
||||
materialsSorted.emplace_back( &mat, distanceToCamera );
|
||||
}
|
||||
|
||||
// Sort from back to front
|
||||
std::sort( materialsSorted.begin(), materialsSorted.end(),
|
||||
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
|
||||
std::pair<const MODEL_3D::MATERIAL*, float>& b ) {
|
||||
// If A is inside B, then A is rendered first
|
||||
if( b.first->m_bbox.Inside( a.first->m_bbox ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a.first->m_bbox.Inside( b.first->m_bbox ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return a.second > b.second;
|
||||
} );
|
||||
|
||||
for( const std::pair<const MODEL_3D::MATERIAL*, float>& mat : materialsSorted )
|
||||
{
|
||||
materialsToRender.push_back( mat.first );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( const MODEL_3D::MATERIAL& mat : m_materials )
|
||||
{
|
||||
// There is at least one default material created in case a mesh has no declared materials.
|
||||
// Most meshes have a material, so usually the first material will have nothing to render and is skip.
|
||||
// See S3D::GetModel for more details.
|
||||
if( mat.m_render_idx_count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ( mat.IsTransparent() != aTransparent )
|
||||
&& ( aOpacity >= 1.0f )
|
||||
&& m_materialMode != MATERIAL_MODE::DIFFUSE_ONLY )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
materialsToRender.push_back( &mat );
|
||||
}
|
||||
}
|
||||
|
||||
for( const MODEL_3D::MATERIAL* mat : materialsToRender )
|
||||
{
|
||||
switch( m_materialMode )
|
||||
{
|
||||
case MATERIAL_MODE::NORMAL:
|
||||
OglSetMaterial( *mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
case MATERIAL_MODE::DIFFUSE_ONLY:
|
||||
OglSetDiffuseMaterial( mat->m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
case MATERIAL_MODE::CAD_MODE:
|
||||
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat->m_Diffuse ), aOpacity,
|
||||
OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
|
||||
aUseSelectedMaterial, aSelectionColor );
|
||||
break;
|
||||
|
||||
@@ -550,9 +467,9 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
|
||||
break;
|
||||
}
|
||||
|
||||
glDrawElements( GL_TRIANGLES, mat->m_render_idx_count, m_index_buffer_type,
|
||||
glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
|
||||
reinterpret_cast<const void*>(
|
||||
static_cast<uintptr_t>( mat->m_render_idx_buffer_offset ) ) );
|
||||
static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
*/
|
||||
void DrawOpaque( bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
|
||||
{
|
||||
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
|
||||
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,19 +63,9 @@ public:
|
||||
void DrawTransparent( float aOpacity, bool aUseSelectedMaterial,
|
||||
SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
|
||||
{
|
||||
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor, nullptr, nullptr );
|
||||
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the model into the current context.
|
||||
* if aModelWorldMatrix and aCameraWorldPos is provided,
|
||||
* it renders the material groups sorted.
|
||||
*/
|
||||
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
const SFVEC3F& aSelectionColor,
|
||||
const glm::mat4 *aModelWorldMatrix,
|
||||
const SFVEC3F *aCameraWorldPos ) const;
|
||||
|
||||
/**
|
||||
* Return true if have opaque meshes to render.
|
||||
*/
|
||||
@@ -146,8 +136,6 @@ private:
|
||||
unsigned int m_render_idx_buffer_offset = 0;
|
||||
unsigned int m_render_idx_count = 0;
|
||||
|
||||
BBOX_3D m_bbox; ///< bounding box for this material group, used for transparent material ordering
|
||||
|
||||
MATERIAL( const SMATERIAL& aOther ) : SMATERIAL( aOther ) { }
|
||||
bool IsTransparent() const { return m_Transparency > FLT_EPSILON; }
|
||||
};
|
||||
@@ -171,6 +159,9 @@ private:
|
||||
|
||||
static void MakeBbox( const BBOX_3D& aBox, unsigned int aIdxOffset, VERTEX* aVtxOut,
|
||||
GLuint* aIdxOut, const glm::vec4& aColor );
|
||||
|
||||
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
|
||||
SFVEC3F& aSelectionColor ) const;
|
||||
};
|
||||
|
||||
#endif // _MODEL_3D_H_
|
||||
|
||||
@@ -912,8 +912,7 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
{
|
||||
|
||||
@@ -22,19 +22,14 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
|
||||
#include "plugins/3dapi/xv3d_types.h"
|
||||
#include "render_3d_opengl.h"
|
||||
#include "opengl_utils.h"
|
||||
#include "common_ogl/ogl_utils.h"
|
||||
#include <footprint.h>
|
||||
#include <3d_math.h>
|
||||
#include <glm/geometric.hpp>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <base_units.h>
|
||||
@@ -863,12 +858,9 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
glm::mat4 cameraViewMatrix;
|
||||
|
||||
glGetFloatv( GL_MODELVIEW_MATRIX, glm::value_ptr( cameraViewMatrix ) );
|
||||
|
||||
// Render 3D Models (Non-transparent)
|
||||
renderOpaqueModels( cameraViewMatrix );
|
||||
render3dModels( false, false );
|
||||
render3dModels( true, false );
|
||||
|
||||
// Display board body
|
||||
if( m_boardAdapter.m_Cfg->m_Render.show_board_body )
|
||||
@@ -930,7 +922,8 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
|
||||
|
||||
renderTransparentModels( cameraViewMatrix );
|
||||
render3dModels( false, true );
|
||||
render3dModels( true, true );
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
OglResetTextureState();
|
||||
@@ -1150,15 +1143,14 @@ void RENDER_3D_OPENGL::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList,
|
||||
bool aGetTop, bool aGetBot, bool aRenderTransparentOnly,
|
||||
bool aRenderSelectedOnly )
|
||||
void RENDER_3D_OPENGL::render3dModelsSelected( bool aRenderTopOrBot, bool aRenderTransparentOnly,
|
||||
bool aRenderSelectedOnly )
|
||||
{
|
||||
wxASSERT( ( aGetTop == true ) || ( aGetBot == true ) );
|
||||
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
MODEL_3D::BeginDrawMulti( !aRenderSelectedOnly );
|
||||
|
||||
// Go for all footprints
|
||||
for( FOOTPRINT* fp : m_boardAdapter.GetBoard()->Footprints() )
|
||||
{
|
||||
@@ -1183,52 +1175,54 @@ void RENDER_3D_OPENGL::get3dModelsSelected( std::list<MODELTORENDER> &aDstRender
|
||||
{
|
||||
if( m_boardAdapter.IsFootprintShown( (FOOTPRINT_ATTR_T) fp->GetAttributes() ) )
|
||||
{
|
||||
const bool isFlipped = fp->IsFlipped();
|
||||
|
||||
if( ( aGetTop == !isFlipped ) ||
|
||||
( aGetBot == isFlipped ) )
|
||||
get3dModelsFromFootprint( aDstRenderList, fp, aRenderTransparentOnly, highlight );
|
||||
if( aRenderTopOrBot == !fp->IsFlipped() )
|
||||
renderFootprint( fp, aRenderTransparentOnly, highlight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MODEL_3D::EndDrawMulti();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
|
||||
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected )
|
||||
void RENDER_3D_OPENGL::render3dModels( bool aRenderTopOrBot, bool aRenderTransparentOnly )
|
||||
{
|
||||
if( m_boardAdapter.m_IsBoardView )
|
||||
render3dModelsSelected( aRenderTopOrBot, aRenderTransparentOnly, true );
|
||||
|
||||
render3dModelsSelected( aRenderTopOrBot, aRenderTransparentOnly, false );
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::renderFootprint( const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected )
|
||||
{
|
||||
if( !aFootprint->Models().empty() )
|
||||
{
|
||||
const double zpos = m_boardAdapter.GetFootprintZPos( aFootprint->IsFlipped() );
|
||||
SFVEC3F selColor = m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.opengl_selection_color );
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
VECTOR2I pos = aFootprint->GetPosition();
|
||||
|
||||
glm::mat4 fpMatrix( 1.0f );
|
||||
|
||||
fpMatrix = glm::translate( fpMatrix,
|
||||
SFVEC3F( pos.x * m_boardAdapter.BiuTo3dUnits(),
|
||||
-pos.y * m_boardAdapter.BiuTo3dUnits(),
|
||||
zpos ) );
|
||||
glTranslatef( pos.x * m_boardAdapter.BiuTo3dUnits(), -pos.y * m_boardAdapter.BiuTo3dUnits(),
|
||||
zpos );
|
||||
|
||||
if( !aFootprint->GetOrientation().IsZero() )
|
||||
{
|
||||
fpMatrix = glm::rotate( fpMatrix,
|
||||
(float) aFootprint->GetOrientation().AsRadians(),
|
||||
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
|
||||
}
|
||||
glRotated( aFootprint->GetOrientation().AsDegrees(), 0.0, 0.0, 1.0 );
|
||||
|
||||
if( aFootprint->IsFlipped() )
|
||||
{
|
||||
fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(), SFVEC3F( 0.0f, 1.0f, 0.0f ) );
|
||||
fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(), SFVEC3F( 0.0f, 0.0f, 1.0f ) );
|
||||
glRotatef( 180.0f, 0.0f, 1.0f, 0.0f );
|
||||
glRotatef( 180.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
const double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3dUnits() *
|
||||
UNITS3D_TO_UNITSPCB;
|
||||
double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3dUnits() * UNITS3D_TO_UNITSPCB;
|
||||
|
||||
fpMatrix = glm::scale( fpMatrix,
|
||||
SFVEC3F( modelunit_to_3d_units_factor ) );
|
||||
glScaled( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor,
|
||||
modelunit_to_3d_units_factor );
|
||||
|
||||
// Get the list of model files for this model
|
||||
for( const FP_3DMODEL& sM : aFootprint->Models() )
|
||||
@@ -1249,232 +1243,66 @@ void RENDER_3D_OPENGL::get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstR
|
||||
if( ( !aRenderTransparentOnly && modelPtr->HasOpaqueMeshes() && opaque ) ||
|
||||
( aRenderTransparentOnly && ( modelPtr->HasTransparentMeshes() || !opaque ) ) )
|
||||
{
|
||||
glm::mat4 modelworldMatrix = fpMatrix;
|
||||
glPushMatrix();
|
||||
|
||||
const SFVEC3F offset = SFVEC3F( sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z );
|
||||
const SFVEC3F rotation = SFVEC3F( sM.m_Rotation.x, sM.m_Rotation.y, sM.m_Rotation.z );
|
||||
const SFVEC3F scale = SFVEC3F( sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z );
|
||||
|
||||
std::vector<float> key = { offset.x, offset.y, offset.z,
|
||||
rotation.x, rotation.y, rotation.z,
|
||||
scale.x, scale.y, scale.z };
|
||||
std::vector<double> key = { sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z,
|
||||
sM.m_Rotation.x, sM.m_Rotation.y, sM.m_Rotation.z,
|
||||
sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z };
|
||||
|
||||
auto it = m_3dModelMatrixMap.find( key );
|
||||
|
||||
if( it != m_3dModelMatrixMap.end() )
|
||||
{
|
||||
modelworldMatrix *= it->second;
|
||||
glMultMatrixf( glm::value_ptr( it->second ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
glm::mat4 mtx( 1.0f );
|
||||
mtx = glm::translate( mtx, offset );
|
||||
mtx = glm::rotate( mtx, glm::radians( -rotation.z ), { 0.0f, 0.0f, 1.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( -rotation.y ), { 0.0f, 1.0f, 0.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( -rotation.x ), { 1.0f, 0.0f, 0.0f } );
|
||||
mtx = glm::scale( mtx, scale );
|
||||
glm::mat4 mtx( 1 );
|
||||
mtx = glm::translate( mtx, { sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.z ), { 0.0f, 0.0f, 1.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.y ), { 0.0f, 1.0f, 0.0f } );
|
||||
mtx = glm::rotate( mtx, glm::radians( (float) -sM.m_Rotation.x ), { 1.0f, 0.0f, 0.0f } );
|
||||
mtx = glm::scale( mtx, { sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z } );
|
||||
m_3dModelMatrixMap[ key ] = mtx;
|
||||
|
||||
modelworldMatrix *= mtx;
|
||||
glMultMatrixf( glm::value_ptr( mtx ) );
|
||||
}
|
||||
|
||||
|
||||
if( aRenderTransparentOnly )
|
||||
{
|
||||
aDstRenderList.emplace_back( modelworldMatrix,
|
||||
modelPtr,
|
||||
sM.m_Opacity,
|
||||
true,
|
||||
aFootprint->IsSelected() || aIsSelected );
|
||||
modelPtr->DrawTransparent( sM.m_Opacity,
|
||||
aFootprint->IsSelected() || aIsSelected,
|
||||
selColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
aDstRenderList.emplace_back( modelworldMatrix,
|
||||
modelPtr,
|
||||
1.0f,
|
||||
false,
|
||||
aFootprint->IsSelected() || aIsSelected );
|
||||
modelPtr->DrawOpaque( aFootprint->IsSelected() || aIsSelected, selColor );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.opengl_show_model_bbox )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
void RENDER_3D_OPENGL::renderOpaqueModels( const glm::mat4 &aCameraViewMatrix )
|
||||
{
|
||||
const SFVEC3F selColor = m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.opengl_selection_color );
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
glPushMatrix();
|
||||
glLineWidth( 1 );
|
||||
modelPtr->DrawBboxes();
|
||||
|
||||
std::list<MODELTORENDER> renderList;
|
||||
glLineWidth( 4 );
|
||||
modelPtr->DrawBbox();
|
||||
|
||||
if( m_boardAdapter.m_IsBoardView )
|
||||
{
|
||||
renderList.clear();
|
||||
glEnable( GL_LIGHTING );
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
|
||||
get3dModelsSelected( renderList, true, true, false, true );
|
||||
|
||||
if( !renderList.empty() )
|
||||
{
|
||||
MODEL_3D::BeginDrawMulti( false );
|
||||
|
||||
for( const MODELTORENDER& mtr : renderList )
|
||||
{
|
||||
renderModel( aCameraViewMatrix, mtr, selColor, nullptr );
|
||||
}
|
||||
|
||||
MODEL_3D::EndDrawMulti();
|
||||
}
|
||||
}
|
||||
|
||||
renderList.clear();
|
||||
get3dModelsSelected( renderList, true, true, false, false );
|
||||
|
||||
if( !renderList.empty() )
|
||||
{
|
||||
MODEL_3D::BeginDrawMulti( true );
|
||||
|
||||
for( const MODELTORENDER& mtr : renderList )
|
||||
{
|
||||
renderModel( aCameraViewMatrix, mtr, selColor, nullptr );
|
||||
}
|
||||
|
||||
MODEL_3D::EndDrawMulti();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::renderTransparentModels( const glm::mat4 &aCameraViewMatrix )
|
||||
{
|
||||
const SFVEC3F selColor = m_boardAdapter.GetColor( m_boardAdapter.m_Cfg->m_Render.opengl_selection_color );
|
||||
|
||||
std::list<MODELTORENDER> renderListModels; // do not clear it until this function returns
|
||||
|
||||
if( m_boardAdapter.m_IsBoardView )
|
||||
{
|
||||
// Get Transparent Selected
|
||||
get3dModelsSelected( renderListModels, true, true, true, true );
|
||||
}
|
||||
|
||||
// Get Transparent Not Selected
|
||||
get3dModelsSelected( renderListModels, true, true, true, false );
|
||||
|
||||
if( renderListModels.empty() )
|
||||
return;
|
||||
|
||||
std::vector<std::pair<const MODELTORENDER *, float>> transparentModelList;
|
||||
|
||||
transparentModelList.reserve( renderListModels.size() );
|
||||
|
||||
// Calculate the distance to the camera for each model
|
||||
const SFVEC3F &cameraPos = m_camera.GetPos();
|
||||
|
||||
for( const MODELTORENDER& mtr : renderListModels )
|
||||
{
|
||||
const BBOX_3D& bBox = mtr.m_model->GetBBox();
|
||||
const SFVEC3F& bBoxCenter = bBox.GetCenter();
|
||||
const SFVEC3F bBoxWorld = mtr.m_modelWorldMat * glm::vec4( bBoxCenter, 1.0f );
|
||||
|
||||
const float distanceToCamera = glm::length( cameraPos - bBoxWorld );
|
||||
|
||||
transparentModelList.emplace_back( &mtr, distanceToCamera );
|
||||
}
|
||||
|
||||
// Sort from back to front
|
||||
std::sort( transparentModelList.begin(), transparentModelList.end(),
|
||||
[&]( std::pair<const MODELTORENDER *, float>& a,
|
||||
std::pair<const MODELTORENDER *, float>& b ) {
|
||||
return a.second > b.second;
|
||||
} );
|
||||
|
||||
// Start rendering calls
|
||||
glPushMatrix();
|
||||
|
||||
bool isUsingColorInformation = !( transparentModelList.begin()->first->m_isSelected &&
|
||||
m_boardAdapter.m_IsBoardView );
|
||||
|
||||
MODEL_3D::BeginDrawMulti( isUsingColorInformation );
|
||||
|
||||
for( const std::pair<const MODELTORENDER *, float>& mtr : transparentModelList )
|
||||
{
|
||||
if( m_boardAdapter.m_IsBoardView )
|
||||
{
|
||||
// Toggle between using model color or the select color
|
||||
if( !isUsingColorInformation && !mtr.first->m_isSelected )
|
||||
{
|
||||
isUsingColorInformation = true;
|
||||
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnable( GL_COLOR_MATERIAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isUsingColorInformation && mtr.first->m_isSelected )
|
||||
{
|
||||
isUsingColorInformation = false;
|
||||
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glDisable( GL_COLOR_MATERIAL );
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render model, sort each individuall material group
|
||||
// by passing cameraPos
|
||||
renderModel( aCameraViewMatrix, *mtr.first, selColor, &cameraPos );
|
||||
}
|
||||
|
||||
MODEL_3D::EndDrawMulti();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_OPENGL::renderModel( const glm::mat4 &aCameraViewMatrix,
|
||||
const MODELTORENDER &aModelToRender,
|
||||
const SFVEC3F &aSelColor,
|
||||
const SFVEC3F *aCameraWorldPos )
|
||||
{
|
||||
const glm::mat4 modelviewMatrix = aCameraViewMatrix * aModelToRender.m_modelWorldMat;
|
||||
|
||||
glLoadMatrixf( glm::value_ptr( modelviewMatrix ) );
|
||||
|
||||
aModelToRender.m_model->Draw( aModelToRender.m_isTransparent,
|
||||
aModelToRender.m_opacity,
|
||||
aModelToRender.m_isSelected,
|
||||
aSelColor,
|
||||
&aModelToRender.m_modelWorldMat,
|
||||
aCameraWorldPos );
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.opengl_show_model_bbox )
|
||||
{
|
||||
const bool wasBlendEnabled = glIsEnabled( GL_BLEND );
|
||||
|
||||
if( !wasBlendEnabled )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
}
|
||||
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
glLineWidth( 1 );
|
||||
aModelToRender.m_model->DrawBboxes();
|
||||
|
||||
glLineWidth( 4 );
|
||||
aModelToRender.m_model->DrawBbox();
|
||||
|
||||
glEnable( GL_LIGHTING );
|
||||
|
||||
if( !wasBlendEnabled )
|
||||
{
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -129,44 +129,18 @@ private:
|
||||
*/
|
||||
void load3dModels( REPORTER* aStatusReporter );
|
||||
|
||||
struct MODELTORENDER
|
||||
{
|
||||
glm::mat4 m_modelWorldMat;
|
||||
const MODEL_3D* m_model;
|
||||
float m_opacity;
|
||||
bool m_isTransparent;
|
||||
bool m_isSelected;
|
||||
/**
|
||||
* @param aRenderTopOrBot true will render Top, false will render bottom
|
||||
* @param aRenderTransparentOnly true will render only the transparent objects, false will
|
||||
* render opaque
|
||||
*/
|
||||
void render3dModels( bool aRenderTopOrBot, bool aRenderTransparentOnly );
|
||||
|
||||
MODELTORENDER( glm::mat4 aModelWorldMat,
|
||||
const MODEL_3D* aNodel,
|
||||
float aOpacity,
|
||||
bool aIsTransparent,
|
||||
bool aIsSelected ) :
|
||||
m_modelWorldMat( std::move( aModelWorldMat ) ),
|
||||
m_model( aNodel ),
|
||||
m_opacity( aOpacity ),
|
||||
m_isTransparent( aIsTransparent ),
|
||||
m_isSelected( aIsSelected )
|
||||
{
|
||||
}
|
||||
};
|
||||
void render3dModelsSelected( bool aRenderTopOrBot, bool aRenderTransparentOnly,
|
||||
bool aRenderSelectedOnly );
|
||||
|
||||
void renderOpaqueModels( const glm::mat4 &aCameraViewMatrix );
|
||||
void renderTransparentModels( const glm::mat4 &aCameraViewMatrix );
|
||||
|
||||
void renderModel( const glm::mat4 &aCameraViewMatrix,
|
||||
const MODELTORENDER &aModelToRender,
|
||||
const SFVEC3F &aSelColor,
|
||||
const SFVEC3F *aCameraWorldPos );
|
||||
|
||||
|
||||
void get3dModelsSelected( std::list<MODELTORENDER> &aDstRenderList,
|
||||
bool aGetTop, bool aGetBot, bool aRenderTransparentOnly,
|
||||
bool aRenderSelectedOnly );
|
||||
|
||||
void get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstRenderList,
|
||||
const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected );
|
||||
void renderFootprint( const FOOTPRINT* aFootprint, bool aRenderTransparentOnly,
|
||||
bool aIsSelected );
|
||||
|
||||
void setLightFront( bool enabled );
|
||||
void setLightTop( bool enabled );
|
||||
@@ -236,7 +210,7 @@ private:
|
||||
|
||||
// Caches
|
||||
std::map< wxString, MODEL_3D* > m_3dModelMap;
|
||||
std::map< std::vector<float>, glm::mat4 > m_3dModelMatrixMap;
|
||||
std::map< std::vector<double>, glm::mat4 > m_3dModelMatrixMap;
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
|
||||
@@ -1202,8 +1202,7 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
|
||||
if( !m_boardAdapter.m_IsPreviewer
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
|
||||
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
|
||||
{
|
||||
|
||||
@@ -229,16 +229,6 @@ bool BBOX_2D::Inside( const SFVEC2F& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
bool BBOX_2D::Inside( const BBOX_2D& aBBox ) const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
wxASSERT( aBBox.IsInitialized() );
|
||||
|
||||
return Inside( aBBox.Min() ) &&
|
||||
Inside( aBBox.Max() );
|
||||
}
|
||||
|
||||
|
||||
float BBOX_2D::Area() const
|
||||
{
|
||||
SFVEC2F extent = GetExtent();
|
||||
|
||||
@@ -132,14 +132,6 @@ public:
|
||||
*/
|
||||
bool Inside( const SFVEC2F& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Check if a bounding box is inside this bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to test if it is inside
|
||||
* @return true if aBBox is smaller and all points are inside
|
||||
*/
|
||||
bool Inside( const BBOX_2D& aBBox ) const;
|
||||
|
||||
/**
|
||||
* Calculate the area of a bounding box.
|
||||
*
|
||||
|
||||
@@ -238,16 +238,6 @@ bool BBOX_3D::Inside( const SFVEC3F& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
bool BBOX_3D::Inside( const BBOX_3D& aBBox ) const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
wxASSERT( aBBox.IsInitialized() );
|
||||
|
||||
return Inside( aBBox.Min() ) &&
|
||||
Inside( aBBox.Max() );
|
||||
}
|
||||
|
||||
|
||||
float BBOX_3D::Volume() const
|
||||
{
|
||||
wxASSERT( IsInitialized() );
|
||||
|
||||
@@ -125,14 +125,6 @@ public:
|
||||
*/
|
||||
bool Inside( const SFVEC3F& aPoint ) const;
|
||||
|
||||
/**
|
||||
* Check if a bounding box is inside this bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to test if it is inside
|
||||
* @return true if aBBox is smaller and all points are inside
|
||||
*/
|
||||
bool Inside( const BBOX_3D& aBBox ) const;
|
||||
|
||||
/**
|
||||
* Apply a transformation matrix to the box points.
|
||||
*
|
||||
|
||||
@@ -70,8 +70,6 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
|
||||
m_selected = -1;
|
||||
|
||||
m_previewLabel->SetFont( KIUI::GetStatusFont( this ) );
|
||||
|
||||
// Set the bitmap of 3D view buttons:
|
||||
m_bpvTop->SetBitmap( KiBitmap( BITMAPS::axis3d_top ) );
|
||||
m_bpvFront->SetBitmap( KiBitmap( BITMAPS::axis3d_front ) );
|
||||
@@ -142,9 +140,6 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
this );
|
||||
}
|
||||
|
||||
aFrame->Connect( UNITS_CHANGED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
|
||||
#ifdef __WXOSX__
|
||||
// Call layout once to get the proper button sizes after the bitmaps have been set
|
||||
Layout();
|
||||
@@ -543,29 +538,6 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelOffset( wxMouseEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onUnitsChanged( wxCommandEvent& aEvent )
|
||||
{
|
||||
double xoff_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
xoff->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
double yoff_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
yoff->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
double zoff_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
zoff->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
|
||||
PCB_BASE_FRAME* frame = static_cast<PCB_BASE_FRAME*>( aEvent.GetClientData() );
|
||||
m_userUnits = frame->GetUserUnits();
|
||||
|
||||
xoff->SetValue( formatOffsetValue( xoff_mm ) );
|
||||
yoff->SetValue( formatOffsetValue( yoff_mm ) );
|
||||
zoff->SetValue( formatOffsetValue( zoff_mm ) );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::UpdateDummyFootprint( bool aReloadRequired )
|
||||
{
|
||||
m_dummyFootprint->Models().clear();
|
||||
|
||||
@@ -141,8 +141,6 @@ private:
|
||||
void doIncrementRotation( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementOffset( wxSpinEvent& aEvent, double aSign );
|
||||
|
||||
void onUnitsChanged( wxCommandEvent& aEvent );
|
||||
|
||||
wxString formatScaleValue( double aValue );
|
||||
wxString formatRotationValue( double aValue );
|
||||
wxString formatOffsetValue( double aValue );
|
||||
|
||||
@@ -183,11 +183,12 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
wxBoxSizer* bSizer6;
|
||||
bSizer6 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_previewLabel = new wxStaticText( this, wxID_ANY, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_previewLabel->Wrap( -1 );
|
||||
m_previewLabel->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
|
||||
wxStaticText* staticPreviewLabel;
|
||||
staticPreviewLabel = new wxStaticText( this, wxID_ANY, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
staticPreviewLabel->Wrap( -1 );
|
||||
staticPreviewLabel->SetFont( wxFont( 11, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
|
||||
|
||||
bSizer6->Add( m_previewLabel, 1, wxEXPAND|wxLEFT|wxRIGHT, 10 );
|
||||
bSizer6->Add( staticPreviewLabel, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 );
|
||||
|
||||
|
||||
bSizerRight->Add( bSizer6, 0, wxEXPAND, 5 );
|
||||
@@ -206,7 +207,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_bpvISO = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
|
||||
m_bpvISO->SetToolTip( _("Enable/disable orthographic projection") );
|
||||
|
||||
bSizer3DButtons->Add( m_bpvISO, 0, wxTOP, 14 );
|
||||
bSizer3DButtons->Add( m_bpvISO, 0, wxTOP|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
@@ -2089,7 +2089,7 @@
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">10</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">1</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@@ -2127,11 +2127,11 @@
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_previewLabel</property>
|
||||
<property name="name">staticPreviewLabel</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
@@ -2172,8 +2172,8 @@
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">14</property>
|
||||
<property name="flag">wxTOP</property>
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxTOP|wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
||||
@@ -68,7 +68,6 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
wxSlider* m_opacity;
|
||||
wxTextCtrl* m_boardThicknessCtrl;
|
||||
wxStaticText* m_boardThicknessUnits;
|
||||
wxStaticText* m_previewLabel;
|
||||
wxBoxSizer* m_SizerPanelView;
|
||||
wxBitmapButton* m_bpvISO;
|
||||
wxBitmapButton* m_bpvLeft;
|
||||
|
||||
+2
-6
@@ -350,16 +350,12 @@ endif(USE_DISTCC)
|
||||
# Set flags for GCC, or treat llvm as GCC
|
||||
#================================================
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
|
||||
# Set 32-bit flag for GCC to prevent excess precision
|
||||
# clang des not know this flag, so keep this separate
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
|
||||
set( CMAKE_CXX_FLAGS "-ffloat-store ${CMAKE_CXX_FLAGS}" )
|
||||
endif()
|
||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
|
||||
# Link flags in Debug: -g1 and -ggdb1 or -g1 and -ggdb3 can be used.
|
||||
# Level 1 produces minimal information, enough for making basic backtraces.
|
||||
|
||||
@@ -66,7 +66,7 @@ macro( create_git_version_header _git_src_path )
|
||||
# Check to make sure 'git' command did not fail. Otherwise fallback
|
||||
# to KiCadVersion.cmake as the revision level.
|
||||
if( _git_describe_result EQUAL 0 )
|
||||
set( KICAD_VERSION "${_git_DESCRIBE}" )
|
||||
set( KICAD_VERSION "(${_git_DESCRIBE})" )
|
||||
endif()
|
||||
|
||||
if( _git_rev_parse_head_result EQUAL 0 )
|
||||
|
||||
@@ -926,17 +926,8 @@ if(wxWidgets_FOUND)
|
||||
"\\2" wxWidgets_VERSION_MINOR "${_wx_version_h}" )
|
||||
string(REGEX REPLACE "^(.*\n)?#define +wxRELEASE_NUMBER +([0-9]+).*"
|
||||
"\\2" wxWidgets_VERSION_PATCH "${_wx_version_h}" )
|
||||
string(REGEX REPLACE "^(.*\n)?#define +wxSUBRELEASE_NUMBER +([0-9]+).*"
|
||||
"\\2" wxWidgets_VERSION_SUBRELEASE "${_wx_version_h}" )
|
||||
|
||||
if( ${wxWidgets_VERSION_SUBRELEASE} GREATER 0 )
|
||||
set(wxWidgets_VERSION_STRING
|
||||
"${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}.${wxWidgets_VERSION_SUBRELEASE}" )
|
||||
else()
|
||||
set(wxWidgets_VERSION_STRING
|
||||
"${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" )
|
||||
endif()
|
||||
|
||||
set(wxWidgets_VERSION_STRING
|
||||
"${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" )
|
||||
DBG_MSG("wxWidgets_VERSION_STRING: ${wxWidgets_VERSION_STRING}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.2" )
|
||||
set( KICAD_SEMANTIC_VERSION "7.99.0-unknown" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <eda_base_frame.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <paths.h>
|
||||
#include <kiplatform/ui.h>
|
||||
|
||||
|
||||
static std::unique_ptr<BITMAP_STORE> s_BitmapStore;
|
||||
|
||||
+11
-18
@@ -75,7 +75,6 @@ void BITMAP_BASE::SetImage( wxImage* aImage )
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *aImage );
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,21 +90,6 @@ void BITMAP_BASE::rebuildBitmap( bool aResetID )
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::updatePPI()
|
||||
{
|
||||
// Todo: eventually we need to support dpi / scaling in both dimensions
|
||||
int dpiX = m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
|
||||
if( dpiX > 1 )
|
||||
{
|
||||
if( m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
|
||||
m_ppi = KiROUND( dpiX * 2.54 );
|
||||
else
|
||||
m_ppi = dpiX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
|
||||
{
|
||||
*m_image = *aItem->m_image;
|
||||
@@ -132,7 +116,6 @@ bool BITMAP_BASE::ReadImageFile( wxInputStream& aInStream )
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -153,7 +136,17 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
|
||||
// Todo: eventually we need to support dpi / scaling in both dimensions
|
||||
int dpiX = m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
|
||||
if( dpiX > 1 )
|
||||
{
|
||||
if( m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
|
||||
m_ppi = KiROUND( dpiX * 2.54 );
|
||||
else
|
||||
m_ppi = dpiX;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -177,20 +177,12 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
|
||||
|
||||
aMsg << eol;
|
||||
|
||||
wxString osDescription;
|
||||
|
||||
#if __LINUX__
|
||||
osDescription = wxGetLinuxDistributionInfo().Description;
|
||||
#endif
|
||||
|
||||
// Linux uses the lsb-release program to get the description of the OS, if lsb-release
|
||||
// isn't installed, then the string will be empty and we fallback to the method used on
|
||||
// the other platforms (to at least get the kernel/uname info).
|
||||
if( osDescription.empty() )
|
||||
osDescription = wxGetOsDescription();
|
||||
|
||||
aMsg << "Platform: "
|
||||
<< osDescription << ", "
|
||||
#if __LINUX__
|
||||
<< wxGetLinuxDistributionInfo().Description << ", "
|
||||
#else
|
||||
<< wxGetOsDescription() << ", "
|
||||
#endif
|
||||
<< GetPlatformGetBitnessName() << ", "
|
||||
<< platform.GetEndiannessName() << ", "
|
||||
<< platform.GetPortIdName();
|
||||
|
||||
+21
-4
@@ -31,13 +31,30 @@
|
||||
#include <dialogs/html_message_box.h>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <pgm_base.h>
|
||||
#include "cli/cli_names.h"
|
||||
|
||||
// Set of dialogs that have been chosen not to be shown again
|
||||
static std::unordered_map<unsigned long, int> doNotShowAgainDlgs;
|
||||
|
||||
|
||||
bool IsGUI()
|
||||
{
|
||||
if( !wxTheApp )
|
||||
return false;
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
return wxTheApp->IsGUI();
|
||||
#else
|
||||
// wxWidgets older than version 3.1.6 do not have a way to know if the app
|
||||
// has a GUI or is a console application.
|
||||
// So the trick is to set the App class name when starting kicad-cli, and when
|
||||
// the app class name is the kicad-cli class name the app is a console app
|
||||
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
|
||||
return run_gui;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
KIDIALOG::KIDIALOG( wxWindow* aParent, const wxString& aMessage, const wxString& aCaption,
|
||||
long aStyle )
|
||||
: wxRichMessageDialog( aParent, aMessage, aCaption, aStyle | wxCENTRE | wxSTAY_ON_TOP ),
|
||||
@@ -288,7 +305,7 @@ void DisplayError( wxWindow* aParent, const wxString& aText, int aDisplayTime )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Pgm().IsGUI() )
|
||||
if( !IsGUI() )
|
||||
{
|
||||
wxFprintf( stderr, aText );
|
||||
return;
|
||||
@@ -313,7 +330,7 @@ void DisplayErrorMessage( wxWindow* aParent, const wxString& aText, const wxStri
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Pgm().IsGUI() )
|
||||
if( !IsGUI() )
|
||||
{
|
||||
wxFprintf( stderr, aText );
|
||||
return;
|
||||
@@ -340,7 +357,7 @@ void DisplayInfoMessage( wxWindow* aParent, const wxString& aMessage, const wxSt
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Pgm().IsGUI() )
|
||||
if( !IsGUI() )
|
||||
{
|
||||
wxFprintf( stdout, "%s %s", aMessage, aExtraInfo );
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* 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
|
||||
@@ -178,15 +178,7 @@ bool DATABASE_CONNECTION::Disconnect()
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_conn->disconnect();
|
||||
}
|
||||
catch( boost::locale::conv::conversion_error& exc )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "Disconnect() error \"%s\" occured." ), exc.what() );
|
||||
return false;
|
||||
}
|
||||
m_conn->disconnect();
|
||||
|
||||
return !m_conn->connected();
|
||||
}
|
||||
|
||||
@@ -659,10 +659,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Greek (el_GR)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "aris-kimi" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Greek (el_GR)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Adolfo Jayme Barrientos" ),
|
||||
wxEmptyString,
|
||||
@@ -692,10 +688,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish (ES)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "VicSanRoPe" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Spanish - Latin American (ES)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ulices Avila Hernandez" ),
|
||||
wxEmptyString,
|
||||
@@ -830,46 +822,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김낙환" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이기형" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "남우근" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "강명구" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김용재" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "서범기" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김세영" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이윤성" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "KwonHyeokbeom" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Minsu Kim (0xGabriel)" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Korean (KO)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
|
||||
wxEmptyString,
|
||||
@@ -900,14 +860,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tom Niesse" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Christiaan Nieuwlaat" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Dutch (NL)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jarl Gjessing" ),
|
||||
wxEmptyString,
|
||||
@@ -980,10 +932,6 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Portuguese (PT)" ) ) );
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "ssantos" ),
|
||||
wxEmptyString,
|
||||
wxEmptyString,
|
||||
wxS( "Portuguese (PT)" ) ) );
|
||||
|
||||
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Igor Plyatov" ),
|
||||
wxEmptyString,
|
||||
@@ -1181,7 +1129,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
#define SYMBOL_LIB_CONTRIBUTION _( "Symbols by" )
|
||||
aInfo.AddLibrarian( new CONTRIBUTOR( wxS( "GitLab contributors" ),
|
||||
wxEmptyString,
|
||||
wxS( "https://gitlab.com/kicad/libraries/kicad-symbols/-/graphs/master" ),
|
||||
wxS( "https://gitlab.com/kicad/libraries/kicad-symbols/-/graphs/v7" ),
|
||||
SYMBOL_LIB_CONTRIBUTION,
|
||||
aInfo.CreateKiBitmap( BITMAPS::add_component ) ) );
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ bool DIALOG_PAGES_SETTINGS::TransferDataFromWindow()
|
||||
m_screen->SetContentModified();
|
||||
|
||||
if( LocalPrjConfigChanged() )
|
||||
m_parent->OnModify();
|
||||
m_parent->SaveProjectSettings();
|
||||
|
||||
// Call the post processing (if any) after changes
|
||||
m_parent->OnPageSettingsChange();
|
||||
@@ -674,9 +674,9 @@ void DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample()
|
||||
|
||||
GRFilledRect( &memDC, VECTOR2I( 0, 0 ), m_layout_size, 0, bgColor, bgColor );
|
||||
|
||||
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, emptyString,
|
||||
m_tb, nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(),
|
||||
1, &Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
|
||||
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, m_tb,
|
||||
nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(), 1,
|
||||
&Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
|
||||
|
||||
memDC.SelectObject( wxNullBitmap );
|
||||
m_PageLayoutExampleBitmap->SetBitmap( *m_pageBitmap );
|
||||
|
||||
@@ -117,7 +117,8 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
|
||||
|
||||
if( idx == static_cast<int>( m_cbTheme->GetCount() ) - 2 )
|
||||
{
|
||||
m_cbTheme->SetStringSelection( GetSettingsDropdownName( m_currentSettings ) );
|
||||
// separator; re-select active theme
|
||||
m_cbTheme->SetStringSelection( m_currentSettings->GetName() );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -216,7 +217,10 @@ void PANEL_COLOR_SETTINGS::createThemeList( const wxString& aCurrent )
|
||||
|
||||
for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
|
||||
{
|
||||
wxString name = GetSettingsDropdownName( settings );
|
||||
wxString name = settings->GetName();
|
||||
|
||||
if( settings->IsReadOnly() )
|
||||
name += wxS( " " ) + _( "(read-only)" );
|
||||
|
||||
int pos = m_cbTheme->Append( name, static_cast<void*>( settings ) );
|
||||
|
||||
@@ -258,11 +262,8 @@ void PANEL_COLOR_SETTINGS::createSwatch( int aLayer, const wxString& aName )
|
||||
defaultColor, SWATCH_MEDIUM );
|
||||
swatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
|
||||
|
||||
// Display the swatches in the left column and the layer name in the right column
|
||||
// The right column is sometimes (depending on the translation) truncated for long texts.
|
||||
// We cannot allow swatches to be truncated or not shown
|
||||
m_colorsGridSizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3 );
|
||||
m_colorsGridSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxLEFT, 5 );
|
||||
m_colorsGridSizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3 );
|
||||
|
||||
m_labels[aLayer] = label;
|
||||
m_swatches[aLayer] = swatch;
|
||||
@@ -282,8 +283,6 @@ void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLaye
|
||||
auto selected =
|
||||
static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( m_cbTheme->GetSelection() ) );
|
||||
|
||||
wxCHECK_RET( selected, wxT( "Invalid color theme selected" ) );
|
||||
|
||||
COLOR4D current = m_currentSettings->GetColor( aLayer );
|
||||
COLOR4D saved = selected->GetColor( aLayer );
|
||||
bool readOnly = m_currentSettings->IsReadOnly();
|
||||
@@ -377,14 +376,3 @@ bool PANEL_COLOR_SETTINGS::saveCurrentTheme( bool aValidate )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wxString PANEL_COLOR_SETTINGS::GetSettingsDropdownName(COLOR_SETTINGS* aSettings)
|
||||
{
|
||||
wxString name = aSettings->GetName();
|
||||
|
||||
if( aSettings->IsReadOnly() )
|
||||
name += wxS( " " ) + _( "(read-only)" );
|
||||
|
||||
return name;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 jean-pierre.charras
|
||||
* Copyright (C) 2011-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2011-2020 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
|
||||
@@ -110,19 +110,12 @@ bool PANEL_IMAGE_EDITOR::TransferDataFromWindow()
|
||||
void PANEL_IMAGE_EDITOR::OnRedrawPanel( wxPaintEvent& event )
|
||||
{
|
||||
wxPaintDC dc( m_panelDraw );
|
||||
wxSize display_size = m_panelDraw->GetClientSize();
|
||||
wxSize size = m_panelDraw->GetClientSize();
|
||||
dc.SetDeviceOrigin( size.x / 2, size.y / 2 );
|
||||
|
||||
double img_scale = 1.0 / m_workingImage->GetScalingFactor();
|
||||
VECTOR2I img_size_pixels = m_workingImage->GetSizePixels();
|
||||
|
||||
// Adjust the display scale to use the full available display area
|
||||
double scale_X = (double)display_size.x/img_size_pixels.x;
|
||||
double scale_Y = (double)display_size.y/img_size_pixels.y;
|
||||
|
||||
double display_scale = img_scale * std::min( scale_X, scale_Y );
|
||||
|
||||
dc.SetUserScale( display_scale, display_scale );
|
||||
m_workingImage->DrawBitmap( &dc, VECTOR2I( m_workingImage->GetSize()/2 ) );
|
||||
double scale = 1.0 / m_workingImage->GetScalingFactor();
|
||||
dc.SetUserScale( scale, scale );
|
||||
m_workingImage->DrawBitmap( &dc, wxPoint( 0, 0 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
@@ -1,368 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="16" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">panel_image_editor_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">panel_image_editor_base</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Panel" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">PANEL_IMAGE_EDITOR_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">500,300</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerMain</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bUpperSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerLeft</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND | wxALL</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxPanel" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">256,256</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_panelDraw</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL|wxBORDER_SIMPLE</property>
|
||||
<event name="OnPaint">OnRedrawPanel</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerRight</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="current"></property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="disabled"></property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="focus"></property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Grey</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_buttonGrey</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="position"></property>
|
||||
<property name="pressed"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">OnGreyScaleConvert</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">10</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="spacer" expanded="1">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Image Scale:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticTextScale</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength">0</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_textCtrlScale</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
+11
-10
@@ -58,13 +58,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
|
||||
wxScrolledCanvas( aParentWindow, aWindowId, aPosition, aSize ),
|
||||
m_MouseCapturedLost( false ),
|
||||
m_parent( aParentWindow ),
|
||||
m_edaFrame( nullptr ),
|
||||
m_lastRefresh( 0 ),
|
||||
m_pendingRefresh( false ),
|
||||
m_drawing( false ),
|
||||
m_drawingEnabled( false ),
|
||||
m_gal( nullptr ),
|
||||
m_view( nullptr ),
|
||||
m_painter( nullptr ),
|
||||
@@ -76,9 +70,10 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
m_stealsFocus( true ),
|
||||
m_statusPopup( nullptr )
|
||||
{
|
||||
m_PaintEventCounter = std::make_unique<PROF_COUNTER>( "Draw panel paint events" );
|
||||
m_parent = aParentWindow;
|
||||
m_MouseCapturedLost = false;
|
||||
|
||||
m_minRefreshPeriod = 13; // 77 FPS (minus render time) by default
|
||||
m_PaintEventCounter = std::make_unique<PROF_COUNTER>( "Draw panel paint events" );
|
||||
|
||||
SetLayoutDirection( wxLayout_LeftToRight );
|
||||
|
||||
@@ -151,6 +146,12 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
Connect( eventType, wxEventHandler( EDA_DRAW_PANEL_GAL::OnEvent ), nullptr,
|
||||
m_eventDispatcher );
|
||||
|
||||
m_pendingRefresh = false;
|
||||
m_drawing = false;
|
||||
m_drawingEnabled = false;
|
||||
|
||||
m_minRefreshPeriod = 13; // 77 FPS (minus render time) by default
|
||||
|
||||
// Set up timer that prevents too frequent redraw commands
|
||||
m_refreshTimer.SetOwner( this );
|
||||
Connect( m_refreshTimer.GetId(), wxEVT_TIMER,
|
||||
@@ -211,7 +212,7 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||
if( !m_drawingEnabled )
|
||||
return;
|
||||
|
||||
if( !m_gal->IsInitialized() || !m_gal->IsVisible() )
|
||||
if( !m_gal->IsVisible() )
|
||||
return;
|
||||
|
||||
m_pendingRefresh = false;
|
||||
@@ -626,7 +627,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( m_gal && m_gal->IsInitialized() && m_gal->IsVisible() )
|
||||
if( m_gal && m_gal->IsVisible() )
|
||||
{
|
||||
m_onShowTimer.Stop();
|
||||
OnShow();
|
||||
|
||||
@@ -219,10 +219,6 @@ void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
|
||||
if( canCloseWindow( event ) )
|
||||
{
|
||||
m_isClosing = true;
|
||||
|
||||
if( m_infoBar )
|
||||
m_infoBar->Dismiss();
|
||||
|
||||
APP_SETTINGS_BASE* cfg = config();
|
||||
|
||||
if( cfg )
|
||||
@@ -1234,7 +1230,7 @@ bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
|
||||
|
||||
void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
{
|
||||
if( !Pgm().IsGUI() )
|
||||
if( !IsGUI() )
|
||||
return;
|
||||
|
||||
wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
|
||||
|
||||
+13
-27
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2004-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-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
|
||||
@@ -78,16 +78,12 @@ BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, KIWAY_PLAYER )
|
||||
EVT_ACTIVATE( EDA_DRAW_FRAME::onActivate )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
bool EDA_DRAW_FRAME::m_openGLFailureOccured = false;
|
||||
|
||||
|
||||
EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
|
||||
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
|
||||
long aStyle, const wxString& aFrameName,
|
||||
const EDA_IU_SCALE& aIuScale ) :
|
||||
KIWAY_PLAYER( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, aIuScale ),
|
||||
m_socketServer( nullptr )
|
||||
long aStyle, const wxString& aFrameName, const EDA_IU_SCALE& aIuScale ) :
|
||||
KIWAY_PLAYER( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, aIuScale )
|
||||
{
|
||||
m_socketServer = nullptr;
|
||||
m_mainToolBar = nullptr;
|
||||
@@ -175,8 +171,8 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
|
||||
OnMove( dummy );
|
||||
|
||||
// we need to kludge the msg panel to the correct size again
|
||||
// especially important even for first launches as the constructor of the window
|
||||
// here usually doesn't have the correct dpi awareness yet
|
||||
// especially important even for first launches as the constructor of the window here usually doesn't
|
||||
// have the correct dpi awareness yet
|
||||
m_frameSize.y += m_msgFrameHeight;
|
||||
m_msgFrameHeight = EDA_MSG_PANEL::GetRequiredHeight( this );
|
||||
m_frameSize.y -= m_msgFrameHeight;
|
||||
@@ -289,7 +285,7 @@ void EDA_DRAW_FRAME::ToggleUserUnits()
|
||||
else
|
||||
{
|
||||
SetUserUnits( GetUserUnits() == EDA_UNITS::INCHES ? EDA_UNITS::MILLIMETRES
|
||||
: EDA_UNITS::INCHES );
|
||||
: EDA_UNITS::INCHES );
|
||||
unitsChangeRefresh();
|
||||
|
||||
wxCommandEvent e( UNITS_CHANGED );
|
||||
@@ -613,8 +609,7 @@ void EDA_DRAW_FRAME::DisplayGridMsg()
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x,
|
||||
false ) );
|
||||
msg.Printf( wxS( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x, false ) );
|
||||
|
||||
SetStatusText( msg, 4 );
|
||||
}
|
||||
@@ -990,8 +985,8 @@ static const wxString productName = wxT( "KiCad E.D.A. " );
|
||||
|
||||
|
||||
void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPageInfo,
|
||||
const wxString& aSheetName, const wxString& aSheetPath,
|
||||
const wxString& aFileName, const TITLE_BLOCK& aTitleBlock,
|
||||
const wxString& aFullSheetName, const wxString& aFileName,
|
||||
const TITLE_BLOCK& aTitleBlock,
|
||||
const std::map<wxString, wxString>* aProperties, int aSheetCount,
|
||||
const wxString& aPageNumber, double aMils2Iu, const PROJECT* aProject,
|
||||
const wxString& aSheetLayer, bool aIsFirstPage )
|
||||
@@ -1003,8 +998,7 @@ void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPage
|
||||
drawList.SetPageNumber( aPageNumber );
|
||||
drawList.SetSheetCount( aSheetCount );
|
||||
drawList.SetFileName( aFileName );
|
||||
drawList.SetSheetName( aSheetName );
|
||||
drawList.SetSheetPath( aSheetPath );
|
||||
drawList.SetSheetName( aFullSheetName );
|
||||
drawList.SetSheetLayer( aSheetLayer );
|
||||
drawList.SetProject( aProject );
|
||||
drawList.SetIsFirstPage( aIsFirstPage );
|
||||
@@ -1034,10 +1028,9 @@ void EDA_DRAW_FRAME::PrintDrawingSheet( const RENDER_SETTINGS* aSettings, BASE_S
|
||||
DC->SetAxisOrientation( true, false );
|
||||
}
|
||||
|
||||
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), GetFullScreenDesc(),
|
||||
aFilename, GetTitleBlock(), aProperties, aScreen->GetPageCount(),
|
||||
aScreen->GetPageNumber(), aMils2Iu, &Prj(), aSheetLayer,
|
||||
aScreen->GetVirtualPageNumber() == 1 );
|
||||
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), aFilename, GetTitleBlock(),
|
||||
aProperties, aScreen->GetPageCount(), aScreen->GetPageNumber(), aMils2Iu,
|
||||
&Prj(), aSheetLayer, aScreen->GetVirtualPageNumber() == 1 );
|
||||
|
||||
if( origin.y > 0 )
|
||||
{
|
||||
@@ -1054,13 +1047,6 @@ wxString EDA_DRAW_FRAME::GetScreenDesc() const
|
||||
}
|
||||
|
||||
|
||||
wxString EDA_DRAW_FRAME::GetFullScreenDesc() const
|
||||
{
|
||||
// Virtual function. Base class implementation returns an empty string.
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
|
||||
const wxString& wildcard, const wxString& ext,
|
||||
bool isDirectory, bool aIsGlobal,
|
||||
|
||||
+4
-3
@@ -392,9 +392,10 @@ static struct EDA_ITEM_DESC
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( EDA_ITEM );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_ITEM, KICAD_T>( wxS( "Type" ),
|
||||
NO_SETTER( EDA_ITEM, KICAD_T ), &EDA_ITEM::Type ) )
|
||||
.SetIsHiddenFromPropertiesManager();
|
||||
auto typeProp = new PROPERTY_ENUM<EDA_ITEM, KICAD_T>( wxS( "Type" ),
|
||||
NO_SETTER( EDA_ITEM, KICAD_T ), &EDA_ITEM::Type );
|
||||
typeProp->SetIsInternal( true );
|
||||
propMgr.AddProperty( typeProp );
|
||||
}
|
||||
} _EDA_ITEM_DESC;
|
||||
|
||||
|
||||
+5
-30
@@ -1687,36 +1687,21 @@ static struct EDA_SHAPE_DESC
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( EDA_SHAPE );
|
||||
|
||||
auto isNotPolygon =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() != SHAPE_T::POLY;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
auto shape = new PROPERTY_ENUM<EDA_SHAPE, SHAPE_T>( _HKI( "Shape" ),
|
||||
NO_SETTER( EDA_SHAPE, SHAPE_T ), &EDA_SHAPE::GetShape );
|
||||
propMgr.AddProperty( shape );
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start X" ),
|
||||
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
|
||||
.SetAvailableFunc( isNotPolygon );
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) );
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start Y" ),
|
||||
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
|
||||
.SetAvailableFunc( isNotPolygon );
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End X" ),
|
||||
&EDA_SHAPE::SetEndX, &EDA_SHAPE::GetEndX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
|
||||
.SetAvailableFunc( isNotPolygon );
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) );
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End Y" ),
|
||||
&EDA_SHAPE::SetEndY, &EDA_SHAPE::GetEndY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
|
||||
.SetAvailableFunc( isNotPolygon );
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
|
||||
// TODO: m_arcCenter, m_bezierC1, m_bezierC2, m_poly
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
|
||||
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
|
||||
@@ -1736,17 +1721,7 @@ static struct EDA_SHAPE_DESC
|
||||
filled->SetAvailableFunc(
|
||||
[=]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
SHAPE_T itemShape;
|
||||
|
||||
try
|
||||
{
|
||||
itemShape = aItem->Get<SHAPE_T>( shape );
|
||||
}
|
||||
catch( std::runtime_error& err )
|
||||
{
|
||||
wxFAIL_MSG( err.what() );
|
||||
return false;
|
||||
}
|
||||
SHAPE_T itemShape = aItem->Get<SHAPE_T>( shape );
|
||||
|
||||
switch( itemShape )
|
||||
{
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see change_log.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
|
||||
|
||||
@@ -65,7 +65,7 @@ int EDA_UNIT_UTILS::Mils2mm( double aVal )
|
||||
}
|
||||
|
||||
|
||||
bool EDA_UNIT_UTILS::FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS& aUnits )
|
||||
void EDA_UNIT_UTILS::FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS& aUnits )
|
||||
{
|
||||
wxString buf( aTextValue.Strip( wxString::both ) );
|
||||
unsigned brk_point = 0;
|
||||
@@ -92,9 +92,6 @@ bool EDA_UNIT_UTILS::FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS
|
||||
aUnits = EDA_UNITS::INCHES;
|
||||
else if( unit == wxT( "de" ) || unit == wxT( "ra" ) ) // "deg" or "rad"
|
||||
aUnits = EDA_UNITS::DEGREES;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+33
-148
@@ -18,25 +18,23 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <font/fontconfig.h>
|
||||
#include <pgm_base.h>
|
||||
#include <wx/log.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <string_utils.h>
|
||||
#include <macros.h>
|
||||
#include <font/fontconfig.h>
|
||||
|
||||
using namespace fontconfig;
|
||||
|
||||
static FONTCONFIG* g_config = nullptr;
|
||||
|
||||
/**
|
||||
* A simple wrapper to avoid exporing fontconfig in the header
|
||||
*/
|
||||
struct fontconfig::FONTCONFIG_PAT
|
||||
|
||||
inline static FcChar8* wxStringToFcChar8( const wxString& str )
|
||||
{
|
||||
FcPattern* pat;
|
||||
};
|
||||
wxScopedCharBuffer const fcBuffer = str.ToUTF8();
|
||||
return (FcChar8*) fcBuffer.data();
|
||||
}
|
||||
|
||||
|
||||
wxString FONTCONFIG::Version()
|
||||
@@ -63,112 +61,19 @@ FONTCONFIG* Fontconfig()
|
||||
}
|
||||
|
||||
|
||||
bool FONTCONFIG::isLanguageMatch( const wxString& aSearchLang, const wxString& aSupportedLang )
|
||||
{
|
||||
if( aSearchLang.Lower() == aSupportedLang.Lower() )
|
||||
return true;
|
||||
|
||||
if( aSupportedLang.empty() )
|
||||
return false;
|
||||
|
||||
if( aSearchLang.empty() )
|
||||
return false;
|
||||
|
||||
wxArrayString supportedLangBits;
|
||||
wxStringSplit( aSupportedLang.Lower(), supportedLangBits, wxS( '-' ) );
|
||||
|
||||
wxArrayString searhcLangBits;
|
||||
wxStringSplit( aSearchLang.Lower(), searhcLangBits, wxS( '-' ) );
|
||||
|
||||
// if either side of the comparison have only one section, then its a broad match but fine
|
||||
// i.e. the haystack is declaring broad support or the search language is broad
|
||||
if( searhcLangBits.size() == 1 || supportedLangBits.size() == 1 )
|
||||
{
|
||||
return searhcLangBits[0] == supportedLangBits[0];
|
||||
}
|
||||
|
||||
// the full two part comparison should have passed the initial shortcut
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::string FONTCONFIG::getFcString( FONTCONFIG_PAT& aPat, const char* aObj, int aIdx )
|
||||
{
|
||||
FcChar8* str;
|
||||
std::string res;
|
||||
|
||||
if( FcPatternGetString( aPat.pat, aObj, aIdx, &str ) == FcResultMatch )
|
||||
res = std::string( reinterpret_cast<char*>( str ) );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void FONTCONFIG::getAllFamilyStrings( FONTCONFIG_PAT& aPat,
|
||||
std::unordered_map<std::string, std::string>& aFamStringMap )
|
||||
{
|
||||
std::string famLang;
|
||||
std::string fam;
|
||||
|
||||
int langIdx = 0;
|
||||
do
|
||||
{
|
||||
famLang = getFcString( aPat, FC_FAMILYLANG, langIdx );
|
||||
|
||||
if( famLang.empty() && langIdx != 0 )
|
||||
break;
|
||||
else
|
||||
{
|
||||
fam = getFcString( aPat, FC_FAMILY, langIdx );
|
||||
aFamStringMap.insert_or_assign( famLang, fam );
|
||||
}
|
||||
} while( langIdx++ < std::numeric_limits<
|
||||
int8_t>::max() ); //arbitrary to avoid getting stuck for any reason
|
||||
}
|
||||
|
||||
|
||||
std::string FONTCONFIG::getFamilyStringByLang( FONTCONFIG_PAT& aPat, const wxString& aDesiredLang )
|
||||
{
|
||||
std::unordered_map<std::string, std::string> famStrings;
|
||||
getAllFamilyStrings( aPat, famStrings );
|
||||
|
||||
if( famStrings.empty() )
|
||||
return "";
|
||||
|
||||
for( auto const& [key, val] : famStrings )
|
||||
{
|
||||
if( isLanguageMatch( aDesiredLang, FROM_UTF8( key.c_str() ) ) )
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
// fall back to the first and maybe only available name
|
||||
// most fonts by review don't even bother declaring more than one font family name
|
||||
// and they don't even bother declare the language tag either, they just leave it blank
|
||||
return famStrings.begin()->second;
|
||||
}
|
||||
|
||||
|
||||
FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString &aFontFile,
|
||||
int& aFaceIndex, bool aBold, bool aItalic )
|
||||
bool aBold, bool aItalic )
|
||||
{
|
||||
FF_RESULT retval = FF_RESULT::FF_ERROR;
|
||||
wxString qualifiedFontName = aFontName;
|
||||
|
||||
wxScopedCharBuffer const fcBuffer = qualifiedFontName.ToUTF8();
|
||||
|
||||
FcPattern* pat = FcPatternCreate();
|
||||
|
||||
if( aBold )
|
||||
FcPatternAddString( pat, FC_STYLE, (const FcChar8*) "Bold" );
|
||||
qualifiedFontName << wxS( ":Bold" );
|
||||
|
||||
if( aItalic )
|
||||
FcPatternAddString( pat, FC_STYLE, (const FcChar8*) "Italic" );
|
||||
|
||||
FcPatternAddString( pat, FC_FAMILY, (FcChar8*) fcBuffer.data() );
|
||||
qualifiedFontName << wxS( ":Italic" );
|
||||
|
||||
FcPattern* pat = FcNameParse( wxStringToFcChar8( qualifiedFontName ) );
|
||||
FcConfigSubstitute( nullptr, pat, FcMatchPattern );
|
||||
FcDefaultSubstitute( pat );
|
||||
|
||||
@@ -184,23 +89,14 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch )
|
||||
{
|
||||
aFontFile = wxString::FromUTF8( (char*) file );
|
||||
aFaceIndex = 0;
|
||||
|
||||
wxString styleStr;
|
||||
FcChar8* family = nullptr;
|
||||
FcChar8* style = nullptr;
|
||||
|
||||
retval = FF_RESULT::FF_SUBSTITUTE;
|
||||
|
||||
std::unordered_map<std::string, std::string> famStrings;
|
||||
FONTCONFIG_PAT patHolder{ font };
|
||||
|
||||
getAllFamilyStrings( patHolder, famStrings );
|
||||
|
||||
if( FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch )
|
||||
{
|
||||
FcPatternGetInteger( font, FC_INDEX, 0, &aFaceIndex );
|
||||
|
||||
fontName = wxString::FromUTF8( (char*) family );
|
||||
|
||||
if( FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch )
|
||||
@@ -233,26 +129,18 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
has_ital = true;
|
||||
}
|
||||
|
||||
for( auto const& [key, val] : famStrings )
|
||||
if( fontName.Lower().StartsWith( aFontName.Lower() ) )
|
||||
{
|
||||
wxString searchFont;
|
||||
searchFont = wxString::FromUTF8( (char*) val.data() );
|
||||
|
||||
if( searchFont.Lower().StartsWith( aFontName.Lower() ) )
|
||||
{
|
||||
if( ( aBold && !has_bold ) && ( aItalic && !has_ital ) )
|
||||
retval = FF_RESULT::FF_MISSING_BOLD_ITAL;
|
||||
else if( aBold && !has_bold )
|
||||
retval = FF_RESULT::FF_MISSING_BOLD;
|
||||
else if( aItalic && !has_ital )
|
||||
retval = FF_RESULT::FF_MISSING_ITAL;
|
||||
else if( ( aBold != has_bold ) || ( aItalic != has_ital ) )
|
||||
retval = FF_RESULT::FF_SUBSTITUTE;
|
||||
else
|
||||
retval = FF_RESULT::FF_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
if( ( aBold && !has_bold ) && ( aItalic && !has_ital ) )
|
||||
retval = FF_RESULT::FF_MISSING_BOLD_ITAL;
|
||||
else if( aBold && !has_bold )
|
||||
retval = FF_RESULT::FF_MISSING_BOLD;
|
||||
else if( aItalic && !has_ital )
|
||||
retval = FF_RESULT::FF_MISSING_ITAL;
|
||||
else if( ( aBold != has_bold ) || ( aItalic != has_ital ) )
|
||||
retval = FF_RESULT::FF_SUBSTITUTE;
|
||||
else
|
||||
retval = FF_RESULT::FF_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,14 +158,13 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
}
|
||||
|
||||
|
||||
void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts, const std::string& aDesiredLang )
|
||||
void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts )
|
||||
{
|
||||
// be sure to cache bust if the language changed
|
||||
if( m_fontInfoCache.empty() || m_fontCacheLastLang != aDesiredLang )
|
||||
if( m_fonts.empty() )
|
||||
{
|
||||
FcPattern* pat = FcPatternCreate();
|
||||
FcObjectSet* os = FcObjectSetBuild( FC_FAMILY, FC_FAMILYLANG, FC_STYLE, FC_LANG, FC_FILE,
|
||||
FC_OUTLINE, nullptr );
|
||||
FcObjectSet* os = FcObjectSetBuild( FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, FC_OUTLINE,
|
||||
nullptr );
|
||||
FcFontSet* fs = FcFontList( nullptr, pat, os );
|
||||
|
||||
for( int i = 0; fs && i < fs->nfont; ++i )
|
||||
@@ -285,10 +172,12 @@ void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts, const std::string&
|
||||
FcPattern* font = fs->fonts[i];
|
||||
FcChar8* file;
|
||||
FcChar8* style;
|
||||
FcChar8* family;
|
||||
FcLangSet* langSet;
|
||||
FcBool outline;
|
||||
|
||||
if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch
|
||||
&& FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch
|
||||
&& FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch
|
||||
&& FcPatternGetLangSet( font, FC_LANG, 0, &langSet ) == FcResultMatch
|
||||
&& FcPatternGetBool( font, FC_OUTLINE, 0, &outline ) == FcResultMatch )
|
||||
@@ -296,9 +185,7 @@ void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts, const std::string&
|
||||
if( !outline )
|
||||
continue;
|
||||
|
||||
FONTCONFIG_PAT patHolder{ font };
|
||||
std::string theFamily =
|
||||
getFamilyStringByLang( patHolder, FROM_UTF8( aDesiredLang.c_str() ) );
|
||||
std::string theFamily( reinterpret_cast<char *>( family ) );
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// On Mac (at least) some of the font names are in their own language. If
|
||||
@@ -351,10 +238,10 @@ void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts, const std::string&
|
||||
if( theFamily.length() > 0 && theFamily.front() == '.' )
|
||||
continue;
|
||||
|
||||
std::map<std::string, FONTINFO>::iterator it = m_fontInfoCache.find( theFamily );
|
||||
std::map<std::string, FONTINFO>::iterator it = m_fonts.find( theFamily );
|
||||
|
||||
if( it == m_fontInfoCache.end() )
|
||||
m_fontInfoCache.emplace( theFamily, fontInfo );
|
||||
if( it == m_fonts.end() )
|
||||
m_fonts.emplace( theFamily, fontInfo );
|
||||
else
|
||||
it->second.Children().push_back( fontInfo );
|
||||
}
|
||||
@@ -362,10 +249,8 @@ void FONTCONFIG::ListFonts( std::vector<std::string>& aFonts, const std::string&
|
||||
|
||||
if( fs )
|
||||
FcFontSetDestroy( fs );
|
||||
|
||||
m_fontCacheLastLang = aDesiredLang;
|
||||
}
|
||||
|
||||
for( const std::pair<const std::string, FONTINFO>& entry : m_fontInfoCache )
|
||||
for( const std::pair<const std::string, FONTINFO>& entry : m_fonts )
|
||||
aFonts.push_back( entry.second.Family() );
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ using namespace KIFONT;
|
||||
|
||||
|
||||
FT_Library OUTLINE_FONT::m_freeType = nullptr;
|
||||
std::mutex OUTLINE_FONT::m_freeTypeMutex;
|
||||
|
||||
OUTLINE_FONT::OUTLINE_FONT() :
|
||||
m_face(NULL),
|
||||
@@ -52,8 +51,6 @@ OUTLINE_FONT::OUTLINE_FONT() :
|
||||
m_fakeBold( false ),
|
||||
m_fakeItal( false )
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
if( !m_freeType )
|
||||
FT_Init_FreeType( &m_freeType );
|
||||
}
|
||||
@@ -61,8 +58,6 @@ OUTLINE_FONT::OUTLINE_FONT() :
|
||||
|
||||
wxString OUTLINE_FONT::FreeTypeVersion()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
if( !m_freeType )
|
||||
FT_Init_FreeType( &m_freeType );
|
||||
|
||||
@@ -95,16 +90,12 @@ wxString OUTLINE_FONT::FontLibraryVersion()
|
||||
|
||||
OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, bool aItalic )
|
||||
{
|
||||
std::unique_ptr<OUTLINE_FONT> font = std::make_unique<OUTLINE_FONT>();
|
||||
OUTLINE_FONT* font = new OUTLINE_FONT();
|
||||
|
||||
wxString fontFile;
|
||||
int faceIndex;
|
||||
using fc = fontconfig::FONTCONFIG;
|
||||
|
||||
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, faceIndex, aBold, aItalic );
|
||||
|
||||
if( retval == fc::FF_RESULT::FF_ERROR )
|
||||
return nullptr;
|
||||
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, aBold, aItalic );
|
||||
|
||||
if( retval == fc::FF_RESULT::FF_MISSING_BOLD || retval == fc::FF_RESULT::FF_MISSING_BOLD_ITAL )
|
||||
font->SetFakeBold();
|
||||
@@ -112,23 +103,21 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
|
||||
if( retval == fc::FF_RESULT::FF_MISSING_ITAL || retval == fc::FF_RESULT::FF_MISSING_BOLD_ITAL )
|
||||
font->SetFakeItal();
|
||||
|
||||
if( font->loadFace( fontFile, faceIndex ) != 0 )
|
||||
return nullptr;
|
||||
if( retval != fc::FF_RESULT::FF_ERROR )
|
||||
(void) font->loadFace( fontFile );
|
||||
|
||||
font->m_fontName = aFontName; // Keep asked-for name, even if we substituted.
|
||||
font->m_fontFileName = fontFile;
|
||||
|
||||
return font.release();
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName, int aFaceIndex )
|
||||
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName )
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
// TODO: check that going from wxString to char* with UTF-8
|
||||
// conversion for filename makes sense on any/all platforms
|
||||
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), aFaceIndex, &m_face );
|
||||
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), 0, &m_face );
|
||||
|
||||
if( !e )
|
||||
{
|
||||
@@ -334,18 +323,6 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
return getTextAsGlyphsUnlocked( aBBox, aGlyphs, aText, aSize, aPosition, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
VECTOR2D glyphSize = aSize;
|
||||
FT_Face face = m_face;
|
||||
@@ -389,7 +366,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
{
|
||||
FT_Matrix matrix;
|
||||
// Create a 12 degree slant
|
||||
const float angle = (float)( -M_PI * 12.0f ) / 180.0f;
|
||||
const float angle = ( -M_PI * 12 ) / 180.0f;
|
||||
matrix.xx = (FT_Fixed) ( cos( angle ) * 0x10000L );
|
||||
matrix.xy = (FT_Fixed) ( -sin( angle ) * 0x10000L );
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
@@ -489,7 +466,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
{
|
||||
std::vector<std::unique_ptr<GLYPH>> underscoreGlyphs;
|
||||
|
||||
getTextAsGlyphsUnlocked( nullptr, &underscoreGlyphs, wxT( "_" ), aSize, { 0, 0 }, ANGLE_0, false,
|
||||
getTextAsGlyphs( nullptr, &underscoreGlyphs, wxT( "_" ), aSize, { 0, 0 }, ANGLE_0, false,
|
||||
{ 0, 0 }, aTextStyle & ~TEXT_STYLE::OVERBAR );
|
||||
|
||||
OUTLINE_GLYPH* underscoreGlyph = static_cast<OUTLINE_GLYPH*>( underscoreGlyphs[0].get() );
|
||||
@@ -575,9 +552,6 @@ void OUTLINE_FONT::RenderToOpenGLCanvas( KIGFX::OPENGL_GAL& aGal, const wxString
|
||||
unsigned int glyphCount;
|
||||
hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( buf, &glyphCount );
|
||||
hb_glyph_position_t* glyphPos = hb_buffer_get_glyph_positions( buf, &glyphCount );
|
||||
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
|
||||
hb_ft_font_set_funcs( referencedFont );
|
||||
|
||||
+10
-20
@@ -52,8 +52,7 @@ static constexpr double UNDERLINE_POSITION_FACTOR = -0.16;
|
||||
///< Scale factor for a glyph
|
||||
static constexpr double STROKE_FONT_SCALE = 1.0 / 21.0;
|
||||
|
||||
///< Offset (in stroke font units) to move the origin to the baseline.
|
||||
static constexpr int FONT_OFFSET = -8;
|
||||
static constexpr int FONT_OFFSET = -10;
|
||||
|
||||
|
||||
bool g_defaultFontInitialized = false;
|
||||
@@ -226,8 +225,11 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
constexpr int TAB_WIDTH = 4;
|
||||
constexpr double SPACE_WIDTH = 0.6;
|
||||
constexpr double INTER_CHAR = 0.2;
|
||||
constexpr double TAB_WIDTH = 4 * 0.82; // Not quite as wide as 5.1/6.0 tab formatting, but
|
||||
// a better match for Scintilla, and closer to the
|
||||
// nominal SPACE_WIDTH + INTER_CHAR
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.7;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.5;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.3;
|
||||
@@ -235,8 +237,6 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
VECTOR2I cursor( aPosition );
|
||||
VECTOR2D glyphSize( aSize );
|
||||
double tilt = ( aTextStyle & TEXT_STYLE::ITALIC ) ? ITALIC_TILT : 0.0;
|
||||
double space_width = m_glyphBoundingBoxes->front().GetWidth(); // First char is space
|
||||
int char_count = 0;
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::SUBSCRIPT || aTextStyle & TEXT_STYLE::SUPERSCRIPT )
|
||||
{
|
||||
@@ -250,26 +250,18 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
|
||||
for( wxUniChar c : aText )
|
||||
{
|
||||
// Handle tabs as locked to the next 4th column (in base-widths).
|
||||
// Handle tabs as locked to the nearest 4th column (in space-widths).
|
||||
if( c == '\t' )
|
||||
{
|
||||
char_count = ( char_count / TAB_WIDTH + 1 ) * TAB_WIDTH - 1;
|
||||
int tabWidth = KiROUND( glyphSize.x * TAB_WIDTH );
|
||||
int currentIntrusion = ( cursor.x - aOrigin.x ) % tabWidth;
|
||||
|
||||
int new_cursor = aPosition.x + aSize.x * char_count
|
||||
+ aSize.x * space_width;
|
||||
|
||||
while( new_cursor <= cursor.x )
|
||||
{
|
||||
char_count += TAB_WIDTH;
|
||||
new_cursor += aSize.x * TAB_WIDTH;
|
||||
}
|
||||
|
||||
cursor.x = new_cursor;
|
||||
cursor.x += tabWidth - currentIntrusion;
|
||||
}
|
||||
else if( c == ' ' )
|
||||
{
|
||||
// 'space' character - draw nothing, advance cursor position
|
||||
cursor.x += KiROUND( glyphSize.x * space_width );
|
||||
cursor.x += KiROUND( glyphSize.x * SPACE_WIDTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -300,8 +292,6 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
|
||||
cursor.x += KiROUND( glyphExtents.x );
|
||||
}
|
||||
|
||||
++char_count;
|
||||
}
|
||||
|
||||
VECTOR2D barOffset( 0.0, 0.0 );
|
||||
|
||||
@@ -596,7 +596,6 @@ bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable )
|
||||
}
|
||||
}
|
||||
|
||||
aTable.Clear();
|
||||
aTable.Load( fn.GetFullPath() );
|
||||
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
|
||||
+13
-47
@@ -57,6 +57,11 @@ static std::optional<double> getKiCadConfiguredScale( const COMMON_SETTINGS& aCo
|
||||
scale = canvas_scale;
|
||||
}
|
||||
|
||||
if( scale )
|
||||
{
|
||||
wxLogTrace( traceHiDpi, wxS( "Scale factor (configured): %f" ), *scale );
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
@@ -78,6 +83,11 @@ static std::optional<double> getEnvironmentScale()
|
||||
scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) );
|
||||
}
|
||||
|
||||
if( scale )
|
||||
{
|
||||
wxLogTrace( traceHiDpi, wxS( "Scale factor (environment): %f" ), *scale );
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
@@ -91,18 +101,15 @@ DPI_SCALING::DPI_SCALING( COMMON_SETTINGS* aConfig, const wxWindow* aWindow )
|
||||
double DPI_SCALING::GetScaleFactor() const
|
||||
{
|
||||
std::optional<double> val;
|
||||
wxString src;
|
||||
|
||||
if( m_config )
|
||||
{
|
||||
val = getKiCadConfiguredScale( *m_config );
|
||||
src = wxS( "config" );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
val = getEnvironmentScale();
|
||||
src = wxS( "env" );
|
||||
}
|
||||
|
||||
if( !val && m_window )
|
||||
@@ -110,58 +117,17 @@ double DPI_SCALING::GetScaleFactor() const
|
||||
// Use the native WX reporting.
|
||||
// On Linux, this will not work until WX 3.2 and GTK >= 3.10
|
||||
// Otherwise it returns 1.0
|
||||
val = KIPLATFORM::UI::GetPixelScaleFactor( m_window );
|
||||
src = wxS( "platform" );
|
||||
val = KIPLATFORM::UI::GetSystemScaleFactor( m_window );
|
||||
wxLogTrace( traceHiDpi, wxS( "Scale factor (WX): %f" ), *val );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
// Nothing else we can do, give it a default value
|
||||
val = GetDefaultScaleFactor();
|
||||
src = wxS( "default" );
|
||||
wxLogTrace( traceHiDpi, wxS( "Scale factor (default): %f" ), *val );
|
||||
}
|
||||
|
||||
wxLogTrace( traceHiDpi, wxS( "Scale factor (%s): %f" ), src, *val );
|
||||
|
||||
return *val;
|
||||
}
|
||||
|
||||
|
||||
double DPI_SCALING::GetContentScaleFactor() const
|
||||
{
|
||||
std::optional<double> val;
|
||||
wxString src;
|
||||
|
||||
if( m_config )
|
||||
{
|
||||
val = getKiCadConfiguredScale( *m_config );
|
||||
src = wxS( "config" );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
val = getEnvironmentScale();
|
||||
src = wxS( "env" );
|
||||
}
|
||||
|
||||
if( !val && m_window )
|
||||
{
|
||||
// Use the native WX reporting.
|
||||
// On Linux, this will not work until WX 3.2 and GTK >= 3.10
|
||||
// Otherwise it returns 1.0
|
||||
val = KIPLATFORM::UI::GetContentScaleFactor( m_window );
|
||||
src = wxS( "platform" );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
// Nothing else we can do, give it a default value
|
||||
val = GetDefaultScaleFactor();
|
||||
src = wxS( "default" );
|
||||
}
|
||||
|
||||
wxLogTrace( traceHiDpi, wxS( "Content scale factor (%s): %f" ), src, *val );
|
||||
|
||||
return *val;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,14 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
bmp.w = imgData.GetSize().x;
|
||||
bmp.h = imgData.GetSize().y;
|
||||
|
||||
// The bitmap size needs to be a multiple of 4.
|
||||
// This is easiest to achieve by ensuring that each row
|
||||
// has a multiple of 4 pixels
|
||||
int extra_w = bmp.w % 4;
|
||||
|
||||
if( extra_w )
|
||||
extra_w = 4 - extra_w;
|
||||
|
||||
GLuint textureID;
|
||||
|
||||
if( m_freedTextureIds.empty() )
|
||||
@@ -181,14 +189,15 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
m_freedTextureIds.pop_front();
|
||||
}
|
||||
|
||||
bmp.size = bmp.w * bmp.h * 4;
|
||||
// make_unique initializes this to 0, so extra pixels are transparent
|
||||
bmp.size = ( bmp.w + extra_w ) * bmp.h * 4;
|
||||
auto buf = std::make_unique<uint8_t[]>( bmp.size );
|
||||
|
||||
for( int y = 0; y < bmp.h; y++ )
|
||||
{
|
||||
for( int x = 0; x < bmp.w; x++ )
|
||||
{
|
||||
uint8_t* p = buf.get() + ( bmp.w * y + x ) * 4;
|
||||
uint8_t* p = buf.get() + ( ( bmp.w + extra_w ) * y + x ) * 4;
|
||||
|
||||
p[0] = imgData.GetRed( x, y );
|
||||
p[1] = imgData.GetGreen( x, y );
|
||||
@@ -205,7 +214,7 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, textureID );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w + extra_w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
buf.get() );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||
|
||||
@@ -91,11 +91,6 @@ void GRSetColorPen( wxDC* DC, const COLOR4D& Color, int width, wxPenStyle style
|
||||
if( s_ForceBlackPen )
|
||||
color = COLOR4D::BLACK;
|
||||
|
||||
// wxWidgets will enforce a minimum pen width when printing, so we have to make the pen
|
||||
// transparent when we don't want the object stroked.
|
||||
if( width == 0 )
|
||||
color = COLOR4D::UNSPECIFIED;
|
||||
|
||||
const wxPen& curr_pen = DC->GetPen();
|
||||
|
||||
if( !curr_pen.IsOk() || curr_pen.GetColour() != color.ToColour()
|
||||
|
||||
@@ -424,7 +424,6 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
m_addHandler( dummy );
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2021 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
|
||||
@@ -100,13 +100,12 @@ static int xferinfo( void* aProgress, curl_off_t aDLtotal, curl_off_t aDLnow, cu
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x072000 // 7.32.0
|
||||
|
||||
static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double aULtotal, double aULnow )
|
||||
{
|
||||
return xferinfo( aProgress, static_cast<curl_off_t>( aDLtotal ), static_cast<curl_off_t>( aDLnow ),
|
||||
static_cast<curl_off_t>( aULtotal ), static_cast<curl_off_t>( aULnow ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
@@ -127,11 +126,7 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, static_cast<void*>( &m_buffer ) );
|
||||
|
||||
// Only allow HTTP and HTTPS protocols
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500 // version 7.85.0
|
||||
curl_easy_setopt(m_CURL, CURLOPT_PROTOCOLS_STR, "http,https");
|
||||
#else
|
||||
curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// We need this to use the Windows Certificate store
|
||||
@@ -269,7 +264,7 @@ bool KICAD_CURL_EASY::SetTransferCallback( const TRANSFER_CALLBACK& aCallback, s
|
||||
{
|
||||
progress = std::make_unique<CURL_PROGRESS>( this, aCallback,
|
||||
static_cast<curl_off_t>( aInterval ) );
|
||||
#if LIBCURL_VERSION_NUM >= 0x072000 // 7.32.0
|
||||
#ifdef CURLOPT_XFERINFOFUNCTION
|
||||
setOption( CURLOPT_XFERINFOFUNCTION, xferinfo );
|
||||
setOption( CURLOPT_XFERINFODATA, progress.get() );
|
||||
#else
|
||||
@@ -291,7 +286,7 @@ bool KICAD_CURL_EASY::SetOutputStream( const std::ostream* aOutput )
|
||||
|
||||
int KICAD_CURL_EASY::GetTransferTotal( uint64_t& aDownloadedBytes ) const
|
||||
{
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700 // 7.55.0
|
||||
#ifdef CURLINFO_SIZE_DOWNLOAD_T
|
||||
curl_off_t dl;
|
||||
int result = curl_easy_getinfo( m_CURL, CURLINFO_SIZE_DOWNLOAD_T, &dl );
|
||||
aDownloadedBytes = static_cast<uint64_t>( dl );
|
||||
|
||||
+4
-6
@@ -431,17 +431,15 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( ioe.What() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ), ioe.What() );
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
catch( const std::exception& e)
|
||||
{
|
||||
wxLogError( e.what() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ), e.what() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
DisplayErrorMessage( nullptr, _( "Error loading editor." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,8 +193,6 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
|
||||
{
|
||||
cur->ensureIndex();
|
||||
|
||||
std::shared_lock<std::shared_mutex> lock( cur->m_nickIndexMutex );
|
||||
|
||||
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
|
||||
{
|
||||
if( entry.first == aNickName )
|
||||
@@ -305,7 +303,7 @@ bool LIB_TABLE::InsertRow( LIB_TABLE_ROW* aRow, bool doReplace )
|
||||
{
|
||||
ensureIndex();
|
||||
|
||||
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
|
||||
std::lock_guard<std::mutex> lock( m_nickIndexMutex );
|
||||
|
||||
INDEX_CITER it = m_nickIndex.find( aRow->GetNickName() );
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-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
|
||||
@@ -24,16 +24,12 @@ LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) : GRID_TRICKS( aG
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
|
||||
{
|
||||
bool showActivate = false;
|
||||
bool showDeactivate = false;
|
||||
LIB_TABLE_GRID* tbl = static_cast<LIB_TABLE_GRID*>( m_grid->GetTable() );
|
||||
|
||||
// Ensure selection parameters are up to date
|
||||
getSelectedArea();
|
||||
|
||||
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
|
||||
{
|
||||
if( tbl->GetValueAsBool( row, 0 ) )
|
||||
@@ -53,14 +49,10 @@ void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED, _( "Activate selected" ) );
|
||||
if( showDeactivate )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_DEACTIVATE_SELECTED, _( "Deactivate selected" ) );
|
||||
|
||||
if( showActivate || showDeactivate )
|
||||
menu.AppendSeparator();
|
||||
|
||||
menu.AppendSeparator();
|
||||
GRID_TRICKS::showPopupMenu( menu );
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
{
|
||||
int menu_id = event.GetId();
|
||||
@@ -69,13 +61,10 @@ void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
{
|
||||
LIB_TABLE_GRID* tbl = (LIB_TABLE_GRID*) m_grid->GetTable();
|
||||
|
||||
bool selected_state = menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED;
|
||||
|
||||
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
|
||||
tbl->SetValueAsBool( row, 0, selected_state );
|
||||
|
||||
// Ensure the new state (on/off) of the widgets is immediately shown:
|
||||
m_grid->Refresh();
|
||||
{
|
||||
tbl->SetValueAsBool( row, 0, menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -269,7 +269,7 @@ void LIB_TREE_MODEL_ADAPTER::recreateColumns()
|
||||
for( const wxString& colName : m_shownColumns )
|
||||
{
|
||||
if( !m_colNameMap.count( colName ) )
|
||||
doAddColumn( colName, colName == wxT( "Description" ) );
|
||||
doAddColumn( colName, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This file is part of libeval, a simple math expression evaluator
|
||||
*
|
||||
* Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-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
|
||||
@@ -356,11 +356,10 @@ void COMPILER::newString( const wxString& aString )
|
||||
m_parseFinished = false;
|
||||
}
|
||||
|
||||
|
||||
T_TOKEN COMPILER::getToken()
|
||||
{
|
||||
T_TOKEN rv;
|
||||
rv.value = defaultTokenValue;
|
||||
rv.value.str = nullptr;
|
||||
|
||||
bool done = false;
|
||||
|
||||
|
||||
+1
-39
@@ -110,7 +110,7 @@ LANGUAGE_DESCR LanguagesList[] =
|
||||
{ wxLANGUAGE_SWEDISH, ID_LANGUAGE_SWEDISH, wxT( "Svenska" ), true },
|
||||
// { wxLANGUAGE_VIETNAMESE, ID_LANGUAGE_VIETNAMESE, wxT( "Tiếng Việt" ), true },
|
||||
// { wxLANGUAGE_TURKISH, ID_LANGUAGE_TURKISH, wxT( "Türkçe" ), true },
|
||||
{ wxLANGUAGE_UKRAINIAN, ID_LANGUAGE_UKRANIAN, wxT( "Українська" ), true },
|
||||
{ wxLANGUAGE_UKRAINIAN, ID_LANGUAGE_UKRANIAN, wxT( "Українець" ), true },
|
||||
{ wxLANGUAGE_CHINESE_SIMPLIFIED, ID_LANGUAGE_CHINESE_SIMPLIFIED,
|
||||
wxT( "简体中文" ), true },
|
||||
{ wxLANGUAGE_CHINESE_TRADITIONAL, ID_LANGUAGE_CHINESE_TRADITIONAL,
|
||||
@@ -775,26 +775,6 @@ void PGM_BASE::SetLanguageIdentifier( int menu_id )
|
||||
}
|
||||
|
||||
|
||||
wxString PGM_BASE::GetLanguageTag()
|
||||
{
|
||||
const wxLanguageInfo* langInfo = wxLocale::GetLanguageInfo( m_language_id );
|
||||
|
||||
if( !langInfo )
|
||||
return "";
|
||||
else
|
||||
{
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
wxString str = langInfo->GetCanonicalWithRegion();
|
||||
#else
|
||||
wxString str = langInfo->CanonicalName;
|
||||
#endif
|
||||
str.Replace( "_", "-" );
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PGM_BASE::SetLanguagePath()
|
||||
{
|
||||
wxLocale::AddCatalogLookupPathPrefix( PATHS::GetLocaleDataPath() );
|
||||
@@ -857,21 +837,3 @@ ENV_VAR_MAP& PGM_BASE::GetLocalEnvVariables() const
|
||||
{
|
||||
return GetCommonSettings()->m_Env.vars;
|
||||
}
|
||||
|
||||
|
||||
bool PGM_BASE::IsGUI()
|
||||
{
|
||||
if( !wxTheApp )
|
||||
return false;
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
return wxTheApp->IsGUI();
|
||||
#else
|
||||
// wxWidgets older than version 3.1.6 do not have a way to know if the app
|
||||
// has a GUI or is a console application.
|
||||
// So the trick is to set the App class name when starting kicad-cli, and when
|
||||
// the app class name is the kicad-cli class name the app is a console app
|
||||
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
|
||||
return run_gui;
|
||||
#endif
|
||||
}
|
||||
+129
-170
@@ -861,186 +861,145 @@ void DXF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
}
|
||||
else
|
||||
{
|
||||
TEXT_ATTRIBUTES attrs;
|
||||
attrs.m_Halign = aH_justify;
|
||||
attrs.m_Valign =aV_justify;
|
||||
attrs.m_StrokeWidth = aWidth;
|
||||
attrs.m_Angle = aOrient;
|
||||
attrs.m_Italic = aItalic;
|
||||
attrs.m_Bold = aBold;
|
||||
attrs.m_Mirrored = aSize.x < 0;
|
||||
attrs.m_Multiline = false;
|
||||
plotOneLineOfText( aPos, aColor, aText, attrs );
|
||||
}
|
||||
}
|
||||
/* Emit text as a text entity. This loses formatting and shape but it's
|
||||
more useful as a CAD object */
|
||||
VECTOR2D origin_dev = userToDeviceCoordinates( aPos );
|
||||
SetColor( aColor );
|
||||
wxString cname = getDXFColorName( m_currentColor );
|
||||
VECTOR2D size_dev = userToDeviceSize( aSize );
|
||||
int h_code = 0, v_code = 0;
|
||||
|
||||
|
||||
void DXF_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
TEXT_ATTRIBUTES attrs = aAttributes;
|
||||
// Fix me: see how to use DXF text mode for multiline texts
|
||||
if( attrs.m_Multiline && !aText.Contains( wxT( "\n" ) ) )
|
||||
attrs.m_Multiline = false; // the text has only one line.
|
||||
|
||||
bool processSuperSub = aText.Contains( wxT( "^{" ) ) || aText.Contains( wxT( "_{" ) );
|
||||
|
||||
if( m_textAsLines || containsNonAsciiChars( aText ) || attrs.m_Multiline || processSuperSub )
|
||||
{
|
||||
// output text as graphics.
|
||||
// Perhaps multiline texts could be handled as DXF text entity
|
||||
// but I do not want spend time about that (JPC)
|
||||
PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData );
|
||||
}
|
||||
else
|
||||
plotOneLineOfText( aPos, aColor, aText, attrs );
|
||||
}
|
||||
|
||||
void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes )
|
||||
{
|
||||
/* Emit text as a text entity. This loses formatting and shape but it's
|
||||
more useful as a CAD object */
|
||||
VECTOR2D origin_dev = userToDeviceCoordinates( aPos );
|
||||
SetColor( aColor );
|
||||
wxString cname = getDXFColorName( m_currentColor );
|
||||
VECTOR2D size_dev = userToDeviceSize( aAttributes.m_Size );
|
||||
int h_code = 0, v_code = 0;
|
||||
|
||||
switch( aAttributes.m_Halign )
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: h_code = 0; break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: h_code = 1; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: h_code = 2; break;
|
||||
}
|
||||
|
||||
switch( aAttributes.m_Valign )
|
||||
{
|
||||
case GR_TEXT_V_ALIGN_TOP: v_code = 3; break;
|
||||
case GR_TEXT_V_ALIGN_CENTER: v_code = 2; break;
|
||||
case GR_TEXT_V_ALIGN_BOTTOM: v_code = 1; break;
|
||||
}
|
||||
|
||||
// Position, size, rotation and alignment
|
||||
// The two alignment point usages is somewhat idiot (see the DXF ref)
|
||||
// Anyway since we don't use the fit/aligned options, they're the same
|
||||
fprintf( m_outputFile,
|
||||
" 0\n"
|
||||
"TEXT\n"
|
||||
" 7\n"
|
||||
"%s\n" // Text style
|
||||
" 8\n"
|
||||
"%s\n" // Layer name
|
||||
" 10\n"
|
||||
"%g\n" // First point X
|
||||
" 11\n"
|
||||
"%g\n" // Second point X
|
||||
" 20\n"
|
||||
"%g\n" // First point Y
|
||||
" 21\n"
|
||||
"%g\n" // Second point Y
|
||||
" 40\n"
|
||||
"%g\n" // Text height
|
||||
" 41\n"
|
||||
"%g\n" // Width factor
|
||||
" 50\n"
|
||||
"%g\n" // Rotation
|
||||
" 51\n"
|
||||
"%g\n" // Oblique angle
|
||||
" 71\n"
|
||||
"%d\n" // Mirror flags
|
||||
" 72\n"
|
||||
"%d\n" // H alignment
|
||||
" 73\n"
|
||||
"%d\n", // V alignment
|
||||
aAttributes.m_Bold ?
|
||||
(aAttributes.m_Italic ? "KICADBI" : "KICADB")
|
||||
: (aAttributes.m_Italic ? "KICADI" : "KICAD"), TO_UTF8( cname ),
|
||||
origin_dev.x, origin_dev.x,
|
||||
origin_dev.y, origin_dev.y,
|
||||
size_dev.y, fabs( size_dev.x / size_dev.y ),
|
||||
aAttributes.m_Angle.AsDegrees(),
|
||||
aAttributes.m_Italic ? DXF_OBLIQUE_ANGLE : 0,
|
||||
aAttributes.m_Mirrored ? 2 : 0, // X mirror flag
|
||||
h_code, v_code );
|
||||
|
||||
/* There are two issue in emitting the text:
|
||||
- Our overline character (~) must be converted to the appropriate
|
||||
control sequence %%O or %%o
|
||||
- Text encoding in DXF is more or less unspecified since depends on
|
||||
the DXF declared version, the acad version reading it *and* some
|
||||
system variables to be put in the header handled only by newer acads
|
||||
Also before R15 unicode simply is not supported (you need to use
|
||||
bigfonts which are a massive PITA). Common denominator solution:
|
||||
use Latin1 (and however someone could choke on it, anyway). Sorry
|
||||
for the extended latin people. If somewant want to try fixing this
|
||||
recent version seems to use UTF-8 (and not UCS2 like the rest of
|
||||
Windows)
|
||||
|
||||
XXX Actually there is a *third* issue: older DXF formats are limited
|
||||
to 255 bytes records (it was later raised to 2048); since I'm lazy
|
||||
and text so long is not probable I just don't implement this rule.
|
||||
If someone is interested in fixing this, you have to emit the first
|
||||
partial lines with group code 3 (max 250 bytes each) and then finish
|
||||
with a group code 1 (less than 250 bytes). The DXF refs explains it
|
||||
in no more details...
|
||||
*/
|
||||
|
||||
int braceNesting = 0;
|
||||
int overbarDepth = -1;
|
||||
|
||||
fputs( " 1\n", m_outputFile );
|
||||
|
||||
for( unsigned int i = 0; i < aText.length(); i++ )
|
||||
{
|
||||
/* Here I do a bad thing: writing the output one byte at a time!
|
||||
but today I'm lazy and I have no idea on how to coerce a Unicode
|
||||
wxString to spit out latin1 encoded text ...
|
||||
|
||||
At least stdio is *supposed* to do output buffering, so there is
|
||||
hope is not too slow */
|
||||
wchar_t ch = aText[i];
|
||||
|
||||
if( ch > 255 )
|
||||
switch( aH_justify )
|
||||
{
|
||||
// I can't encode this...
|
||||
putc( '?', m_outputFile );
|
||||
case GR_TEXT_H_ALIGN_LEFT: h_code = 0; break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: h_code = 1; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: h_code = 2; break;
|
||||
}
|
||||
else
|
||||
|
||||
switch( aV_justify )
|
||||
{
|
||||
if( aText[i] == '~' && i+1 < aText.length() && aText[i+1] == '{' )
|
||||
{
|
||||
fputs( "%%o", m_outputFile );
|
||||
overbarDepth = braceNesting;
|
||||
case GR_TEXT_V_ALIGN_TOP: v_code = 3; break;
|
||||
case GR_TEXT_V_ALIGN_CENTER: v_code = 2; break;
|
||||
case GR_TEXT_V_ALIGN_BOTTOM: v_code = 1; break;
|
||||
}
|
||||
|
||||
// Skip the '{'
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if( aText[i] == '{' )
|
||||
{
|
||||
braceNesting++;
|
||||
}
|
||||
else if( aText[i] == '}' )
|
||||
{
|
||||
if( braceNesting > 0 )
|
||||
braceNesting--;
|
||||
// Position, size, rotation and alignment
|
||||
// The two alignment point usages is somewhat idiot (see the DXF ref)
|
||||
// Anyway since we don't use the fit/aligned options, they're the same
|
||||
fprintf( m_outputFile,
|
||||
" 0\n"
|
||||
"TEXT\n"
|
||||
" 7\n"
|
||||
"%s\n" // Text style
|
||||
" 8\n"
|
||||
"%s\n" // Layer name
|
||||
" 10\n"
|
||||
"%g\n" // First point X
|
||||
" 11\n"
|
||||
"%g\n" // Second point X
|
||||
" 20\n"
|
||||
"%g\n" // First point Y
|
||||
" 21\n"
|
||||
"%g\n" // Second point Y
|
||||
" 40\n"
|
||||
"%g\n" // Text height
|
||||
" 41\n"
|
||||
"%g\n" // Width factor
|
||||
" 50\n"
|
||||
"%g\n" // Rotation
|
||||
" 51\n"
|
||||
"%g\n" // Oblique angle
|
||||
" 71\n"
|
||||
"%d\n" // Mirror flags
|
||||
" 72\n"
|
||||
"%d\n" // H alignment
|
||||
" 73\n"
|
||||
"%d\n", // V alignment
|
||||
aBold ? (aItalic ? "KICADBI" : "KICADB") : (aItalic ? "KICADI" : "KICAD"),
|
||||
TO_UTF8( cname ),
|
||||
origin_dev.x, origin_dev.x,
|
||||
origin_dev.y, origin_dev.y,
|
||||
size_dev.y, fabs( size_dev.x / size_dev.y ),
|
||||
aOrient.AsDegrees(),
|
||||
aItalic ? DXF_OBLIQUE_ANGLE : 0,
|
||||
size_dev.x < 0 ? 2 : 0, // X mirror flag
|
||||
h_code, v_code );
|
||||
|
||||
if( braceNesting == overbarDepth )
|
||||
/* There are two issue in emitting the text:
|
||||
- Our overline character (~) must be converted to the appropriate
|
||||
control sequence %%O or %%o
|
||||
- Text encoding in DXF is more or less unspecified since depends on
|
||||
the DXF declared version, the acad version reading it *and* some
|
||||
system variables to be put in the header handled only by newer acads
|
||||
Also before R15 unicode simply is not supported (you need to use
|
||||
bigfonts which are a massive PITA). Common denominator solution:
|
||||
use Latin1 (and however someone could choke on it, anyway). Sorry
|
||||
for the extended latin people. If somewant want to try fixing this
|
||||
recent version seems to use UTF-8 (and not UCS2 like the rest of
|
||||
Windows)
|
||||
|
||||
XXX Actually there is a *third* issue: older DXF formats are limited
|
||||
to 255 bytes records (it was later raised to 2048); since I'm lazy
|
||||
and text so long is not probable I just don't implement this rule.
|
||||
If someone is interested in fixing this, you have to emit the first
|
||||
partial lines with group code 3 (max 250 bytes each) and then finish
|
||||
with a group code 1 (less than 250 bytes). The DXF refs explains it
|
||||
in no more details...
|
||||
*/
|
||||
|
||||
int braceNesting = 0;
|
||||
int overbarDepth = -1;
|
||||
|
||||
fputs( " 1\n", m_outputFile );
|
||||
|
||||
for( unsigned int i = 0; i < aText.length(); i++ )
|
||||
{
|
||||
/* Here I do a bad thing: writing the output one byte at a time!
|
||||
but today I'm lazy and I have no idea on how to coerce a Unicode
|
||||
wxString to spit out latin1 encoded text ...
|
||||
|
||||
At least stdio is *supposed* to do output buffering, so there is
|
||||
hope is not too slow */
|
||||
wchar_t ch = aText[i];
|
||||
|
||||
if( ch > 255 )
|
||||
{
|
||||
// I can't encode this...
|
||||
putc( '?', m_outputFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aText[i] == '~' && i+1 < aText.length() && aText[i+1] == '{' )
|
||||
{
|
||||
fputs( "%%O", m_outputFile );
|
||||
overbarDepth = -1;
|
||||
fputs( "%%o", m_outputFile );
|
||||
overbarDepth = braceNesting;
|
||||
|
||||
// Skip the '{'
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if( aText[i] == '{' )
|
||||
{
|
||||
braceNesting++;
|
||||
}
|
||||
else if( aText[i] == '}' )
|
||||
{
|
||||
if( braceNesting > 0 )
|
||||
braceNesting--;
|
||||
|
||||
if( braceNesting == overbarDepth )
|
||||
{
|
||||
fputs( "%%O", m_outputFile );
|
||||
overbarDepth = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
putc( ch, m_outputFile );
|
||||
}
|
||||
|
||||
putc( ch, m_outputFile );
|
||||
}
|
||||
}
|
||||
|
||||
putc( '\n', m_outputFile );
|
||||
putc( '\n', m_outputFile );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@ void GERBER_PLOTTER::SetGerberCoordinatesFormat( int aResolution, bool aUseInche
|
||||
|
||||
void GERBER_PLOTTER::emitDcode( const VECTOR2D& pt, int dcode )
|
||||
{
|
||||
|
||||
fprintf( m_outputFile, "X%dY%dD%02d*\n", KiROUND( pt.x ), KiROUND( pt.y ), dcode );
|
||||
}
|
||||
|
||||
@@ -848,16 +849,11 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
|
||||
LineTo( start );
|
||||
|
||||
VECTOR2D devEnd = userToDeviceCoordinates( end );
|
||||
|
||||
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
|
||||
// Warning: it is **not** userToDeviceCoordinates( center - start ) when the plotter
|
||||
// has an offset.
|
||||
VECTOR2D devRelCenter = userToDeviceCoordinates( center ) - userToDeviceCoordinates( start );
|
||||
VECTOR2D devCenter = userToDeviceCoordinates( center - start );
|
||||
|
||||
// We need to know if the arc is CW or CCW in device coordinates, so build this arc.
|
||||
SHAPE_ARC deviceArc( userToDeviceCoordinates( start ),
|
||||
userToDeviceCoordinates( aArc.GetArcMid() ),
|
||||
devEnd, 0 );
|
||||
userToDeviceCoordinates( aArc.GetArcMid() ), devEnd, 0 );
|
||||
|
||||
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
|
||||
|
||||
@@ -868,7 +864,7 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
|
||||
|
||||
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
|
||||
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
|
||||
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
|
||||
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
|
||||
|
||||
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
|
||||
}
|
||||
@@ -889,8 +885,7 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
||||
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
|
||||
end.y = aCenter.y - KiROUND( aRadius * aEndAngle.Sin() );
|
||||
VECTOR2D devEnd = userToDeviceCoordinates( end );
|
||||
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
|
||||
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
|
||||
VECTOR2D devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
|
||||
|
||||
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
|
||||
|
||||
@@ -901,22 +896,24 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
||||
|
||||
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
|
||||
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
|
||||
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
|
||||
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
|
||||
|
||||
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADATA* aGbrMetadata )
|
||||
void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aData )
|
||||
{
|
||||
if( aPoly.PointCount() <= 2 )
|
||||
return;
|
||||
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
bool clearTA_AperFunction = false; // true if a TA.AperFunction is used
|
||||
|
||||
if( aGbrMetadata )
|
||||
if( gbr_metadata )
|
||||
{
|
||||
std::string attrib = aGbrMetadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
|
||||
std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
|
||||
|
||||
if( !attrib.empty() )
|
||||
{
|
||||
@@ -925,7 +922,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADA
|
||||
}
|
||||
}
|
||||
|
||||
PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0 , aGbrMetadata );
|
||||
PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0 , gbr_metadata );
|
||||
|
||||
// Clear the TA attribute, to avoid the next item to inherit it:
|
||||
if( clearTA_AperFunction )
|
||||
@@ -942,17 +939,18 @@ void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADA
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotGerberRegion( const std::vector<VECTOR2I>& aCornerList,
|
||||
GBR_METADATA* aGbrMetadata )
|
||||
void GERBER_PLOTTER::PlotGerberRegion( const std::vector<VECTOR2I>& aCornerList, void* aData )
|
||||
{
|
||||
if( aCornerList.size() <= 2 )
|
||||
return;
|
||||
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
bool clearTA_AperFunction = false; // true if a TA.AperFunction is used
|
||||
|
||||
if( aGbrMetadata )
|
||||
if( gbr_metadata )
|
||||
{
|
||||
std::string attrib = aGbrMetadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
|
||||
std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
|
||||
|
||||
if( !attrib.empty() )
|
||||
{
|
||||
@@ -961,7 +959,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector<VECTOR2I>& aCornerList,
|
||||
}
|
||||
}
|
||||
|
||||
PlotPoly( aCornerList, FILL_T::FILLED_SHAPE, 0, aGbrMetadata );
|
||||
PlotPoly( aCornerList, FILL_T::FILLED_SHAPE, 0, gbr_metadata );
|
||||
|
||||
// Clear the TA attribute, to avoid the next item to inherit it:
|
||||
if( clearTA_AperFunction )
|
||||
@@ -978,19 +976,6 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector<VECTOR2I>& aCornerList,
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotPolyAsRegion( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill,
|
||||
int aWidth, GBR_METADATA* aGbrMetadata )
|
||||
{
|
||||
// plot a filled polygon using Gerber region, therefore adding X2 attributes
|
||||
// to the solid polygon
|
||||
if( aWidth )
|
||||
PlotPoly( aPoly, FILL_T::NO_FILL, aWidth, aGbrMetadata );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
PlotGerberRegion( aPoly, aGbrMetadata );
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int aWidth,
|
||||
void* aData )
|
||||
{
|
||||
@@ -1026,7 +1011,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
|
||||
{
|
||||
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
|
||||
|
||||
plotArc( arc, true );
|
||||
plotArc( arc, ii > 0 );
|
||||
|
||||
// skip points on arcs, since we plot the arc itself
|
||||
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
|
||||
@@ -1060,7 +1045,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
|
||||
{
|
||||
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
|
||||
|
||||
plotArc( arc, true );
|
||||
plotArc( arc, ii > 0 );
|
||||
|
||||
// skip points on arcs, since we plot the arc itself
|
||||
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
|
||||
@@ -1337,7 +1322,7 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
|
||||
if( orient.IsCardinal90() )
|
||||
std::swap( size.x, size.y );
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( aPos );
|
||||
VECTOR2I pos_device = userToDeviceCoordinates( aPos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, ANGLE_0, APERTURE::AT_OVAL, aperture_attrib );
|
||||
|
||||
@@ -1368,7 +1353,7 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
|
||||
orient -= ANGLE_180;
|
||||
}
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( aPos );
|
||||
VECTOR2I pos_device = userToDeviceCoordinates( aPos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, orient, APERTURE::AM_ROTATED_OVAL, aperture_attrib );
|
||||
|
||||
@@ -1431,7 +1416,7 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( pos );
|
||||
VECTOR2I pos_device = userToDeviceCoordinates( pos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, ANGLE_0, APERTURE::AT_RECT, aperture_attrib );
|
||||
|
||||
@@ -1448,7 +1433,7 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
|
||||
{
|
||||
m_hasApertureRotRect = true;
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( pos );
|
||||
VECTOR2I pos_device = userToDeviceCoordinates( pos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, aOrient, APERTURE::AM_ROT_RECT, aperture_attrib );
|
||||
|
||||
@@ -1770,7 +1755,7 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const
|
||||
if( aData )
|
||||
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( aShapePos );
|
||||
VECTOR2I pos_device = userToDeviceCoordinates( aShapePos );
|
||||
SHAPE_POLY_SET outline;
|
||||
std::vector<VECTOR2I> cornerList;
|
||||
|
||||
@@ -2009,20 +1994,6 @@ void GERBER_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData );
|
||||
}
|
||||
|
||||
void GERBER_PLOTTER::SetLayerPolarity( bool aPositive )
|
||||
{
|
||||
if( aPositive )
|
||||
|
||||
@@ -1376,9 +1376,7 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f;
|
||||
double wideningFactor, heightFactor;
|
||||
|
||||
VECTOR2I t_size( std::abs( aSize.x ), std::abs( aSize.y ) );
|
||||
|
||||
computeTextParameters( aPos, aText, aOrient, t_size, m_plotMirror, aH_justify,
|
||||
computeTextParameters( aPos, aText, aOrient, aSize, m_plotMirror, aH_justify,
|
||||
aV_justify, aWidth, aItalic, aBold, &wideningFactor, &ctm_a,
|
||||
&ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
|
||||
|
||||
@@ -1391,7 +1389,7 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
if( !aFont )
|
||||
aFont = KIFONT::FONT::GetFont();
|
||||
|
||||
VECTOR2I full_box( aFont->StringBoundaryLimits( aText, t_size, aWidth, aBold, aItalic ) );
|
||||
VECTOR2I full_box( aFont->StringBoundaryLimits( aText, aSize, aWidth, aBold, aItalic ) );
|
||||
VECTOR2I box_x( full_box.x, 0 );
|
||||
VECTOR2I box_y( 0, full_box.y );
|
||||
|
||||
@@ -1412,13 +1410,13 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
{
|
||||
wxString word = str_tok.GetNextToken();
|
||||
|
||||
computeTextParameters( pos, word, aOrient, t_size, m_plotMirror, GR_TEXT_H_ALIGN_LEFT,
|
||||
computeTextParameters( pos, word, aOrient, aSize, m_plotMirror, GR_TEXT_H_ALIGN_LEFT,
|
||||
GR_TEXT_V_ALIGN_BOTTOM, aWidth, aItalic, aBold, &wideningFactor, &ctm_a,
|
||||
&ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
|
||||
|
||||
// Extract the changed width and rotate by the orientation to get the offset for the
|
||||
// next word
|
||||
VECTOR2I bbox( aFont->StringBoundaryLimits( word, t_size, aWidth, aBold, aItalic ).x, 0 );
|
||||
VECTOR2I bbox( aFont->StringBoundaryLimits( word, aSize, aWidth, aBold, aItalic ).x, 0 );
|
||||
RotatePoint( bbox, aOrient );
|
||||
pos += bbox;
|
||||
|
||||
@@ -1446,30 +1444,6 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
}
|
||||
|
||||
|
||||
void PDF_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
VECTOR2I size = aAttributes.m_Size;
|
||||
|
||||
// PDF files do not like 0 sized texts which create broken files.
|
||||
if( size.x == 0 || size.y == 0 )
|
||||
return;
|
||||
|
||||
if( aAttributes.m_Mirrored )
|
||||
size.x = -size.x;
|
||||
|
||||
PDF_PLOTTER::Text( aPos, aColor, aText, aAttributes.m_Angle, size,
|
||||
aAttributes.m_Halign, aAttributes.m_Valign,
|
||||
aAttributes.m_StrokeWidth,
|
||||
aAttributes.m_Italic, aAttributes.m_Bold,
|
||||
aAttributes.m_Multiline,
|
||||
aFont, aData );
|
||||
}
|
||||
|
||||
|
||||
void PDF_PLOTTER::HyperlinkBox( const BOX2I& aBox, const wxString& aDestinationURL )
|
||||
{
|
||||
m_hyperlinksInPage.push_back( std::make_pair( aBox, aDestinationURL ) );
|
||||
|
||||
@@ -967,28 +967,6 @@ void PS_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
}
|
||||
|
||||
|
||||
void PS_PLOTTER::PlotText( const VECTOR2I& aPos,
|
||||
const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
SetCurrentLineWidth( aAttributes.m_StrokeWidth );
|
||||
SetColor( aColor );
|
||||
|
||||
// Draw the hidden postscript text (if requested)
|
||||
if( m_textMode == PLOT_TEXT_MODE::PHANTOM )
|
||||
{
|
||||
std::string ps_test = encodeStringForPlotter( aText );
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
|
||||
fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y );
|
||||
}
|
||||
|
||||
PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Character widths for Helvetica
|
||||
*/
|
||||
|
||||
@@ -633,13 +633,7 @@ void SVG_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||
{
|
||||
wxMemoryOutputStream img_stream;
|
||||
|
||||
if( m_colorMode )
|
||||
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
|
||||
else // Plot in B&W
|
||||
{
|
||||
wxImage image = aImage.ConvertToGreyscale();
|
||||
image.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
|
||||
}
|
||||
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
|
||||
size_t input_len = img_stream.GetOutputStreamBuffer()->GetBufferSize();
|
||||
std::vector<uint8_t> buffer( input_len );
|
||||
std::vector<uint8_t> encoded;
|
||||
@@ -853,23 +847,3 @@ void SVG_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
|
||||
fputs( "</g>", m_outputFile );
|
||||
}
|
||||
|
||||
|
||||
void SVG_PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
VECTOR2I size = aAttributes.m_Size;
|
||||
|
||||
if( aAttributes.m_Mirrored )
|
||||
size.x = -size.x;
|
||||
|
||||
SVG_PLOTTER::Text( aPos, aColor, aText, aAttributes.m_Angle, size,
|
||||
aAttributes.m_Halign, aAttributes.m_Valign,
|
||||
aAttributes.m_StrokeWidth,
|
||||
aAttributes.m_Italic, aAttributes.m_Bold,
|
||||
aAttributes.m_Multiline,
|
||||
aFont, aData );
|
||||
}
|
||||
|
||||
+18
-50
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-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
|
||||
@@ -694,6 +694,23 @@ void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int a
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as GRText, but plot graphic text instead of draw it.
|
||||
*
|
||||
* @param aPos is the text position (according to aH_justify, aV_justify).
|
||||
* @param aColor is the text color.
|
||||
* @param aText is the text to draw.
|
||||
* @param aOrient is the angle.
|
||||
* @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts).
|
||||
* @param aH_justify is the horizontal justification (Left, center, right).
|
||||
* @param aV_justify is the vertical justification (bottom, center, top).
|
||||
* @param aPenWidth is the line width (if = 0, use plot default line width).
|
||||
* @param aItalic is the true to simulate an italic font.
|
||||
* @param aBold use true to use a bold font Useful only with default width value (aPenWidth = 0).
|
||||
* @param aMultilineAllowed use true to plot text as multiline, otherwise single line.
|
||||
* @param aData is a parameter used by some plotters in SetCurrentLineWidth(),
|
||||
* not directly used here.
|
||||
*/
|
||||
void PLOTTER::Text( const VECTOR2I& aPos,
|
||||
const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
@@ -742,55 +759,6 @@ void PLOTTER::Text( const VECTOR2I& aPos,
|
||||
attributes.m_Valign = aV_justify;
|
||||
attributes.m_Size = aSize;
|
||||
|
||||
// if Size.x is < 0, the text is mirrored (we have no other param to know a text is mirrored)
|
||||
if( attributes.m_Size.x < 0 )
|
||||
{
|
||||
attributes.m_Size.x = -attributes.m_Size.x;
|
||||
attributes.m_Mirrored = true;
|
||||
}
|
||||
|
||||
if( !aFont )
|
||||
aFont = KIFONT::FONT::GetFont();
|
||||
|
||||
aFont->Draw( &callback_gal, aText, aPos, attributes );
|
||||
}
|
||||
|
||||
void PLOTTER::PlotText( const VECTOR2I& aPos, const COLOR4D& aColor,
|
||||
const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttributes,
|
||||
KIFONT::FONT* aFont,
|
||||
void* aData )
|
||||
{
|
||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||
|
||||
TEXT_ATTRIBUTES attributes = aAttributes;
|
||||
int penWidth = attributes.m_StrokeWidth;
|
||||
|
||||
SetColor( aColor );
|
||||
SetCurrentLineWidth( penWidth, aData );
|
||||
|
||||
if( penWidth == 0 && attributes.m_Bold ) // Use default values if aPenWidth == 0
|
||||
penWidth = GetPenSizeForBold( std::min( attributes.m_Size.x, attributes.m_Size.y ) );
|
||||
|
||||
if( penWidth < 0 )
|
||||
penWidth = -penWidth;
|
||||
|
||||
attributes.m_StrokeWidth = penWidth;
|
||||
|
||||
CALLBACK_GAL callback_gal( empty_opts,
|
||||
// Stroke callback
|
||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
||||
{
|
||||
MoveTo( aPt1 );
|
||||
LineTo( aPt2 );
|
||||
PenFinish();
|
||||
},
|
||||
// Polygon callback
|
||||
[&]( const SHAPE_LINE_CHAIN& aPoly )
|
||||
{
|
||||
PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData );
|
||||
} );
|
||||
|
||||
if( !aFont )
|
||||
aFont = KIFONT::FONT::GetFont();
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ void CADSTAR_ARCHIVE_PARSER::LINECODE::Parse( XNODE* aNode, PARSER_CONTEXT* aCon
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
||||
if( !cNode || cNode->GetName() != wxT( "STYLE" ) )
|
||||
if( cNode->GetName() != wxT( "STYLE" ) )
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxString::Format( "LINECODE -> %s", Name ) );
|
||||
|
||||
wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
|
||||
@@ -486,28 +486,18 @@ void CADSTAR_ARCHIVE_PARSER::VERTEX::AppendToChain( SHAPE_LINE_CHAIN* aChainToAp
|
||||
const std::function<VECTOR2I( const VECTOR2I& )> aCadstarToKicadPointCallback,
|
||||
double aAccuracy ) const
|
||||
{
|
||||
VECTOR2I endPoint = aCadstarToKicadPointCallback( End );
|
||||
|
||||
if( Type == VERTEX_TYPE::POINT )
|
||||
{
|
||||
aChainToAppendTo->Append( aCadstarToKicadPointCallback( End ) );
|
||||
aChainToAppendTo->Append( endPoint );
|
||||
return;
|
||||
}
|
||||
|
||||
wxCHECK_MSG( aChainToAppendTo->PointCount() > 0, /*void*/,
|
||||
"Can't append an arc to vertex to an empty chain" );
|
||||
|
||||
aChainToAppendTo->Append( BuildArc( aChainToAppendTo->GetPoint( -1 ), aCadstarToKicadPointCallback),
|
||||
aAccuracy );
|
||||
}
|
||||
|
||||
|
||||
SHAPE_ARC CADSTAR_ARCHIVE_PARSER::VERTEX::BuildArc( const VECTOR2I& aPrevPoint,
|
||||
const std::function<VECTOR2I( const VECTOR2I& )> aCadstarToKicadPointCallback ) const
|
||||
{
|
||||
wxCHECK_MSG( Type != VERTEX_TYPE::POINT, SHAPE_ARC(),
|
||||
"Can't build an arc for a straight segment!" );
|
||||
|
||||
VECTOR2I startPoint = aPrevPoint;
|
||||
VECTOR2I endPoint = aCadstarToKicadPointCallback( End );
|
||||
VECTOR2I startPoint = aChainToAppendTo->GetPoint( -1 );
|
||||
VECTOR2I centerPoint;
|
||||
|
||||
if( Type == VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE || Type == VERTEX_TYPE::CLOCKWISE_SEMICIRCLE )
|
||||
@@ -526,8 +516,9 @@ SHAPE_ARC CADSTAR_ARCHIVE_PARSER::VERTEX::BuildArc( const VECTOR2I& aPrevPoint,
|
||||
clockwise = !clockwise;
|
||||
|
||||
SHAPE_ARC arc;
|
||||
arc.ConstructFromStartEndCenter( startPoint, endPoint, centerPoint, clockwise );
|
||||
|
||||
return arc.ConstructFromStartEndCenter( startPoint, endPoint, centerPoint, clockwise );
|
||||
aChainToAppendTo->Append( arc, aAccuracy );
|
||||
}
|
||||
|
||||
|
||||
@@ -2428,9 +2419,7 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
const wxString& aFileTypeIdentifier, PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
KEYWORD emptyKeywords[1] = {};
|
||||
XNODE* rootNode = nullptr;
|
||||
XNODE* cNode = nullptr;
|
||||
XNODE* iNode = nullptr;
|
||||
XNODE * iNode = nullptr, *cNode = nullptr;
|
||||
int tok;
|
||||
bool cadstarFileCheckDone = false;
|
||||
wxString str;
|
||||
@@ -2462,10 +2451,7 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
|
||||
{
|
||||
if( !aProgressReporter->KeepRefreshing() )
|
||||
{
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "File import cancelled by user." ) );
|
||||
}
|
||||
|
||||
aProgressReporter->SetCurrentProgress( currentProgress() );
|
||||
previousReportedProgress = currentProgress();
|
||||
@@ -2481,7 +2467,6 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
else
|
||||
{
|
||||
//too many closing brackets
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||
}
|
||||
}
|
||||
@@ -2491,9 +2476,6 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
str = wxString( lexer.CurText(), *conv );
|
||||
cNode = new XNODE( wxXML_ELEMENT_NODE, str );
|
||||
|
||||
if( !rootNode )
|
||||
rootNode = cNode;
|
||||
|
||||
if( iNode )
|
||||
{
|
||||
//we will add it as attribute as well as child node
|
||||
@@ -2503,10 +2485,7 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
else if( !cadstarFileCheckDone )
|
||||
{
|
||||
if( cNode->GetName() != aFileTypeIdentifier )
|
||||
{
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||
}
|
||||
|
||||
cadstarFileCheckDone = true;
|
||||
}
|
||||
@@ -2522,28 +2501,19 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
|
||||
else
|
||||
{
|
||||
//not enough closing brackets
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Not enough closing brackets
|
||||
if( iNode != nullptr )
|
||||
{
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||
}
|
||||
|
||||
// Throw if no data was parsed
|
||||
if( rootNode )
|
||||
{
|
||||
return rootNode;
|
||||
}
|
||||
if( cNode )
|
||||
return cNode;
|
||||
else
|
||||
{
|
||||
delete rootNode;
|
||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ class wxXmlAttribute;
|
||||
class PROGRESS_REPORTER;
|
||||
class SHAPE_LINE_CHAIN;
|
||||
class SHAPE_POLY_SET;
|
||||
class SHAPE_ARC;
|
||||
|
||||
/**
|
||||
* @brief Helper functions and common structures for CADSTAR PCB and Schematic archive files.
|
||||
@@ -93,8 +92,6 @@ class CADSTAR_ARCHIVE_PARSER
|
||||
public:
|
||||
CADSTAR_ARCHIVE_PARSER() { m_progressReporter = nullptr; }
|
||||
|
||||
virtual ~CADSTAR_ARCHIVE_PARSER() {}
|
||||
|
||||
|
||||
typedef wxString LINECODE_ID;
|
||||
typedef wxString HATCHCODE_ID;
|
||||
@@ -454,10 +451,6 @@ public:
|
||||
void AppendToChain( SHAPE_LINE_CHAIN* aChainToAppendTo,
|
||||
const std::function<VECTOR2I( const VECTOR2I& )> aCadstarToKicadPointCallback,
|
||||
double aAccuracy ) const;
|
||||
|
||||
SHAPE_ARC BuildArc( const VECTOR2I& aPrevPoint,
|
||||
const std::function<VECTOR2I( const VECTOR2I& )>
|
||||
aCadstarToKicadPointCallback ) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,7 @@ struct EPART;
|
||||
struct ETEXT;
|
||||
|
||||
typedef std::unordered_map<wxString, wxXmlNode*> NODE_MAP;
|
||||
typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP;
|
||||
typedef std::map<wxString, EINSTANCE*> EINSTANCE_MAP;
|
||||
typedef std::map<wxString, std::unique_ptr<EPART>> EPART_MAP;
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wxString& aGroup )
|
||||
void PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wxString& aGroup )
|
||||
{
|
||||
const wxString& name = aProperty->Name();
|
||||
TYPE_ID hash = aProperty->OwnerHash();
|
||||
@@ -147,16 +147,15 @@ PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wx
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
return *aProperty;
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName,
|
||||
PROPERTY_BASE* aNew, const wxString& aGroup )
|
||||
void PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE* aNew,
|
||||
const wxString& aGroup )
|
||||
{
|
||||
CLASS_DESC& classDesc = getClass( aNew->OwnerHash() );
|
||||
classDesc.m_replaced.insert( std::make_pair( aBase, aName ) );
|
||||
return AddProperty( aNew, aGroup );
|
||||
AddProperty( aNew, aGroup );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <pgm_base.h>
|
||||
#include <settings/app_settings.h>
|
||||
#include <settings/json_settings_internals.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
|
||||
@@ -148,7 +147,7 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
||||
&m_System.last_imperial_units, static_cast<int>( EDA_UNITS::INCHES ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
|
||||
&m_ColorTheme, COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT ) );
|
||||
&m_ColorTheme, wxS( "_builtin_default" ) ) );
|
||||
|
||||
addParamsForWindow( &m_Window, "window" );
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
const int colorsSchemaVersion = 5;
|
||||
const wxString COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT = "_builtin_default";
|
||||
const wxString COLOR_SETTINGS::COLOR_BUILTIN_CLASSIC = "_builtin_classic";
|
||||
|
||||
|
||||
COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) :
|
||||
@@ -380,12 +378,12 @@ void COLOR_SETTINGS::SetColor( int aLayer, const COLOR4D& aColor )
|
||||
|
||||
std::vector<COLOR_SETTINGS*> COLOR_SETTINGS::CreateBuiltinColorSettings()
|
||||
{
|
||||
COLOR_SETTINGS* defaultTheme = new COLOR_SETTINGS( COLOR_BUILTIN_DEFAULT );
|
||||
COLOR_SETTINGS* defaultTheme = new COLOR_SETTINGS( wxT( "_builtin_default" ) );
|
||||
defaultTheme->SetName( _( "KiCad Default" ) );
|
||||
defaultTheme->m_writeFile = false;
|
||||
defaultTheme->Load(); // We can just get the colors out of the param defaults for this one
|
||||
|
||||
COLOR_SETTINGS* classicTheme = new COLOR_SETTINGS( COLOR_BUILTIN_CLASSIC );
|
||||
COLOR_SETTINGS* classicTheme = new COLOR_SETTINGS( wxT( "_builtin_classic" ) );
|
||||
classicTheme->SetName( _( "KiCad Classic" ) );
|
||||
classicTheme->m_writeFile = false;
|
||||
|
||||
|
||||
@@ -66,10 +66,6 @@ SETTINGS_MANAGER::SETTINGS_MANAGER( bool aHeadless ) :
|
||||
|
||||
// create the common settings shared by all applications. Not loaded immediately
|
||||
m_common_settings = RegisterSettings( new COMMON_SETTINGS, false );
|
||||
|
||||
// Create the built-in color settings
|
||||
// Here to allow the Python API to access the built-in colors
|
||||
registerBuiltinColorSettings();
|
||||
}
|
||||
|
||||
SETTINGS_MANAGER::~SETTINGS_MANAGER()
|
||||
@@ -207,7 +203,7 @@ COLOR_SETTINGS* SETTINGS_MANAGER::GetColorSettings( const wxString& aName )
|
||||
if( !ret )
|
||||
{
|
||||
ret = registerColorSettings( aName );
|
||||
*ret = *m_color_settings.at( COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT );
|
||||
*ret = *m_color_settings.at( "_builtin_default" );
|
||||
ret->SetFilename( wxT( "user" ) );
|
||||
ret->SetReadOnly( false );
|
||||
}
|
||||
@@ -216,7 +212,7 @@ COLOR_SETTINGS* SETTINGS_MANAGER::GetColorSettings( const wxString& aName )
|
||||
}
|
||||
|
||||
// This had better work
|
||||
return m_color_settings.at( COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT );
|
||||
return m_color_settings.at( "_builtin_default" );
|
||||
}
|
||||
|
||||
|
||||
@@ -309,17 +305,11 @@ COLOR_SETTINGS* SETTINGS_MANAGER::GetMigratedColorSettings()
|
||||
}
|
||||
|
||||
|
||||
void SETTINGS_MANAGER::registerBuiltinColorSettings()
|
||||
{
|
||||
for( COLOR_SETTINGS* settings : COLOR_SETTINGS::CreateBuiltinColorSettings() )
|
||||
m_color_settings[settings->GetFilename()] = RegisterSettings( settings, false );
|
||||
}
|
||||
|
||||
|
||||
void SETTINGS_MANAGER::loadAllColorSettings()
|
||||
{
|
||||
// Create the built-in color settings
|
||||
registerBuiltinColorSettings();
|
||||
for( COLOR_SETTINGS* settings : COLOR_SETTINGS::CreateBuiltinColorSettings() )
|
||||
m_color_settings[settings->GetFilename()] = RegisterSettings( settings, false );
|
||||
|
||||
wxFileName third_party_path;
|
||||
const ENV_VAR_MAP& env = Pgm().GetLocalEnvVariables();
|
||||
@@ -633,12 +623,12 @@ bool SETTINGS_MANAGER::GetPreviousVersionPaths( std::vector<wxString>* aPaths )
|
||||
wxFileName wxGtkPath;
|
||||
wxGtkPath.AssignDir( wxS( "~/.config/kicad" ) );
|
||||
wxGtkPath.MakeAbsolute();
|
||||
base_paths.emplace_back( wxGtkPath );
|
||||
base_paths.emplace_back( wxGtkPath.GetPath() );
|
||||
|
||||
// We also want to pick up regular flatpak if we are nightly
|
||||
wxGtkPath.AssignDir( wxS( "~/.var/app/org.kicad.KiCad/config/kicad" ) );
|
||||
wxGtkPath.MakeAbsolute();
|
||||
base_paths.emplace_back( wxGtkPath );
|
||||
base_paths.emplace_back( wxGtkPath.GetPath() );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
}
|
||||
else if( aContext == CTX_JS_STR )
|
||||
{
|
||||
if( c >= 0x7F || c == '\'' || c == '\\' || c == '(' || c == ')' )
|
||||
if( c >= 0x7F || c == '\'' || c == '\\' )
|
||||
{
|
||||
unsigned int code = c;
|
||||
char buffer[16];
|
||||
|
||||
+1
-41
@@ -34,18 +34,13 @@
|
||||
|
||||
%rename(getWxPoint) operator wxPoint;
|
||||
%rename(getWxSize) operator wxSize;
|
||||
%{
|
||||
#include <math/vector2d.h>
|
||||
#include <math/vector3.h>
|
||||
#include <math/box2.h>
|
||||
%}
|
||||
%include <math/vector2d.h>
|
||||
%include <math/vector3.h>
|
||||
#include <math/box2.h>
|
||||
%include <math/box2.h>
|
||||
|
||||
%template(VECTOR2I) VECTOR2<int>;
|
||||
%template(VECTOR2I_EXTENDED_TYPE) VECTOR2_TRAITS<int>;
|
||||
%template(VECTOR3D) VECTOR3<double>;
|
||||
%template(BOX2I) BOX2<VECTOR2I>;
|
||||
|
||||
%extend VECTOR2<int>
|
||||
@@ -79,38 +74,3 @@
|
||||
|
||||
%}
|
||||
}
|
||||
|
||||
%extend VECTOR3<double>
|
||||
{
|
||||
void Set(double x, double y, double z) { self->x = x; self->y = y; self->z = z; }
|
||||
|
||||
PyObject* Get()
|
||||
{
|
||||
PyObject* tup = PyTuple_New(3);
|
||||
PyTuple_SET_ITEM(tup, 0, PyFloat_FromDouble(self->x));
|
||||
PyTuple_SET_ITEM(tup, 1, PyFloat_FromDouble(self->y));
|
||||
PyTuple_SET_ITEM(tup, 2, PyFloat_FromDouble(self->z));
|
||||
return tup;
|
||||
}
|
||||
|
||||
%pythoncode
|
||||
%{
|
||||
def __eq__(self,other): return (self.x==other.x and self.y==other.y and self.z==other.z)
|
||||
def __ne__(self,other): return not (self==other)
|
||||
def __str__(self): return str(self.Get())
|
||||
def __repr__(self): return 'VECTOR3D'+str(self.Get())
|
||||
def __len__(self): return len(self.Get())
|
||||
def __getitem__(self, index): return self.Get()[index]
|
||||
def __setitem__(self, index, val):
|
||||
if index == 0:
|
||||
self.x = val
|
||||
elif index == 1:
|
||||
self.y = val
|
||||
elif index == 2:
|
||||
self.z = val
|
||||
else:
|
||||
raise IndexError
|
||||
def __nonzero__(self): return self.Get() != (0, 0, 0)
|
||||
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
/// URL to launch a new issue with pre-populated description
|
||||
wxString COMMON_CONTROL::m_bugReportUrl =
|
||||
wxS( "https://gitlab.com/kicad/code/kicad/issues/new?issuable_template=bare&issue[description]=%s" );
|
||||
wxS( "https://gitlab.com/kicad/code/kicad/issues/new?issue[description]=%s" );
|
||||
|
||||
|
||||
/// Issue template to use for reporting bugs (this should not be translated)
|
||||
@@ -113,9 +113,7 @@ int COMMON_CONTROL::ShowLibraryTable( const TOOL_EVENT& aEvent )
|
||||
try // Sch frame was not available, try to start it
|
||||
{
|
||||
KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH );
|
||||
|
||||
if( kiface )
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
|
||||
@@ -1400,7 +1400,7 @@ void VIEW::RecacheAllItems()
|
||||
|
||||
void VIEW::UpdateItems()
|
||||
{
|
||||
if( !m_gal->IsVisible() || !m_gal->IsInitialized() )
|
||||
if( !m_gal->IsVisible() )
|
||||
return;
|
||||
|
||||
unsigned int cntGeomUpdate = 0;
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <widgets/color_swatch.h>
|
||||
#include <wx/dcmemory.h>
|
||||
|
||||
#include <gal/dpi_scaling.h>
|
||||
#include <dialogs/dialog_color_picker.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -134,16 +133,6 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, const COLOR4D& aColor, int aID,
|
||||
m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU );
|
||||
m_checkerboardBg = aParent->GetBackgroundColour();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// These need additional scaling on Windows because of some discrepancy between pixel and
|
||||
// content scaling that only affects certain widgets on Windows HiDPI. On other platforms, the
|
||||
// value returned by ConvertDialogToPixels appears to be correct.
|
||||
DPI_SCALING dpi( nullptr, aParent );
|
||||
|
||||
m_size /= dpi.GetContentScaleFactor();
|
||||
m_checkerboardSize /= dpi.GetContentScaleFactor();
|
||||
#endif
|
||||
|
||||
auto sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
SetSizer( sizer );
|
||||
|
||||
@@ -311,4 +300,4 @@ void COLOR_SWATCH::OnDarkModeToggle()
|
||||
m_checkerboardBg = m_parent->GetBackgroundColour();
|
||||
wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg );
|
||||
m_swatch->SetBitmap( bm );
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <widgets/font_choice.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <wx/fontenum.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
// The "official" name of the building Kicad stroke font (always existing)
|
||||
#include <font/kicad_font_name.h>
|
||||
@@ -34,7 +32,7 @@ FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize
|
||||
m_systemFontCount = wxChoice::GetCount();
|
||||
|
||||
std::vector<std::string> fontNames;
|
||||
Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ) );
|
||||
Fontconfig()->ListFonts( fontNames );
|
||||
|
||||
wxArrayString menuList;
|
||||
|
||||
@@ -55,11 +53,7 @@ FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize
|
||||
menuList.Add( wxString( name ) );
|
||||
|
||||
menuList.Sort();
|
||||
|
||||
Freeze();
|
||||
Append( menuList );
|
||||
KIPLATFORM::UI::LargeChoiceBoxHack( this );
|
||||
Thaw();
|
||||
|
||||
m_notFound = wxS( " " ) + _( "<not found>" );
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <wx/odcombo.h>
|
||||
#include <wx/menuitem.h>
|
||||
|
||||
#include <gal/dpi_scaling.h>
|
||||
#include <layer_ids.h>
|
||||
#include <widgets/layer_box_selector.h>
|
||||
|
||||
@@ -141,12 +140,9 @@ int LAYER_BOX_SELECTOR::SetLayerSelection( int layer )
|
||||
|
||||
void LAYER_BOX_SELECTOR::ResyncBitmapOnly()
|
||||
{
|
||||
DPI_SCALING dpi( nullptr, this );
|
||||
int size = static_cast<int>( dpi.GetScaleFactor() * 14 );
|
||||
|
||||
for( int i = 0; i < (int) GetCount(); ++i )
|
||||
{
|
||||
wxBitmap layerbmp( size, size );
|
||||
wxBitmap layerbmp( 14, 14 );
|
||||
DrawColorSwatch( layerbmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,16 +185,6 @@ LIB_TREE::~LIB_TREE()
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE::ShowChangedLanguage()
|
||||
{
|
||||
if( m_query_ctrl )
|
||||
m_query_ctrl->SetDescriptiveText( _( "Filter" ) );
|
||||
|
||||
if( m_adapter )
|
||||
m_adapter->ShowChangedLanguage();
|
||||
}
|
||||
|
||||
|
||||
LIB_ID LIB_TREE::GetSelectedLibId( int* aUnit ) const
|
||||
{
|
||||
wxDataViewItem sel = m_tree_ctrl->GetSelection();
|
||||
|
||||
+223
-243
@@ -61,8 +61,7 @@ double mpWindow::zoomIncrementalFactor = 1.1;
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS( mpLayer, wxObject )
|
||||
|
||||
mpLayer::mpLayer() :
|
||||
m_type( mpLAYER_UNDEF )
|
||||
mpLayer::mpLayer() : m_type( mpLAYER_UNDEF )
|
||||
{
|
||||
SetPen( (wxPen&) *wxBLACK_PEN );
|
||||
SetFont( (wxFont&) *wxNORMAL_FONT );
|
||||
@@ -198,14 +197,12 @@ wxSize mpInfoLayer::GetSize() const
|
||||
}
|
||||
|
||||
|
||||
mpInfoCoords::mpInfoCoords() :
|
||||
mpInfoLayer()
|
||||
mpInfoCoords::mpInfoCoords() : mpInfoLayer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) :
|
||||
mpInfoLayer( rect, brush )
|
||||
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -276,14 +273,12 @@ void mpInfoCoords::Plot( wxDC& dc, mpWindow& w )
|
||||
}
|
||||
|
||||
|
||||
mpInfoLegend::mpInfoLegend() :
|
||||
mpInfoLayer()
|
||||
mpInfoLegend::mpInfoLegend() : mpInfoLayer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) :
|
||||
mpInfoLayer( rect, brush )
|
||||
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -306,7 +301,7 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
int scrx = w.GetScrX();
|
||||
int scry = w.GetScrY();
|
||||
|
||||
if( m_winX != scrx || m_winY != scry )
|
||||
if( (m_winX != scrx) || (m_winY != scry) )
|
||||
{
|
||||
if( m_winX > 1 )
|
||||
m_dim.x = (int) floor( (double) (m_dim.x * scrx / m_winX) );
|
||||
@@ -327,27 +322,26 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
// wxBrush semiWhite(image1);
|
||||
dc.SetBrush( m_brush );
|
||||
dc.SetFont( m_font );
|
||||
|
||||
const int baseWidth = mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH;
|
||||
int textX = baseWidth, textY = mpLEGEND_MARGIN;
|
||||
int plotCount = 0;
|
||||
int posY = 0;
|
||||
int tmpX = 0;
|
||||
int tmpY = 0;
|
||||
mpLayer* layer = nullptr;
|
||||
wxPen lpen;
|
||||
wxString label;
|
||||
const int baseWidth = (mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH);
|
||||
int textX = baseWidth, textY = mpLEGEND_MARGIN;
|
||||
int plotCount = 0;
|
||||
int posY = 0;
|
||||
int tmpX = 0, tmpY = 0;
|
||||
mpLayer* ly = NULL;
|
||||
wxPen lpen;
|
||||
wxString label;
|
||||
|
||||
for( unsigned int p = 0; p < w.CountAllLayers(); p++ )
|
||||
{
|
||||
layer = w.GetLayer( p );
|
||||
ly = w.GetLayer( p );
|
||||
|
||||
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
|
||||
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
|
||||
{
|
||||
label = layer->GetDisplayName();
|
||||
label = ly->GetName();
|
||||
dc.GetTextExtent( label, &tmpX, &tmpY );
|
||||
textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth + mpLEGEND_MARGIN;
|
||||
textY += tmpY;
|
||||
textX =
|
||||
( textX > (tmpX + baseWidth) ) ? textX : (tmpX + baseWidth + mpLEGEND_MARGIN);
|
||||
textY += (tmpY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,25 +357,25 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
|
||||
|
||||
for( unsigned int p2 = 0; p2 < w.CountAllLayers(); p2++ )
|
||||
{
|
||||
layer = w.GetLayer( p2 );
|
||||
ly = w.GetLayer( p2 );
|
||||
|
||||
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
|
||||
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
|
||||
{
|
||||
label = layer->GetDisplayName();
|
||||
lpen = layer->GetPen();
|
||||
label = ly->GetName();
|
||||
lpen = ly->GetPen();
|
||||
dc.GetTextExtent( label, &tmpX, &tmpY );
|
||||
dc.SetPen( lpen );
|
||||
// textX = (textX > (tmpX + baseWidth)) ? textX : (tmpX + baseWidth);
|
||||
// textY += (tmpY + mpLEGEND_MARGIN);
|
||||
posY = m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY + (tmpY >> 1);
|
||||
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
|
||||
posY, // Y start coord
|
||||
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
|
||||
posY );
|
||||
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
|
||||
posY, // Y start coord
|
||||
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
|
||||
posY );
|
||||
// dc.DrawRectangle(m_dim.x + 5, m_dim.y + 5 + plotCount*tmpY, 5, 5);
|
||||
dc.DrawText( label,
|
||||
m_dim.x + baseWidth,
|
||||
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
|
||||
m_dim.x + baseWidth,
|
||||
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
|
||||
plotCount++;
|
||||
}
|
||||
}
|
||||
@@ -547,8 +541,8 @@ mpFXY::mpFXY( const wxString& name, int flags )
|
||||
SetName( name );
|
||||
m_flags = flags;
|
||||
m_type = mpLAYER_PLOT;
|
||||
m_scaleX = nullptr;
|
||||
m_scaleY = nullptr;
|
||||
m_scaleX = NULL;
|
||||
m_scaleY = NULL;
|
||||
|
||||
// Avoid not initialized members:
|
||||
maxDrawX = minDrawX = maxDrawY = minDrawY = 0;
|
||||
@@ -568,216 +562,205 @@ void mpFXY::UpdateViewBoundary( wxCoord xnew, wxCoord ynew )
|
||||
|
||||
void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||
{
|
||||
wxCHECK_RET( m_scaleX, wxS( "X scale was not set" ) );
|
||||
|
||||
wxCHECK_RET( m_scaleY, wxS( "Y scale was not set" ) );
|
||||
|
||||
if( !m_visible )
|
||||
return;
|
||||
|
||||
wxCoord startPx = m_drawOutsideMargins ? 0 : w.GetMarginLeft();
|
||||
wxCoord endPx = m_drawOutsideMargins ? w.GetScrX() : w.GetScrX() - w.GetMarginRight();
|
||||
wxCoord minYpx = m_drawOutsideMargins ? 0 : w.GetMarginTop();
|
||||
wxCoord maxYpx = m_drawOutsideMargins ? w.GetScrY() : w.GetScrY() - w.GetMarginBottom();
|
||||
|
||||
// Check for a collapsed window before we try to allocate a negative number of points
|
||||
if( endPx <= startPx || minYpx >= maxYpx )
|
||||
return;
|
||||
|
||||
dc.SetPen( m_pen );
|
||||
|
||||
double x, y;
|
||||
// Do this to reset the counters to evaluate bounding box for label positioning
|
||||
Rewind();
|
||||
GetNextXY( x, y );
|
||||
maxDrawX = x;
|
||||
minDrawX = x;
|
||||
maxDrawY = y;
|
||||
minDrawY = y;
|
||||
// drawnPoints = 0;
|
||||
Rewind();
|
||||
|
||||
dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
|
||||
|
||||
if( !m_continuous )
|
||||
if( m_visible )
|
||||
{
|
||||
bool first = true;
|
||||
wxCoord ix = 0;
|
||||
std::set<wxCoord> ys;
|
||||
dc.SetPen( m_pen );
|
||||
|
||||
while( GetNextXY( x, y ) )
|
||||
double x, y;
|
||||
// Do this to reset the counters to evaluate bounding box for label positioning
|
||||
Rewind(); GetNextXY( x, y );
|
||||
maxDrawX = x; minDrawX = x; maxDrawY = y; minDrawY = y;
|
||||
// drawnPoints = 0;
|
||||
Rewind();
|
||||
|
||||
wxCoord startPx = m_drawOutsideMargins ? 0 : w.GetMarginLeft();
|
||||
wxCoord endPx = m_drawOutsideMargins ? w.GetScrX() : w.GetScrX() - w.GetMarginRight();
|
||||
wxCoord minYpx = m_drawOutsideMargins ? 0 : w.GetMarginTop();
|
||||
wxCoord maxYpx = m_drawOutsideMargins ? w.GetScrY() : w.GetScrY() - w.GetMarginBottom();
|
||||
|
||||
dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
|
||||
|
||||
if( !m_continuous )
|
||||
{
|
||||
double px = m_scaleX->TransformToPlot( x );
|
||||
double py = m_scaleY->TransformToPlot( y );
|
||||
wxCoord newX = w.x2p( px );
|
||||
bool first = true;
|
||||
wxCoord ix = 0;
|
||||
std::set<wxCoord> ys;
|
||||
|
||||
if( first )
|
||||
while( GetNextXY( x, y ) )
|
||||
{
|
||||
ix = newX;
|
||||
first = false;
|
||||
}
|
||||
double px = m_scaleX->TransformToPlot( x );
|
||||
double py = m_scaleY->TransformToPlot( y );
|
||||
wxCoord newX = w.x2p( px );
|
||||
|
||||
if( newX == ix ) // continue until a new X coordinate is reached
|
||||
{
|
||||
// collect all unique points
|
||||
ys.insert( w.y2p( py ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
for( auto& iy: ys )
|
||||
{
|
||||
if( m_drawOutsideMargins
|
||||
|| ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx) ) )
|
||||
if( first )
|
||||
{
|
||||
// for some reason DrawPoint does not use the current pen, so we use
|
||||
// DrawLine for fat pens
|
||||
if( m_pen.GetWidth() <= 1 )
|
||||
dc.DrawPoint( ix, iy );
|
||||
else
|
||||
dc.DrawLine( ix, iy, ix, iy );
|
||||
|
||||
UpdateViewBoundary( ix, iy );
|
||||
ix = newX;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
ys.clear();
|
||||
ix = newX;
|
||||
ys.insert( w.y2p( py ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
int x0=0; // X position of merged current vertical line
|
||||
int ymin0=0; // y min coord of merged current vertical line
|
||||
int ymax0=0; // y max coord of merged current vertical line
|
||||
int dupx0 = 0; // count of currently merged vertical lines
|
||||
wxPoint line_start; // starting point of the current line to draw
|
||||
|
||||
// A buffer to store coordinates of lines to draw
|
||||
std::vector<wxPoint>pointList;
|
||||
pointList.reserve( endPx - startPx + 1 );
|
||||
|
||||
// Note: we can use dc.DrawLines() only for a reasonable number or points (<10000),
|
||||
// because at least on Windows dc.DrawLines() can hang for a lot of points.
|
||||
// (> 10000 points) (can happens when a lot of points is calculated)
|
||||
// To avoid long draw time (and perhaps hanging) one plot only not redundant lines.
|
||||
// To avoid artifacts when skipping points to the same x coordinate, for each group of
|
||||
// points at a give, x coordinate we also draw a vertical line at this coord, from the
|
||||
// ymin to the ymax vertical coordinates of skipped points
|
||||
while( GetNextXY( x, y ) )
|
||||
{
|
||||
double px = m_scaleX->TransformToPlot( x );
|
||||
double py = m_scaleY->TransformToPlot( y );
|
||||
|
||||
wxCoord x1 = w.x2p( px );
|
||||
wxCoord y1 = w.y2p( py );
|
||||
|
||||
// Store only points on the drawing area, to speed up the drawing time
|
||||
// Note: x1 is a value truncated from px by w.x2p(). So to be sure the first point
|
||||
// is drawn, the x1 low limit is startPx-1 in plot coordinates
|
||||
if( x1 >= startPx-1 && x1 <= endPx )
|
||||
{
|
||||
if( !count || line_start.x != x1 )
|
||||
{
|
||||
if( count && dupx0 > 1 && ymin0 != ymax0 )
|
||||
{
|
||||
// Vertical points are merged, draw the pending vertical line
|
||||
// However, if the line is one pixel length, it is not drawn, because
|
||||
// the main trace show this point
|
||||
dc.DrawLine( x0, ymin0, x0, ymax0 );
|
||||
}
|
||||
|
||||
x0 = x1;
|
||||
ymin0 = ymax0 = y1;
|
||||
dupx0 = 0;
|
||||
|
||||
pointList.emplace_back( wxPoint( x1, y1 ) );
|
||||
|
||||
line_start.x = x1;
|
||||
line_start.y = y1;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ymin0 = std::min( ymin0, y1 );
|
||||
ymax0 = std::max( ymax0, y1 );
|
||||
x0 = x1;
|
||||
dupx0++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pointList.size() > 1 )
|
||||
{
|
||||
// For a better look (when using dashed lines) and more optimization, try to merge
|
||||
// horizontal segments, in order to plot longer lines
|
||||
// We are merging horizontal segments because this is easy, and horizontal segments
|
||||
// are a frequent cases
|
||||
std::vector<wxPoint> drawPoints;
|
||||
drawPoints.reserve( endPx - startPx + 1 );
|
||||
|
||||
drawPoints.push_back( pointList[0] ); // push the first point in list
|
||||
|
||||
for( size_t ii = 1; ii < pointList.size()-1; ii++ )
|
||||
{
|
||||
// Skip intermediate points between the first point and the last point of the
|
||||
// segment candidate
|
||||
if( drawPoints.back().y == pointList[ii].y &&
|
||||
drawPoints.back().y == pointList[ii+1].y )
|
||||
if( newX == ix ) // continue until a new X coordinate is reached
|
||||
{
|
||||
// collect all unique points
|
||||
ys.insert( w.y2p( py ) );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
for( auto& iy: ys )
|
||||
{
|
||||
drawPoints.push_back( pointList[ii] );
|
||||
if( m_drawOutsideMargins
|
||||
|| ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx)
|
||||
&& (iy <= maxYpx) ) )
|
||||
{
|
||||
// for some reason DrawPoint does not use the current pen,
|
||||
// so we use DrawLine for fat pens
|
||||
if( m_pen.GetWidth() <= 1 )
|
||||
{
|
||||
dc.DrawPoint( ix, iy );
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.DrawLine( ix, iy, ix, iy );
|
||||
}
|
||||
|
||||
UpdateViewBoundary( ix, iy );
|
||||
}
|
||||
}
|
||||
|
||||
ys.clear();
|
||||
ix = newX;
|
||||
ys.insert( w.y2p( py ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
int x0=0; // X position of merged current vertical line
|
||||
int ymin0=0; // y min coord of merged current vertical line
|
||||
int ymax0=0; // y max coord of merged current vertical line
|
||||
int dupx0 = 0; // count of currently merged vertical lines
|
||||
wxPoint line_start; // starting point of the current line to draw
|
||||
|
||||
// A buffer to store coordinates of lines to draw
|
||||
std::vector<wxPoint>pointList;
|
||||
pointList.reserve( endPx - startPx + 1 );
|
||||
|
||||
// Note: we can use dc.DrawLines() only for a reasonable number or points (<10000),
|
||||
// because at least on Windows dc.DrawLines() can hang for a lot of points.
|
||||
// (> 10000 points) (can happens when a lot of points is calculated)
|
||||
// To avoid long draw time (and perhaps hanging) one plot only not redundant lines.
|
||||
// To avoid artifacts when skipping points to the same x coordinate, for each
|
||||
// group of points at a give, x coordinate we also draw a vertical line at this coord,
|
||||
// from the ymin to the ymax vertical coordinates of skipped points
|
||||
while( GetNextXY( x, y ) )
|
||||
{
|
||||
double px = m_scaleX->TransformToPlot( x );
|
||||
double py = m_scaleY->TransformToPlot( y );
|
||||
|
||||
wxCoord x1 = w.x2p( px );
|
||||
wxCoord y1 = w.y2p( py );
|
||||
|
||||
// Store only points on the drawing area, to speed up the drawing time
|
||||
// Note: x1 is a value truncated from px by w.x2p(). So to be sure the
|
||||
// first point is drawn, the x1 low limit is startPx-1 in plot coordinates
|
||||
if( x1 >= startPx-1 && x1 <= endPx )
|
||||
{
|
||||
if( !count || line_start.x != x1 )
|
||||
{
|
||||
if( count && dupx0 > 1 && ymin0 != ymax0 )
|
||||
{
|
||||
// Vertical points are merged, draw the pending vertical line
|
||||
// However, if the line is one pixel length, it is not drawn,
|
||||
// because the main trace show this point
|
||||
dc.DrawLine( x0, ymin0, x0, ymax0 );
|
||||
}
|
||||
|
||||
x0 = x1;
|
||||
ymin0 = ymax0 = y1;
|
||||
dupx0 = 0;
|
||||
|
||||
pointList.emplace_back( wxPoint( x1, y1 ) );
|
||||
|
||||
line_start.x = x1;
|
||||
line_start.y = y1;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ymin0 = std::min( ymin0, y1 );
|
||||
ymax0 = std::max( ymax0, y1 );
|
||||
x0 = x1;
|
||||
dupx0++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the last point to draw in list
|
||||
if( drawPoints.back() != pointList.back() )
|
||||
drawPoints.push_back( pointList.back() );
|
||||
if( pointList.size() > 1 )
|
||||
{
|
||||
// For a better look (when using dashed lines) and more optimization,
|
||||
// try to merge horizontal segments, in order to plot longer lines
|
||||
// we are merging horizontal segments because this is easy,
|
||||
// and horizontal segments are a frequent cases
|
||||
std::vector<wxPoint> drawPoints;
|
||||
drawPoints.reserve( endPx - startPx + 1 );
|
||||
|
||||
dc.DrawLines( drawPoints.size(), &drawPoints[0] );
|
||||
drawPoints.push_back( pointList[0] ); // push the first point in list
|
||||
|
||||
for( size_t ii = 1; ii < pointList.size()-1; ii++ )
|
||||
{
|
||||
// Skip intermediate points between the first point and the last
|
||||
// point of the segment candidate
|
||||
if( drawPoints.back().y == pointList[ii].y &&
|
||||
drawPoints.back().y == pointList[ii+1].y )
|
||||
continue;
|
||||
else
|
||||
drawPoints.push_back( pointList[ii] );
|
||||
}
|
||||
|
||||
// push the last point to draw in list
|
||||
if( drawPoints.back() != pointList.back() )
|
||||
drawPoints.push_back( pointList.back() );
|
||||
|
||||
dc.DrawLines( drawPoints.size(), &drawPoints[0] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_name.IsEmpty() && m_showName )
|
||||
{
|
||||
dc.SetFont( m_font );
|
||||
|
||||
wxCoord tx, ty;
|
||||
dc.GetTextExtent( m_name, &tx, &ty );
|
||||
|
||||
// xxx implement else ... if (!HasBBox())
|
||||
if( !m_name.IsEmpty() && m_showName )
|
||||
{
|
||||
// const int sx = w.GetScrX();
|
||||
// const int sy = w.GetScrY();
|
||||
dc.SetFont( m_font );
|
||||
|
||||
if( (m_flags & mpALIGNMASK) == mpALIGN_NW )
|
||||
wxCoord tx, ty;
|
||||
dc.GetTextExtent( m_name, &tx, &ty );
|
||||
|
||||
// xxx implement else ... if (!HasBBox())
|
||||
{
|
||||
tx = minDrawX + 8;
|
||||
ty = maxDrawY + 8;
|
||||
}
|
||||
else if( (m_flags & mpALIGNMASK) == mpALIGN_NE )
|
||||
{
|
||||
tx = maxDrawX - tx - 8;
|
||||
ty = maxDrawY + 8;
|
||||
}
|
||||
else if( (m_flags & mpALIGNMASK) == mpALIGN_SE )
|
||||
{
|
||||
tx = maxDrawX - tx - 8;
|
||||
ty = minDrawY - ty - 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mpALIGN_SW
|
||||
tx = minDrawX + 8;
|
||||
ty = minDrawY - ty - 8;
|
||||
// const int sx = w.GetScrX();
|
||||
// const int sy = w.GetScrY();
|
||||
|
||||
if( (m_flags & mpALIGNMASK) == mpALIGN_NW )
|
||||
{
|
||||
tx = minDrawX + 8;
|
||||
ty = maxDrawY + 8;
|
||||
}
|
||||
else if( (m_flags & mpALIGNMASK) == mpALIGN_NE )
|
||||
{
|
||||
tx = maxDrawX - tx - 8;
|
||||
ty = maxDrawY + 8;
|
||||
}
|
||||
else if( (m_flags & mpALIGNMASK) == mpALIGN_SE )
|
||||
{
|
||||
tx = maxDrawX - tx - 8;
|
||||
ty = minDrawY - ty - 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// mpALIGN_SW
|
||||
tx = minDrawX + 8;
|
||||
ty = minDrawY - ty - 8;
|
||||
}
|
||||
}
|
||||
|
||||
dc.DrawText( m_name, tx, ty );
|
||||
}
|
||||
|
||||
dc.DrawText( m_name, tx, ty );
|
||||
}
|
||||
|
||||
dc.DestroyClippingRegion();
|
||||
@@ -1412,7 +1395,7 @@ mpScaleY::mpScaleY( const wxString& name, int flags, bool ticks )
|
||||
m_flags = flags;
|
||||
m_ticks = ticks;
|
||||
m_type = mpLAYER_AXIS;
|
||||
m_masterScale = nullptr;
|
||||
m_masterScale = NULL;
|
||||
m_nameFlags = mpALIGN_BORDER_LEFT;
|
||||
}
|
||||
|
||||
@@ -1618,8 +1601,7 @@ EVT_MENU( mpID_ZOOM_OUT, mpWindow::OnZoomOut )
|
||||
EVT_MENU( mpID_LOCKASPECT, mpWindow::OnLockAspect )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
mpWindow::mpWindow() :
|
||||
wxWindow(),
|
||||
mpWindow::mpWindow() : wxWindow(),
|
||||
m_lockaspect( false ),
|
||||
m_minX( 0.0 ),
|
||||
m_maxX( 0.0 ),
|
||||
@@ -1680,11 +1662,11 @@ mpWindow::mpWindow( wxWindow* parent,
|
||||
m_minX = m_minY = 0;
|
||||
m_maxX = m_maxY = 0;
|
||||
m_last_lx = m_last_ly = 0;
|
||||
m_buff_bmp = nullptr;
|
||||
m_buff_bmp = NULL;
|
||||
m_enableDoubleBuffer = false;
|
||||
m_enableMouseNavigation = true;
|
||||
m_enableLimitedView = false;
|
||||
m_movingInfoLayer = nullptr;
|
||||
m_movingInfoLayer = NULL;
|
||||
// Set margins to 0
|
||||
m_marginTop = 0; m_marginRight = 0; m_marginBottom = 0; m_marginLeft = 0;
|
||||
|
||||
@@ -1932,10 +1914,10 @@ void mpWindow::OnMouseLeftRelease( wxMouseEvent& event )
|
||||
|
||||
m_zooming = false;
|
||||
|
||||
if( m_movingInfoLayer != nullptr )
|
||||
if( m_movingInfoLayer != NULL )
|
||||
{
|
||||
m_movingInfoLayer->UpdateReference();
|
||||
m_movingInfoLayer = nullptr;
|
||||
m_movingInfoLayer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1971,7 +1953,7 @@ void mpWindow::Fit( double xMin, double xMax, double yMin, double yMax,
|
||||
yMin -= yExtra;
|
||||
yMax += yExtra;
|
||||
|
||||
if( printSizeX != nullptr && printSizeY != nullptr )
|
||||
if( printSizeX != NULL && printSizeY != NULL )
|
||||
{
|
||||
// Printer:
|
||||
m_scrX = *printSizeX;
|
||||
@@ -2012,7 +1994,7 @@ void mpWindow::Fit( double xMin, double xMax, double yMin, double yMax,
|
||||
|
||||
// It is VERY IMPORTANT to DO NOT call Refresh if we are drawing to the printer!!
|
||||
// Otherwise, the DC dimensions will be those of the window instead of the printer device
|
||||
if( printSizeX == nullptr || printSizeY == nullptr )
|
||||
if( printSizeX == NULL || printSizeY == NULL )
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
@@ -2652,7 +2634,7 @@ unsigned int mpWindow::CountLayers() const
|
||||
mpLayer* mpWindow::GetLayer( int position ) const
|
||||
{
|
||||
if( ( position >= (int) m_layers.size() ) || position < 0 )
|
||||
return nullptr;
|
||||
return NULL;
|
||||
|
||||
return m_layers[position];
|
||||
}
|
||||
@@ -2666,7 +2648,7 @@ const mpLayer* mpWindow::GetLayerByName( const wxString& name ) const
|
||||
return layer;
|
||||
}
|
||||
|
||||
return nullptr; // Not found
|
||||
return NULL; // Not found
|
||||
}
|
||||
|
||||
|
||||
@@ -2753,7 +2735,7 @@ mpInfoLayer* mpWindow::IsInsideInfoLayer( wxPoint& point )
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2833,8 +2815,7 @@ void mpWindow::SetColourTheme( const wxColour& bgColour, const wxColour& drawCol
|
||||
IMPLEMENT_DYNAMIC_CLASS( mpFXYVector, mpFXY )
|
||||
|
||||
// Constructor
|
||||
mpFXYVector::mpFXYVector( const wxString& name, int flags ) :
|
||||
mpFXY( name, flags )
|
||||
mpFXYVector::mpFXYVector( const wxString& name, int flags ) : mpFXY( name, flags )
|
||||
{
|
||||
m_index = 0;
|
||||
m_minX = -1;
|
||||
@@ -3038,8 +3019,7 @@ void mpText::Plot( wxDC& dc, mpWindow& w )
|
||||
// mpPrintout - provided by Davide Rondini
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) :
|
||||
wxPrintout( title )
|
||||
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) : wxPrintout( title )
|
||||
{
|
||||
drawn = false;
|
||||
plotWindow = drawWindow;
|
||||
@@ -3098,9 +3078,9 @@ bool mpPrintout::OnPrintPage( int page )
|
||||
// Restore colours
|
||||
plotWindow->SetColourTheme( oldBgColour, oldFgColour, oldAxColour );
|
||||
// Restore drawing
|
||||
plotWindow->Fit( plotWindow->GetDesiredXmin(), plotWindow->GetDesiredXmax(),
|
||||
plotWindow->GetDesiredYmin(), plotWindow->GetDesiredYmax(), nullptr,
|
||||
nullptr );
|
||||
plotWindow->Fit( plotWindow->GetDesiredXmin(),
|
||||
plotWindow->GetDesiredXmax(), plotWindow->GetDesiredYmin(),
|
||||
plotWindow->GetDesiredYmax(), NULL, NULL );
|
||||
plotWindow->UpdateAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
delete wxPGGlobalVars->m_defaultRenderer;
|
||||
wxPGGlobalVars->m_defaultRenderer = new PG_CELL_RENDERER();
|
||||
|
||||
m_cachedSelection = std::make_unique<SELECTION>();
|
||||
|
||||
m_caption = new wxStaticText( this, wxID_ANY, _( "No objects selected" ) );
|
||||
mainSizer->Add( m_caption, 0, wxALL | wxEXPAND, 5 );
|
||||
|
||||
@@ -72,7 +74,6 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
wxPG_DEFAULT_STYLE );
|
||||
m_grid->SetUnspecifiedValueAppearance( wxPGCell( wxT( "<...>" ) ) );
|
||||
m_grid->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
|
||||
m_grid->SetValidationFailureBehavior( wxPG_VFB_MARK_CELL );
|
||||
m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
|
||||
m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
|
||||
m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
|
||||
@@ -130,20 +131,23 @@ void PROPERTIES_PANEL::OnLanguageChanged()
|
||||
|
||||
void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
{
|
||||
auto reset =
|
||||
[&]()
|
||||
{
|
||||
if( m_grid->IsEditorFocused() )
|
||||
m_grid->CommitChangesFromEditor();
|
||||
if( *m_cachedSelection == aSelection )
|
||||
{
|
||||
updatePropertyValues( aSelection );
|
||||
return;
|
||||
}
|
||||
|
||||
m_grid->Clear();
|
||||
m_displayed.clear();
|
||||
};
|
||||
*m_cachedSelection = aSelection;
|
||||
|
||||
if( m_grid->IsEditorFocused() )
|
||||
m_grid->CommitChangesFromEditor();
|
||||
|
||||
m_grid->Clear();
|
||||
m_displayed.clear();
|
||||
|
||||
if( aSelection.Empty() )
|
||||
{
|
||||
m_caption->SetLabel( _( "No objects selected" ) );
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,6 +159,15 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
|
||||
wxCHECK( !types.empty(), /* void */ );
|
||||
|
||||
if( aSelection.Size() > 1 )
|
||||
{
|
||||
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
|
||||
}
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
propMgr.SetUnits( m_frame->GetUserUnits() );
|
||||
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
|
||||
@@ -168,7 +181,8 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||
|
||||
std::set<PROPERTY_BASE*> availableProps;
|
||||
std::map<wxPGProperty*, int> pgPropOrders;
|
||||
std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
|
||||
|
||||
// Get all possible properties
|
||||
for( const TYPE_ID& type : types )
|
||||
@@ -200,77 +214,40 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
}
|
||||
}
|
||||
|
||||
EDA_ITEM* firstItem = aSelection.Front();
|
||||
|
||||
// Find a set of properties that is common to all selected items
|
||||
for( PROPERTY_BASE* property : commonProps )
|
||||
{
|
||||
if( property->IsHiddenFromPropertiesManager() )
|
||||
if( property->IsInternal() )
|
||||
continue;
|
||||
|
||||
if( propMgr.IsAvailableFor( TYPE_HASH( *firstItem ), property, firstItem ) )
|
||||
availableProps.insert( property );
|
||||
}
|
||||
|
||||
bool writeable = true;
|
||||
std::set<PROPERTY_BASE*> existingProps;
|
||||
|
||||
for( wxPropertyGridIterator it = m_grid->GetIterator(); !it.AtEnd(); it.Next() )
|
||||
{
|
||||
wxPGProperty* pgProp = it.GetProperty();
|
||||
PROPERTY_BASE* property = propMgr.GetProperty( TYPE_HASH( *firstItem ), pgProp->GetName() );
|
||||
|
||||
// Switching item types? Property may no longer be valid
|
||||
if( !property )
|
||||
if( !propMgr.IsAvailableFor( TYPE_HASH( *aSelection.Front() ), property,
|
||||
aSelection.Front() ) )
|
||||
continue;
|
||||
|
||||
// Either determine the common value for a property or "<...>" to indicate multiple values
|
||||
bool available;
|
||||
bool writeable;
|
||||
wxVariant commonVal;
|
||||
|
||||
extractValueAndWritability( aSelection, property, commonVal, writeable );
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
available = extractValueAndWritability( aSelection, property, commonVal, writeable );
|
||||
|
||||
existingProps.insert( property );
|
||||
}
|
||||
|
||||
if( existingProps == availableProps )
|
||||
return;
|
||||
|
||||
// Some difference exists: start from scratch
|
||||
reset();
|
||||
|
||||
std::map<wxPGProperty*, int> pgPropOrders;
|
||||
std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
|
||||
|
||||
for( PROPERTY_BASE* property : availableProps )
|
||||
{
|
||||
wxPGProperty* pgProp = createPGProperty( property );
|
||||
wxVariant commonVal;
|
||||
|
||||
if( !extractValueAndWritability( aSelection, property, commonVal, writeable ) )
|
||||
continue;
|
||||
|
||||
if( pgProp )
|
||||
if( available )
|
||||
{
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
m_displayed.push_back( property );
|
||||
wxPGProperty* pgProp = createPGProperty( property );
|
||||
|
||||
wxASSERT( displayOrder.count( property ) );
|
||||
pgPropOrders[pgProp] = displayOrder[property];
|
||||
pgPropGroups[property->Group()].emplace_back( pgProp );
|
||||
if( pgProp )
|
||||
{
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
m_displayed.push_back( property );
|
||||
|
||||
wxASSERT( displayOrder.count( property ) );
|
||||
pgPropOrders[pgProp] = displayOrder[property];
|
||||
pgPropGroups[property->Group()].emplace_back( pgProp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aSelection.Size() > 1 )
|
||||
{
|
||||
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
|
||||
}
|
||||
|
||||
const wxString unspecifiedGroupCaption = _( "Basic Properties" );
|
||||
|
||||
for( const wxString& groupName : groupDisplayOrder )
|
||||
|
||||
@@ -75,10 +75,24 @@ protected:
|
||||
/**
|
||||
* Generates the property grid for a given selection of items.
|
||||
*
|
||||
* Calling this will remove any existing properties shown, causing visible flicker on some
|
||||
* platforms and canceling any pending edits. Make sure to only call this when the group of
|
||||
* selected items has actually changed.
|
||||
*
|
||||
* @param aSelection is a set of items to show properties for.
|
||||
*/
|
||||
virtual void rebuildProperties( const SELECTION& aSelection );
|
||||
|
||||
/**
|
||||
* Updates the values shown in the property grid for the current selection.
|
||||
*
|
||||
* Does not add or remove properties from the display (@see rebuildProperties)
|
||||
* This implies that aSelection must have the same contents as m_cachedSelection.
|
||||
*
|
||||
* @param aSelection is the set of selected items.
|
||||
*/
|
||||
virtual void updatePropertyValues( const SELECTION& aSelection ) {}
|
||||
|
||||
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0;
|
||||
|
||||
// Event handlers
|
||||
@@ -114,6 +128,9 @@ protected:
|
||||
|
||||
/// Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
|
||||
float m_splitter_key_proportion;
|
||||
|
||||
/// A copy of the most recent selection passed to rebuildProperties
|
||||
std::unique_ptr<SELECTION> m_cachedSelection;
|
||||
};
|
||||
|
||||
#endif /* PROPERTIES_PANEL_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* 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
|
||||
@@ -42,8 +42,6 @@ void SEARCH_PANE::OnLanguageChange()
|
||||
wxWindow* page = m_notebook->GetPage( i );
|
||||
SEARCH_PANE_TAB* tab = dynamic_cast<SEARCH_PANE_TAB*>( page );
|
||||
|
||||
wxCHECK( tab, /* void */ );
|
||||
|
||||
tab->RefreshColumnNames();
|
||||
m_notebook->SetPageText( i, wxGetTranslation( tab->GetSearchHandler()->GetName() ) );
|
||||
}
|
||||
@@ -105,4 +103,4 @@ void SEARCH_PANE::OnNotebookPageChanged( wxBookCtrlEvent& aEvent )
|
||||
SEARCH_PANE_TAB* SEARCH_PANE::GetCurrentTab() const
|
||||
{
|
||||
return dynamic_cast<SEARCH_PANE_TAB*>( m_notebook->GetCurrentPage() );
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent, wxStaticText* aLabel, wxWindo
|
||||
UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource,
|
||||
wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
|
||||
bool aAllowEval, bool aBindFocusEvent ) :
|
||||
m_eventSource( aEventSource ),
|
||||
m_bindFocusEvent( aBindFocusEvent ),
|
||||
m_label( aLabel ),
|
||||
m_valueCtrl( aValueCtrl ),
|
||||
@@ -98,10 +99,10 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
|
||||
this );
|
||||
}
|
||||
|
||||
if( aEventSource )
|
||||
if( m_eventSource )
|
||||
{
|
||||
aEventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
m_eventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +115,12 @@ UNIT_BINDER::~UNIT_BINDER()
|
||||
this );
|
||||
}
|
||||
|
||||
if( m_eventSource )
|
||||
{
|
||||
m_eventSource->Disconnect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
}
|
||||
|
||||
if( m_valueCtrl )
|
||||
{
|
||||
m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
|
||||
@@ -388,7 +395,7 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
|
||||
|
||||
value += EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
|
||||
}
|
||||
|
||||
|
||||
if( textEntry )
|
||||
textEntry->SetValue( value );
|
||||
else if( staticText )
|
||||
|
||||
@@ -273,7 +273,7 @@ void WX_GRID::DestroyTable( wxGridTableBase* aTable )
|
||||
}
|
||||
|
||||
|
||||
wxString WX_GRID::GetShownColumnsAsString()
|
||||
wxString WX_GRID::GetShownColumns()
|
||||
{
|
||||
wxString shownColumns;
|
||||
|
||||
@@ -292,17 +292,6 @@ wxString WX_GRID::GetShownColumnsAsString()
|
||||
}
|
||||
|
||||
|
||||
std::bitset<64> WX_GRID::GetShownColumns()
|
||||
{
|
||||
std::bitset<64> shownColumns;
|
||||
|
||||
for( int ii = 0; ii < GetNumberCols(); ++ii )
|
||||
shownColumns[ii] = IsColShown( ii );
|
||||
|
||||
return shownColumns;
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::ShowHideColumns( const wxString& shownColumns )
|
||||
{
|
||||
for( int i = 0; i < GetNumberCols(); ++i )
|
||||
@@ -321,18 +310,6 @@ void WX_GRID::ShowHideColumns( const wxString& shownColumns )
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::ShowHideColumns( const std::bitset<64>& aShownColumns )
|
||||
{
|
||||
for( int ii = 0; ii < GetNumberCols(); ++ ii )
|
||||
{
|
||||
if( aShownColumns[ii] )
|
||||
ShowCol( ii );
|
||||
else
|
||||
HideCol( ii );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WX_GRID::DrawCornerLabel( wxDC& dc )
|
||||
{
|
||||
if( m_nativeColumnLabels )
|
||||
|
||||
@@ -63,7 +63,7 @@ WX_INFOBAR::WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr, wxWindowID aWinid
|
||||
|
||||
// Infobar is broken on Mac without the effects
|
||||
SetShowHideEffects( wxSHOW_EFFECT_ROLL_TO_BOTTOM, wxSHOW_EFFECT_ROLL_TO_TOP );
|
||||
SetEffectDuration( 200 );
|
||||
SetEffectDuration( 300 );
|
||||
#else
|
||||
// Infobar freezes canvas on Windows with the effect, and GTK looks bad with it
|
||||
SetShowHideEffects( wxSHOW_EFFECT_NONE, wxSHOW_EFFECT_NONE );
|
||||
|
||||
@@ -38,8 +38,9 @@ SYMBOLS_LISTBOX::SYMBOLS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id ) :
|
||||
ITEMS_LISTBOX_BASE( parent, id ),
|
||||
m_warningAttr( std::make_unique<wxListItemAttr>() )
|
||||
{
|
||||
m_warningAttr->SetBackgroundColour( KIPLATFORM::UI::IsDarkTheme() ? wxColour( 112, 96, 32 )
|
||||
: wxColour( 255, 248, 212 ) );
|
||||
m_warningAttr->SetBackgroundColour( KIPLATFORM::UI::IsDarkTheme()
|
||||
? wxColour( 112, 96, 32 )
|
||||
: *wxYELLOW );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,9 +84,6 @@ void CVPCB_MAINFRAME::ReCreateHToolbar()
|
||||
m_tcFilterString = new wxTextCtrl( m_mainToolBar, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||
wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
|
||||
// Min size on Mac is (a not very useful) single character
|
||||
m_tcFilterString->SetMinSize( wxSize( 150, -1 ) );
|
||||
|
||||
m_tcFilterString->Bind( wxEVT_TEXT_ENTER, &CVPCB_MAINFRAME::onTextFilterChanged, this );
|
||||
|
||||
m_mainToolBar->AddControl( m_tcFilterString );
|
||||
|
||||
+11
-108
@@ -195,7 +195,7 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
|
||||
m_driver_connection->SetDriver( m_driver );
|
||||
m_driver_connection->ClearDirty();
|
||||
}
|
||||
else if( !m_is_bus_member )
|
||||
else
|
||||
{
|
||||
m_driver_connection = nullptr;
|
||||
}
|
||||
@@ -246,36 +246,7 @@ wxString CONNECTION_SUBGRAPH::GetNetName() const
|
||||
}
|
||||
|
||||
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetAllBusLabels() const
|
||||
{
|
||||
std::vector<SCH_ITEM*> labels;
|
||||
|
||||
for( SCH_ITEM* item : m_drivers )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
{
|
||||
CONNECTION_TYPE type = item->Connection( &m_sheet )->Type();
|
||||
|
||||
// Only consider bus vectors
|
||||
if( type == CONNECTION_TYPE::BUS || type == CONNECTION_TYPE::BUS_GROUP )
|
||||
labels.push_back( item );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetVectorBusLabels() const
|
||||
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetBusLabels() const
|
||||
{
|
||||
std::vector<SCH_ITEM*> labels;
|
||||
|
||||
@@ -1000,58 +971,6 @@ void CONNECTION_GRAPH::collectAllDriverValues()
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::generateBusAliasMembers()
|
||||
{
|
||||
std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
|
||||
|
||||
SCH_CONNECTION dummy( this );
|
||||
|
||||
for( auto&& subgraph : m_driver_subgraphs )
|
||||
{
|
||||
auto vec = subgraph->GetAllBusLabels();
|
||||
|
||||
for( auto& item : vec )
|
||||
{
|
||||
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
|
||||
|
||||
dummy.ConfigureFromLabel( label->GetText() );
|
||||
|
||||
wxLogTrace( ConnTrace, wxS( "new bus label (%s)" ), label->GetText() );
|
||||
|
||||
for( auto& conn : dummy.Members() )
|
||||
{
|
||||
wxString name = conn->FullLocalName();
|
||||
|
||||
CONNECTION_SUBGRAPH* new_sg = new CONNECTION_SUBGRAPH( this );
|
||||
SCH_CONNECTION* new_conn = new SCH_CONNECTION( this );
|
||||
|
||||
new_conn->SetName( name );
|
||||
new_conn->SetType( CONNECTION_TYPE::NET );
|
||||
int code = assignNewNetCode( *new_conn );
|
||||
|
||||
wxLogTrace( ConnTrace, wxS( "SG(%ld), Adding full local name (%s) with sg (%d)" ), subgraph->m_code,
|
||||
name, code );
|
||||
|
||||
new_sg->m_driver_connection = new_conn;
|
||||
new_sg->m_code = m_last_subgraph_code++;
|
||||
new_sg->m_sheet = subgraph->m_sheet;
|
||||
new_sg->m_is_bus_member = true;
|
||||
new_sg->m_strong_driver = true;
|
||||
/// Need to figure out why these sgs are not getting connected to their bus parents
|
||||
|
||||
NET_NAME_CODE_CACHE_KEY key = { new_sg->GetNetName(), code };
|
||||
m_net_code_to_subgraphs_map[ key ].push_back( new_sg );
|
||||
m_net_name_to_subgraphs_map[ name ].push_back( new_sg );
|
||||
m_subgraphs.push_back( new_sg );
|
||||
new_subgraphs.push_back( new_sg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::copy( new_subgraphs.begin(), new_subgraphs.end(), std::back_inserter( m_driver_subgraphs ) );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::generateInvisiblePinSubGraphs()
|
||||
{
|
||||
// Generate subgraphs for invisible power pins. These will be merged with other subgraphs
|
||||
@@ -1196,7 +1115,7 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
|
||||
name = new_name;
|
||||
}
|
||||
else if( subgraph->m_driver )
|
||||
else
|
||||
{
|
||||
// If there is no conflict, promote sheet pins to be strong drivers so that they
|
||||
// will be considered below for propagation/merging.
|
||||
@@ -1436,8 +1355,7 @@ void CONNECTION_GRAPH::processSubGraphs()
|
||||
if( subgraph->m_absorbed )
|
||||
continue;
|
||||
|
||||
if( !subgraph->ResolveDrivers() )
|
||||
continue;
|
||||
subgraph->ResolveDrivers();
|
||||
|
||||
if( subgraph->m_driver_connection->IsBus() )
|
||||
assignNetCodesToBus( subgraph->m_driver_connection );
|
||||
@@ -1494,8 +1412,6 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
|
||||
generateInvisiblePinSubGraphs();
|
||||
|
||||
generateBusAliasMembers();
|
||||
|
||||
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
|
||||
processSubGraphs();
|
||||
|
||||
@@ -1694,7 +1610,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
// As a visual aid, we can check sheet pins that are driven by themselves to see
|
||||
// if they should be promoted to buses
|
||||
|
||||
if( subgraph->m_driver && subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
|
||||
if( subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
|
||||
{
|
||||
SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( subgraph->m_driver );
|
||||
|
||||
@@ -1773,8 +1689,6 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
const CONNECTION_SUBGRAPH* driverSubgraph = nullptr;
|
||||
wxString netclass;
|
||||
|
||||
wxCHECK_RET( !subgraphs.empty(), wxT("Invalid empty subgraph" ) );
|
||||
|
||||
for( const CONNECTION_SUBGRAPH* subgraph : subgraphs )
|
||||
{
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
@@ -1785,7 +1699,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
break;
|
||||
}
|
||||
|
||||
if( !netclass.IsEmpty() )
|
||||
if( !netclass.IsEmpty() || !driverSubgraph )
|
||||
{
|
||||
driverSubgraph = subgraph;
|
||||
break;
|
||||
@@ -1795,9 +1709,6 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
if( netclass.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( !driverSubgraph )
|
||||
driverSubgraph = subgraphs.front();
|
||||
|
||||
const wxString netname = driverSubgraph->GetNetName();
|
||||
|
||||
if( driverSubgraph->m_driver_connection->IsBus() )
|
||||
@@ -1824,30 +1735,22 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
|
||||
|
||||
int CONNECTION_GRAPH::getOrCreateNetCode( const wxString& aNetName )
|
||||
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
{
|
||||
int code;
|
||||
|
||||
auto it = m_net_name_to_code_map.find( aNetName );
|
||||
auto it = m_net_name_to_code_map.find( aConnection.Name() );
|
||||
|
||||
if( it == m_net_name_to_code_map.end() )
|
||||
{
|
||||
code = m_last_net_code++;
|
||||
m_net_name_to_code_map[ aNetName ] = code;
|
||||
m_net_name_to_code_map[ aConnection.Name() ] = code;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = it->second;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
{
|
||||
int code = getOrCreateNetCode( aConnection.Name() );
|
||||
|
||||
aConnection.SetNetCode( code );
|
||||
|
||||
return code;
|
||||
@@ -1856,7 +1759,7 @@ int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
|
||||
|
||||
void CONNECTION_GRAPH::assignNetCodesToBus( SCH_CONNECTION* aConnection )
|
||||
{
|
||||
std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->Members() );
|
||||
std::vector< std::shared_ptr<SCH_CONNECTION>>& connections_to_check( aConnection->Members() );
|
||||
|
||||
for( unsigned i = 0; i < connections_to_check.size(); i++ )
|
||||
{
|
||||
@@ -2327,7 +2230,7 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
|
||||
if( !connection->IsBus() )
|
||||
continue;
|
||||
|
||||
auto labels = subgraph->GetVectorBusLabels();
|
||||
auto labels = subgraph->GetBusLabels();
|
||||
|
||||
if( labels.size() > 1 )
|
||||
{
|
||||
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
m_graph( aGraph ),
|
||||
m_dirty( false ),
|
||||
m_absorbed( false ),
|
||||
m_is_bus_member( false ),
|
||||
m_absorbed_by( nullptr ),
|
||||
m_code( -1 ),
|
||||
m_multiple_drivers( false ),
|
||||
@@ -109,11 +108,8 @@ public:
|
||||
*/
|
||||
wxString GetNetName() const;
|
||||
|
||||
/// Returns all the vector-based bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetVectorBusLabels() const;
|
||||
|
||||
/// Returns all the all bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetAllBusLabels() const;
|
||||
/// Returns all the bus labels attached to this subgraph (if any)
|
||||
std::vector<SCH_ITEM*> GetBusLabels() const;
|
||||
|
||||
/// Returns the candidate net name for a driver
|
||||
const wxString& GetNameForDriver( SCH_ITEM* aItem ) const;
|
||||
@@ -164,12 +160,6 @@ public:
|
||||
/// True if this subgraph has been absorbed into another. No pointers here are safe if so!
|
||||
bool m_absorbed;
|
||||
|
||||
/**
|
||||
* True if the subgraph is not actually part of a net. These are created for bus members
|
||||
* to ensure that bus-to-bus connection happens but they don't have any valid data
|
||||
*/
|
||||
bool m_is_bus_member;
|
||||
|
||||
/// If this subgraph is absorbed, points to the absorbing (and valid) subgraph
|
||||
CONNECTION_SUBGRAPH* m_absorbed_by;
|
||||
|
||||
@@ -431,11 +421,6 @@ private:
|
||||
*/
|
||||
void generateInvisiblePinSubGraphs();
|
||||
|
||||
/**
|
||||
* Iterate through labels to create placeholders for bus elements
|
||||
*/
|
||||
void generateBusAliasMembers();
|
||||
|
||||
/**
|
||||
* Process all subgraphs to assign netcodes and merge subgraphs based on labels
|
||||
*/
|
||||
@@ -448,13 +433,6 @@ private:
|
||||
*/
|
||||
int assignNewNetCode( SCH_CONNECTION& aConnection );
|
||||
|
||||
/**
|
||||
*
|
||||
* @param aNetName string with the netname for coding
|
||||
* @return existing netcode (if it exists) or newly created one
|
||||
*/
|
||||
int getOrCreateNetCode( const wxString& aNetName );
|
||||
|
||||
/**
|
||||
* Ensures all members of the bus connection have a valid net code assigned
|
||||
* @param aConnection is a bus connection
|
||||
|
||||
@@ -947,10 +947,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
m_toolManager->RunAction( ACTIONS::updateSchematicFromPcb, true );
|
||||
break;
|
||||
|
||||
case MAIL_RELOAD_LIB:
|
||||
SyncView();
|
||||
break;
|
||||
|
||||
default:;
|
||||
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
|
||||
if( projSettings.m_AnnotateStartNum != startNum )
|
||||
{
|
||||
projSettings.m_AnnotateStartNum = startNum;
|
||||
schFrame->OnModify();
|
||||
schFrame->SaveProjectSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,18 +512,21 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
|
||||
|
||||
|
||||
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
SYMBOL_CHANGE_INFO>& aSymbols )
|
||||
SYMBOL_CHANGE_INFO>& aSymbols )
|
||||
{
|
||||
wxCHECK( !aSymbols.empty(), 0 );
|
||||
|
||||
int matchesProcessed = 0;
|
||||
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
wxString msg;
|
||||
SCH_SCREEN* screen = nullptr;
|
||||
LIB_SYMBOL* libSymbol = nullptr;
|
||||
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
|
||||
|
||||
wxCHECK( frame, 0 );
|
||||
|
||||
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
|
||||
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>::iterator it = symbols.begin();
|
||||
wxString msg;
|
||||
|
||||
auto it = symbols.begin();
|
||||
|
||||
// Remove all symbols that don't have a valid library symbol link or enough units to
|
||||
// satify the library symbol update.
|
||||
@@ -533,7 +536,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
|
||||
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( it->second.m_LibId );
|
||||
libSymbol = frame->GetLibSymbol( it->second.m_LibId );
|
||||
|
||||
if( !libSymbol )
|
||||
{
|
||||
@@ -559,21 +562,18 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
}
|
||||
}
|
||||
|
||||
bool appendUndo = false;
|
||||
|
||||
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
|
||||
// library symbols in the schematic file.
|
||||
for( const auto& [ symbol, symbol_change_info ] : symbols )
|
||||
{
|
||||
wxCHECK( symbol && !symbol_change_info.m_Instances.empty(), 0 );
|
||||
|
||||
SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
|
||||
wxCHECK( screen, 0 );
|
||||
|
||||
screen->Remove( symbol );
|
||||
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, appendUndo );
|
||||
appendUndo = true;
|
||||
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true );
|
||||
}
|
||||
|
||||
for( const auto& [ symbol, symbol_change_info ] : symbols )
|
||||
@@ -581,9 +581,8 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
if( symbol_change_info.m_LibId != symbol->GetLibId() )
|
||||
symbol->SetLibId( symbol_change_info.m_LibId );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
|
||||
symbol->SetLibSymbol( flattenedSymbol.release() );
|
||||
|
||||
@@ -697,6 +696,7 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
}
|
||||
|
||||
symbol->SetSchSymbolLibraryName( wxEmptyString );
|
||||
screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
screen->Append( symbol );
|
||||
frame->GetCanvas()->GetView()->Update( symbol );
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ private:
|
||||
void InstallPageSpiceModel();
|
||||
|
||||
bool TransferDataFromWindow() override;
|
||||
bool NetlistUpdateOpt();
|
||||
void NetlistUpdateOpt();
|
||||
|
||||
void updateGeneratorButtons();
|
||||
|
||||
@@ -254,7 +254,7 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType )
|
||||
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType)
|
||||
page = nullptr;
|
||||
|
||||
// Add notebook pages:
|
||||
@@ -463,35 +463,22 @@ void DIALOG_EXPORT_NETLIST::OnNetlistTypeSelection( wxNotebookEvent& event )
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
|
||||
void DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
wxString spiceCmdString = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
|
||||
bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
|
||||
bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
wxString netFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
|
||||
changed |= ( settings.m_SpiceSaveAllVoltages != saveAllVoltages );
|
||||
changed |= ( settings.m_SpiceSaveAllCurrents != saveAllCurrents );
|
||||
changed |= ( settings.m_SpiceCommandString != spiceCmdString );
|
||||
changed |= ( settings.m_SpiceCurSheetAsRoot != curSheetAsRoot );
|
||||
changed |= ( settings.m_SpiceModelCurSheetAsRoot != spiceModelCurSheetAsRoot );
|
||||
changed |= ( settings.m_NetFormatName != netFormatName );
|
||||
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spiceCmdString;
|
||||
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spiceCmdString;
|
||||
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
|
||||
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
|
||||
settings.m_NetFormatName = netFormatName;
|
||||
|
||||
return changed;
|
||||
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
}
|
||||
|
||||
|
||||
@@ -502,8 +489,7 @@ bool DIALOG_EXPORT_NETLIST::TransferDataFromWindow()
|
||||
wxString fileExt;
|
||||
wxString title = _( "Save Netlist File" );
|
||||
|
||||
if( NetlistUpdateOpt() )
|
||||
m_Parent->OnModify();
|
||||
NetlistUpdateOpt();
|
||||
|
||||
EXPORT_NETLIST_PAGE* currPage;
|
||||
currPage = (EXPORT_NETLIST_PAGE*) m_NoteBook->GetCurrentPage();
|
||||
@@ -635,8 +621,7 @@ bool DIALOG_EXPORT_NETLIST::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt
|
||||
|
||||
void DIALOG_EXPORT_NETLIST::WriteCurrentNetlistSetup()
|
||||
{
|
||||
if( NetlistUpdateOpt() )
|
||||
m_Parent->OnModify();
|
||||
NetlistUpdateOpt();
|
||||
|
||||
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( cfg );
|
||||
@@ -813,7 +798,7 @@ int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller )
|
||||
DIALOG_EXPORT_NETLIST dlg( aCaller );
|
||||
|
||||
int ret = dlg.ShowModal();
|
||||
aCaller->SaveProjectLocalSettings();
|
||||
aCaller->SaveProjectSettings();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -157,8 +157,6 @@ void DIALOG_FIELD_PROPERTIES::init()
|
||||
|
||||
// Predefined fields cannot contain some chars, or cannot be empty,
|
||||
// and need a SCH_FIELD_VALIDATOR (m_StyledTextCtrl cannot use a SCH_FIELD_VALIDATOR).
|
||||
// VALUE_FIELD does not use the validator so that it uses the Scintilla text control, since we
|
||||
// allow text replacement for this field (but not the other predefined fields)
|
||||
bool use_validator = m_fieldId == REFERENCE_FIELD
|
||||
|| m_fieldId == FOOTPRINT_FIELD
|
||||
|| m_fieldId == DATASHEET_FIELD
|
||||
@@ -191,12 +189,10 @@ void DIALOG_FIELD_PROPERTIES::init()
|
||||
"cannot be changed." ) ) );
|
||||
m_note->Show( true );
|
||||
m_TextCtrl->Enable( false );
|
||||
m_StyledTextCtrl->Enable( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TextCtrl->Enable( true );
|
||||
m_StyledTextCtrl->Enable( true );
|
||||
}
|
||||
|
||||
GetSizer()->SetSizeHints( this );
|
||||
|
||||
@@ -489,16 +489,6 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
processItem( aSheetPath, pin );
|
||||
}
|
||||
}
|
||||
else if( m_wires->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_WIRE_T,
|
||||
SCH_LABEL_LOCATE_WIRE_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( m_buses->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_BUS_T,
|
||||
SCH_LABEL_LOCATE_BUS_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( aItem->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
|
||||
{
|
||||
if( m_globalLabels->GetValue() && aItem->Type() == SCH_GLOBAL_LABEL_T )
|
||||
@@ -539,6 +529,16 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m_wires->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_WIRE_T,
|
||||
SCH_LABEL_LOCATE_WIRE_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( m_buses->GetValue() && aItem->IsType( { SCH_ITEM_LOCATE_BUS_T,
|
||||
SCH_LABEL_LOCATE_BUS_T } ) )
|
||||
{
|
||||
processItem( aSheetPath, aItem );
|
||||
}
|
||||
else if( m_schTextAndGraphics->GetValue() && aItem->IsType( { SCH_TEXT_T, SCH_TEXTBOX_T,
|
||||
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
|
||||
SCH_SHAPE_T } ) )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -79,6 +79,7 @@ DIALOG_IMAGE_PROPERTIES_BASE::DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wx
|
||||
|
||||
this->SetSizer( m_GeneralBoxSizer );
|
||||
this->Layout();
|
||||
m_GeneralBoxSizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
@@ -48,8 +47,8 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_IMAGE_PROPERTIES_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">363,281</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
|
||||
<property name="title"></property>
|
||||
<property name="tooltip"></property>
|
||||
@@ -88,7 +87,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -145,7 +143,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -234,7 +231,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -296,7 +292,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -361,7 +356,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -423,7 +417,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -485,7 +478,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
@@ -550,7 +542,6 @@
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user