diff --git a/AUTHORS.txt b/AUTHORS.txt index 00f56b44d5..a672e3242f 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -39,5 +39,6 @@ Remy Halvick, David Briscoe, Dominique Laigle, Paul Burke == Programm credits for icons and others Icons by Iņigo Zuluagaz +New Icons by Fabrizio Tappero 3D modules by Renie Marquet 3D modules by Christophe Boschat diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0bab2c5b21..54c163b4ea 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,17 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with email address. +2011-Sept-01, UPDATE Jean-Pierre Charras +================================================================================ + Add Fabrizio Tappero in contribuotors list. +Eeschema: + Graphic texts ans labels: fix fully broken undo/redo code relative to the way undo/redo command + handles changes (maintly move) for labels + Fix minor bug for undo command relative to block rotate + Remove dead code. + Add new class BITMAP_BASE, and (for Eeschema) SCH_BITMAP to handle bitmap images in schematic. + Remember plot Bitmaps in not possble with all plotters. + 2011-Aug-19, UPDATE Jean-Pierre Charras ================================================================================ diff --git a/bitmaps/CMakeLists.txt b/bitmaps/CMakeLists.txt index 0debedf015..2e5e1001f4 100644 --- a/bitmaps/CMakeLists.txt +++ b/bitmaps/CMakeLists.txt @@ -166,6 +166,7 @@ set(BITMAP_SRCS icon_pcbnew.xpm icon_txt.xpm import3d.xpm + image.xpm import_cmp_from_lib.xpm import_footprint_names.xpm import_hierarchical_label.xpm diff --git a/bitmaps/image.xpm b/bitmaps/image.xpm new file mode 100644 index 0000000000..fee77a6993 --- /dev/null +++ b/bitmaps/image.xpm @@ -0,0 +1,237 @@ +/* XPM */ +const char *image_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 215 2", +"` c Black", +"< c #EAD9C6", +"6 c #F2973F", +"_. c #D9D9D8", +"E. c #80C63D", +"D c #FCE099", +"@X c #919591", +"( c #8D832C", +"t. c #AAB2B7", +"Z. c #A9C2A2", +"f. c #AFB6B9", +"(. c #ADC5D7", +"y. c #A5ABAF", +"] c #EFD1AB", +"u. c #AAACAA", +"r c #F8B167", +"qX c #D2D2D0", +"'. c #9EC790", +") c #DEB05B", +"L c #FBD542", +"2 c #F1B97F", +"& c #D2D2D1", +"h. c #9EAAB6", +" c #FFFFFF", +"9X c #626262", +"XX c #90D94C", +"l. c #8DA1B6", +"$ c #D5D6D4", +"$X c #CBCBC9", +"m c #FAC55B", +"&. c #060502", +",X c #2E2E2E", +"X. c #3B3713", +"J. c #7C95AF", +"a c #F9AC49", +"C c #F2BD7C", +"W. c #88C54C", +"4X c #B9D2B5", +"0. c #D3D6D4", +":. c #564525", +"V c #BFC0BD", +"# c #CECFCB", +"^. c #B2D1B0", +"g c #CECFCE", +"k. c #95A6B9", +"- c #D3D3D2", +", c #E2DFD8", +"W c #FCE883", +"x. c #7A95B1", +"+ c #AEB1AC", +"' c #A4A6A1", +".X c #8AD93D", +"| c #868582", +"d c #F0BD85", +"N. c #9DDF5C", +"]. c #88C264", +"P. c #D6D7D4", +"`. c #D4DDD4", +"|. c #75D319", +"*. c #161206", +"{ c #DFD15F", +". c #675331", +"n c #FAC764", +"; c #D5D5D4", +"5X c #8EC173", +"M. c #B4D3BB", +" X c #80D62B", +"r. c #B5BDC1", +"7 c #EBD0B1", +"A c #FDE3AB", +"y c #F9B466", +"U. c #76CB26", +"<. c #8A7251", +";. c #47381B", +"t c #F9B164", +"/ c #524D1A", +"9 c #D8D9D6", +" . c #BFBFBF", +"j. c #9AA9B8", +"D. c #9FADBC", +"[ c #FCE781", +"s. c #BDC5C7", +"Q. c #8DC55A", +"d. c #BDC2C3", +"U c #C7CAC6", +"S. c #A2B1B6", +"F. c #98A9BA", +"_ c #D1D2D0", +"0 c #F0B97F", +"=. c #201909", +"9. c #D1CCC4", +"K c #FAD242", +"v c #FBCB79", +"c c #FBCE83", +"x c #FBD18E", +"3 c #F0B06F", +"6. c #816848", +"}. c #73D216", +"R. c #79C62D", +"). c #C0C0BD", +"3X c #D9DAD7", +"H c #FACF4C", +"s c #F8A93D", +"S c #FCE1A2", +"0X c #9B9E99", +"7. c #A28D6F", +"Y c #A5A6A3", +"= c #B9B9B5", +"+X c #AAAAAA", +"+. c #D2D3D0", +"oX c #ACCDB4", +"Y. c #71CF16", +"% c #D7D7D5", +"! c #FCE94F", +"N c #EFBA75", +"l c #FCD8A3", +"f c #A8AAA5", +"e. c #C1C7CA", +"* c #94948F", +"H. c #889EB5", +"~ c #CABB3F", +"1X c #ADAEAB", +"%X c #C7D8C7", +"7X c #DADBD9", +"4 c #F1A860", +"L. c #606055", +"T c #F2C48A", +"b c #FAC96E", +"C. c #ADCB98", +".. c #726A34", +"u c #F9B666", +"p c #F9B053", +"i c #F9B35D", +"=X c #75C034", +"G c #FBD361", +"Z c #FDE5B3", +"@ c #BFC1BE", +"X c #868C86", +"$. c #86712E", +": c #D8D8D6", +"c. c #708EAD", +"1 c #F0CAA4", +"-. c #362B13", +">X c #959895", +"j c #FDDFB7", +"g. c #A9B1BA", +"z. c #849BB3", +"Q c #FEFBE0", +"#X c #A9ABA8", +":X c #CFDAD0", +"K. c #AEAFAE", +"@. c #BDBEBB", +"o. c #0C0B04", +"^ c #5F581E", +"e c #F7B06A", +"> c #DBDCDA", +"*X c #81BF55", +"T. c #72CA1E", +"5. c #DBD9D4", +"i. c #939590", +"n. c #848684", +";X c #72C721", +"1. c #B3A188", +"6X c #7CB85A", +"-X c #70CA19", +"O c #9D9D99", +"p. c #9D9D9A", +"8 c #9D9D9B", +"G. c #91A4B8", +"#. c #E5D5C1", +"q c #F5B06C", +"{. c #73D116", +/* pixels */ +" . X o O + @ # $ % & * ", +" = - ; : > , < 1 2 3 4 5 6 7 8 ", +" 9 0 q w e r t y u i p a s d f ", +" g h j k l z x c v b n m M N B ", +" V C Z A S D F G H J K L P I U ", +" Y T R E W Q ! ~ ^ / ( ) _ ", +"` ' ] [ { } | ...X.o.` ` ` O.+.", +"` @.#.$.%.&.*.=.-.;.:.>.,.<.1.2.", +"3.4.5.6.7.8.9.0.q.w.e.r.t.y.u.i.", +"p.a.s.d.f.g.h.j.k.l.z.x.c.v.b.n.", +"m.M.N.B.V.C.Z.A.S.D.F.G.H.J.K.L.", +"P.I.U.Y.T.R.E.W.Q.!.~.^./.(._ ", +")._.`.'.].[.T.{.}.|. X.XXXoXOX ", +" +X@X#X$XP.%X&X*X=X-X}.;X:X>X ", +" ` ,X + + + + + + + Photos + + + + unsorted + + + + + Open Clip Art Library, Source: GNOME Icon Theme, Source: GNOME Icon Theme, Source: GNOME Icon Theme, Source: GNOME Icon Theme + + + + + Lapo Calamandrei + + + + + Lapo Calamandrei + + + 2006-06-11 + image/svg+xml + + + en + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 9be1b77a5a..b45f27b667 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,6 +11,8 @@ set( COMMON_ABOUT_DLG_SRCS dialog_about/dialog_about.cpp dialog_about/dialog_about_base.cpp dialogs/dialog_display_info_HTML_base.cpp + dialogs/dialog_image_editor.cpp + dialogs/dialog_image_editor_base.cpp dialogs/dialog_get_component.cpp dialogs/dialog_get_component_base.cpp dialogs/dialog_hotkeys_editor.cpp @@ -28,6 +30,7 @@ set(COMMON_SRCS bitmap.cpp block_commande.cpp build_version.cpp + class_bitmap_base.cpp class_colors_design_settings.cpp class_marker_base.cpp class_plotter.cpp diff --git a/common/class_bitmap_base.cpp b/common/class_bitmap_base.cpp new file mode 100644 index 0000000000..ed85fa252a --- /dev/null +++ b/common/class_bitmap_base.cpp @@ -0,0 +1,268 @@ +/********************/ +/* sch_bitmap.cpp */ +/********************/ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "fctsys.h" +#include "gr_basic.h" +#include "macros.h" +#include "class_drawpanel.h" +#include "trigo.h" +#include "common.h" +#include "richio.h" +#include "plot_common.h" + +#include "class_bitmap_base.h" + +#include + + +/**********************/ +/* class BITMAP_BASE */ +/**********************/ + +BITMAP_BASE::BITMAP_BASE( const wxPoint& pos ) +{ + m_Scale = 1.0; // 1.0 = original bitmap size + m_bitmap = NULL; + m_image = NULL; + m_pixelScaleFactor = 3.33; // a value OK for bitmaps using 300 PPI + // (Eeschema uses currently 1000PPI +} + + +BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap ) +{ + m_Scale = aSchBitmap.m_Scale; + m_pixelScaleFactor = aSchBitmap.m_pixelScaleFactor; + m_image = new wxImage( *aSchBitmap.m_image ); + m_bitmap = new wxBitmap( *m_image ); +} + + +/** + * Function ImportData + * Copy aItem image to me and update m_bitmap + */ +void BITMAP_BASE::ImportData( BITMAP_BASE* aItem ) +{ + *m_image = *aItem->m_image; + *m_bitmap = *aItem->m_bitmap; + m_Scale = aItem->m_Scale; + m_pixelScaleFactor = aItem->m_pixelScaleFactor; +} + + +bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename ) +{ + wxImage* new_image = new wxImage(); + + if( !new_image->LoadFile( aFullFilename ) ) + { + delete new_image; + return false; + } + + delete m_image; + m_image = new_image; + m_bitmap = new wxBitmap( *m_image ); + + return true; +} + + +bool BITMAP_BASE::SaveData( FILE* aFile ) const +{ + if( m_image ) + { + wxMemoryOutputStream stream; + m_image->SaveFile( stream, wxBITMAP_TYPE_PNG ); + + // Write binary data in hexadecimal form (ASCII) + wxStreamBuffer* buffer = stream.GetOutputStreamBuffer(); + char* begin = (char*) buffer->GetBufferStart(); + int ii; + for( ii = 0; begin <= buffer->GetBufferEnd(); begin++, ii++ ) + { + if( ii >= 32 ) + { + ii = 0; + if( fprintf( aFile, "\n" ) == EOF ) + return false; + } + if( fprintf( aFile, "%2.2X ", *begin & 0xFF ) == EOF ) + return false; + } + + if( fprintf( aFile, "$EndBitmap" ) == EOF ) + return false; + } + + return true; +} + + +bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg ) +{ + wxMemoryOutputStream stream; + char* line; + + while( true ) + { + if( !aLine.ReadLine() ) + return false; + + line = aLine.Line(); + if( strnicmp( line, "EndData", 4 ) == 0 ) + { + // all the PNG date is read. + // We expect here m_image and m_bitmap are void + m_image = new wxImage(); + wxMemoryInputStream istream( stream ); + m_image->LoadFile( istream, wxBITMAP_TYPE_PNG ); + m_bitmap = new wxBitmap( *m_image ); + break; + } + + // Read PNG data, stored in hexadecimal, + // each byte = 2 hexadecimal digits and a space between 2 bytes + // and put it in memory stream buffer + int len = strlen( line ); + for( ; len > 0; len -= 3, line += 3 ) + { + int value = 0; + if( sscanf( line, "%X", &value ) == 1 ) + stream.PutC( (char) value ); + else + break; + } + } + + return true; +} + + +EDA_RECT BITMAP_BASE::GetBoundingBox() const +{ + EDA_RECT rect; + + wxSize size = GetSize(); + + rect.Inflate( size.x / 2, size.y / 2 ); + + return rect; +} + + +void BITMAP_BASE::DrawBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPos ) +{ + if( m_bitmap == NULL ) + return; + + wxPoint pos = aPos; + wxSize size = GetSize(); + + // To draw the bitmap, pos is the upper left corner position + pos.x -= size.x / 2; + pos.y -= size.y / 2; + + double scale; + int logicalOriginX, logicalOriginY; + aDC->GetUserScale( &scale, &scale ); + aDC->GetLogicalOrigin( &logicalOriginX, &logicalOriginY ); + aDC->SetUserScale( scale * GetScalingFactor(), scale * GetScalingFactor() ); + aDC->SetLogicalOrigin( logicalOriginX / GetScalingFactor(), + logicalOriginY / GetScalingFactor() ); + aDC->DrawBitmap( *m_bitmap, + wxRound( pos.x / GetScalingFactor() ), + wxRound( pos.y / GetScalingFactor() ), + true ); + aDC->SetUserScale( scale, scale ); + aDC->SetLogicalOrigin( logicalOriginX, logicalOriginY ); +} + + +/* Function GetSize + * returns the actual size (in user units, not in pixels) of the image + */ +wxSize BITMAP_BASE::GetSize() const +{ + wxSize size; + + if( m_bitmap ) + { + size.x = m_bitmap->GetWidth(); + size.y = m_bitmap->GetHeight(); + + size.x = wxRound( size.x * GetScalingFactor() ); + size.y = wxRound( size.y * GetScalingFactor() ); + } + + return size; +} + + +/* + * Mirror image vertically (i.e. relative to its horizontal X axis ) + * or horizontally (i.e relative to its vertical Y axis) + * param aVertically = false to mirror horizontally + * or true to mirror vertically + */ +void BITMAP_BASE::Mirror( bool aVertically ) +{ + if( m_image ) + { + *m_image = m_image->Mirror( not aVertically ); + *m_bitmap = wxBitmap( *m_image ); + } +} + + +void BITMAP_BASE::Rotate( bool aRotateCCW ) +{ + if( m_image ) + { + *m_image = m_image->Rotate90( aRotateCCW ); + *m_bitmap = wxBitmap( *m_image ); + } +} + + +void BITMAP_BASE::PlotImage( PLOTTER* aPlotter, + wxPoint aPos, + int aDefaultColor, + int aDefaultPensize ) +{ + if( m_image == NULL ) + return; + + // These 2 lines are useful only fot plotters that cannot plot a bitmap + // and plot arectangle instead of. + aPlotter->set_color( aDefaultColor ); + aPlotter->set_current_line_width( aDefaultPensize ); + + aPlotter->PlotImage( *m_image, aPos, GetScalingFactor() ); +} diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp index db2e057c49..531fd5a254 100644 --- a/common/common_plotDXF_functions.cpp +++ b/common/common_plotDXF_functions.cpp @@ -138,6 +138,38 @@ void DXF_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, i pen_finish(); } +/* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * For DXF_PLOTTER, currently: draws a rectangle + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ +void DXF_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) +{ + wxSize size; + size.x = aImage.GetWidth(); + size.y = aImage.GetHeight(); + + size.x = wxRound( size.x * aScaleFactor ); + size.y = wxRound( size.y * aScaleFactor ); + + wxPoint start = aPos; + start.x -= size.x / 2; + start.y -= size.y / 2; + + wxPoint end = start; + end.x += size.x; + end.y += size.y; + + rect( start, end, NO_FILL ); + +} + + /* * Move the pen up (pen = 'U') or down (feather = 'D') at position x, y diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index b9958632d7..cdf2dfe077 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -333,6 +333,36 @@ void GERBER_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill } } +/* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * For GERBER_PLOTTER, draws a rectangle + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ +void GERBER_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) +{ + wxSize size; + size.x = aImage.GetWidth(); + size.y = aImage.GetHeight(); + + size.x = wxRound( size.x * aScaleFactor ); + size.y = wxRound( size.y * aScaleFactor ); + + wxPoint start = aPos; + start.x -= size.x / 2; + start.y -= size.y / 2; + + wxPoint end = start; + end.x += size.x; + end.y += size.y; + + rect( start, end, NO_FILL ); + +} /* Function flash_pad_circle * Plot a circular pad or via at the user position pos diff --git a/common/common_plotHPGL_functions.cpp b/common/common_plotHPGL_functions.cpp index d1c344efdd..2a59ae2fb4 100644 --- a/common/common_plotHPGL_functions.cpp +++ b/common/common_plotHPGL_functions.cpp @@ -97,6 +97,37 @@ void HPGL_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, pen_finish(); } +/* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * For HPGL_PLOTTER, draws a rectangle + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ +void HPGL_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) +{ + wxSize size; + size.x = aImage.GetWidth(); + size.y = aImage.GetHeight(); + + size.x = wxRound( size.x * aScaleFactor ); + size.y = wxRound( size.y * aScaleFactor ); + + wxPoint start = aPos; + start.x -= size.x / 2; + start.y -= size.y / 2; + + wxPoint end = start; + end.x += size.x; + end.y += size.y; + + rect( start, end, NO_FILL ); + +} + /* Set pen up ('U') or down ('D'). */ diff --git a/common/common_plotPS_functions.cpp b/common/common_plotPS_functions.cpp index b382483ab0..d6ba40c404 100644 --- a/common/common_plotPS_functions.cpp +++ b/common/common_plotPS_functions.cpp @@ -197,6 +197,76 @@ void PS_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, in fprintf( output_file, "poly%d\n", aFill ); } +/* + * Function PlotImage + * Only some plotters can plot image bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ +void PS_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) +{ + wxSize pix_size; // size of the bitmap in pixels + pix_size.x = aImage.GetWidth(); + pix_size.y = aImage.GetHeight(); + wxSize drawsize; // requested size of image + drawsize.x = wxRound( aScaleFactor * pix_size.x ); + drawsize.y = wxRound( aScaleFactor * pix_size.y ); + + // calculate the bottom left corner position of bitmap + wxPoint start = aPos; + start.x -= drawsize.x / 2; // left + start.y += drawsize.y / 2; // bottom (Y axis reversed) + + // calculate the top right corner position of bitmap + wxPoint end; + end.x = start.x + drawsize.x; + end.y = start.y - drawsize.y; + + fprintf( output_file, "/origstate save def\n" ); + fprintf( output_file, "/pix %d string def\n", pix_size.x ); + fprintf( output_file, "/greys %d string def\n", pix_size.x ); + + // Locate lower-left corner of image + user_to_device_coordinates( start ); + fprintf( output_file, "%d %d translate\n", start.x, start.y ); + // Map image size to device + user_to_device_coordinates( end ); + fprintf( output_file, "%d %d scale\n", + ABS(end.x - start.x), ABS(end.y - start.y)); + + // Dimensions of source image (in pixels + fprintf( output_file, "%d %d 8", pix_size.x, pix_size.y ); + // Map unit square to source + fprintf( output_file, " [%d 0 0 %d 0 %d]\n", pix_size.x, -pix_size.y , pix_size.y); + // include image data in ps file + fprintf( output_file, "{currentfile pix readhexstring pop}\n" ); + fprintf( output_file, "false 3 colorimage\n"); + // Single data source, 3 colors, Output RGB data (hexadecimal) + int jj = 0; + for( int yy = 0; yy < pix_size.y; yy ++ ) + { + for( int xx = 0; xx < pix_size.x; xx++, jj++ ) + { + if( jj >= 16 ) + { + jj = 0; + fprintf( output_file, "\n"); + } + int red, green, blue; + red = aImage.GetRed( xx, yy) & 0xFF; + green = aImage.GetGreen( xx, yy) & 0xFF; + blue = aImage.GetBlue( xx, yy) & 0xFF; + fprintf( output_file, "%2.2X%2.2X%2.2X", red, green, blue); + } + } + fprintf( output_file, "\n"); + fprintf( output_file, "origstate restore\n" ); +} + + /* Routine to draw to a new position */ diff --git a/common/dialog_about/AboutDialog_main.cpp b/common/dialog_about/AboutDialog_main.cpp index c8a589800a..179d92c602 100644 --- a/common/dialog_about/AboutDialog_main.cpp +++ b/common/dialog_about/AboutDialog_main.cpp @@ -275,6 +275,8 @@ static void InitKiCadAboutNew( AboutAppInfo& info ) /* Programm credits for icons */ info.AddArtist( new Contributor( wxT( "IÃąigo Zuluagaz" ), wxT( "inigo_zuluaga@yahoo.es" ), wxT( "Icons by" ), KiBitmapNew( edit_module_xpm ) ) ); + info.AddArtist( new Contributor( wxT( "Fabrizio Tappero" ), wxT( "fabrizio.tappero@gmail.com" ), + wxT( "New icons by" ), KiBitmapNew( edit_module_xpm ) ) ); info.AddArtist( new Contributor( wxT( "Renie Marquet" ), wxT( "reniemarquet@uol.com.br" ), wxT( "3D modules by" ), KiBitmapNew( three_d_xpm ) ) ); info.AddArtist( new Contributor( wxT( "Christophe Boschat" ), wxT( "nox454@hotmail.fr" ), diff --git a/common/dialogs/dialog_image_editor.cpp b/common/dialogs/dialog_image_editor.cpp new file mode 100644 index 0000000000..78738fa97e --- /dev/null +++ b/common/dialogs/dialog_image_editor.cpp @@ -0,0 +1,103 @@ +/** + * @file dialog_image_editor.cpp + */ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "fctsys.h" +#include "gr_basic.h" + +#include "common.h" +#include "class_drawpanel.h" + +#include "class_bitmap_base.h" + +#include "dialog_image_editor.h" + +DIALOG_IMAGE_EDITOR::DIALOG_IMAGE_EDITOR( wxWindow* aParent, BITMAP_BASE* aItem ) + : DIALOG_IMAGE_EDITOR_BASE( aParent ) +{ + m_workingImage = new BITMAP_BASE( * aItem ); + wxString msg; + msg.Printf( wxT("%f"), m_workingImage->m_Scale ); + m_textCtrlScale->SetValue( msg );; + + GetSizer()->SetSizeHints( this ); + Layout(); + Fit(); + SetMinSize( GetBestSize() ); + + Centre(); + SetFocus(); +} + +void DIALOG_IMAGE_EDITOR::OnMirrorX_click( wxCommandEvent& event ) +{ + + m_workingImage->Mirror( true ); + m_panelDraw->Refresh(); +} + +void DIALOG_IMAGE_EDITOR::OnMirrorY_click( wxCommandEvent& event ) +{ + m_workingImage->Mirror( false ); + m_panelDraw->Refresh(); +} + +void DIALOG_IMAGE_EDITOR::OnRotateClick( wxCommandEvent& event ) +{ + m_workingImage->Rotate( false ); + m_panelDraw->Refresh(); +} + +void DIALOG_IMAGE_EDITOR::OnOK_Button( wxCommandEvent& aEvent ) +{ + EndModal( wxID_OK ); +} + +void DIALOG_IMAGE_EDITOR::OnCancel_Button( wxCommandEvent& aEvent ) +{ + EndModal( wxID_CANCEL ); +} + +void DIALOG_IMAGE_EDITOR::OnRedrawPanel( wxPaintEvent& event ) +{ + wxPaintDC dc( m_panelDraw ); + wxSize size = m_panelDraw->GetClientSize(); + dc.SetDeviceOrigin( size.x/2, size.y/2 ); + + double scale = 1.0 / m_workingImage->GetScalingFactor(); + dc.SetUserScale( scale, scale ); + m_workingImage->DrawBitmap( NULL, &dc, wxPoint(0,0) ); +} + +void DIALOG_IMAGE_EDITOR::TransfertToImage(BITMAP_BASE* aItem ) +{ + wxString msg = m_textCtrlScale->GetValue(); + msg.ToDouble( &m_workingImage->m_Scale ); + m_textCtrlScale->SetValue( msg ); + aItem->ImportData( m_workingImage ); +} + diff --git a/common/dialogs/dialog_image_editor.fbp b/common/dialogs/dialog_image_editor.fbp new file mode 100644 index 0000000000..7be9af1293 --- /dev/null +++ b/common/dialogs/dialog_image_editor.fbp @@ -0,0 +1,714 @@ + + + + + + C++ + 1 + source_name + 0 + res + UTF-8 + connect + dialog_image_editor_base + 1000 + none + 1 + dialog_image_editor + + . + + 1 + 1 + 0 + 0 + + 1 + 1 + 1 + 1 + 0 + + + + + 1 + wxBOTH + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + impl_virtual + + + 1 + + 0 + 0 + wxID_ANY + + + 0 + + + 0 + + 1 + DIALOG_IMAGE_EDITOR_BASE + 1 + + + 1 + + + Resizable + + 1 + 340,256 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Image Editor + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizerMain + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bUpperSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizerLeft + wxHORIZONTAL + none + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + + 0 + + + 0 + 256,256 + 1 + m_panelDraw + 1 + + + protected + 1 + + + Resizable + + 1 + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER|wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + OnRedrawPanel + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizerRight + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Mirror X + + + 0 + + + 0 + + 1 + m_buttonMirrorX + 1 + + + protected + 1 + + + Resizable + + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnMirrorX_click + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Mirror Y + + + 0 + + + 0 + + 1 + m_buttonMirrorY + 1 + + + protected + 1 + + + Resizable + + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnMirrorY_click + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Rotate + + + 0 + + + 0 + + 1 + m_buttonRotate + 1 + + + protected + 1 + + + Resizable + + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRotateClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Image Scale: + + + 0 + + + 0 + + 1 + m_staticTextScale + 1 + + + protected + 1 + + + Resizable + + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + + 0 + + 0 + + 0 + + 1 + m_textCtrlScale + 1 + + + protected + 1 + + + Resizable + + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer1 + protected + + OnCancel_Button + + + + OnOK_Button + + + + + + + + diff --git a/common/dialogs/dialog_image_editor.h b/common/dialogs/dialog_image_editor.h new file mode 100644 index 0000000000..64592cca5e --- /dev/null +++ b/common/dialogs/dialog_image_editor.h @@ -0,0 +1,63 @@ +/** + * @file dialog_image_editor.h + */ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _DIALOG_IMAGE_EDITOR_H_ +#define _DIALOG_IMAGE_EDITOR_H_ + +#include "dialog_image_editor_base.h" + + +class DIALOG_IMAGE_EDITOR : public DIALOG_IMAGE_EDITOR_BASE +{ +private: + BITMAP_BASE* m_workingImage; + +public: + DIALOG_IMAGE_EDITOR( wxWindow* aParent, BITMAP_BASE* aItem ); + ~DIALOG_IMAGE_EDITOR(){ delete m_workingImage; } + + +public: + /** + * Function TransfertToImage + * copy edited image to aItem + * @param aItem = the target + */ + void TransfertToImage( BITMAP_BASE* aItem ); + +private: + void OnMirrorX_click( wxCommandEvent& event ); + void OnMirrorY_click( wxCommandEvent& event ); + void OnRotateClick( wxCommandEvent& event ); + void OnOK_Button( wxCommandEvent& aEvent ); + void OnCancel_Button( wxCommandEvent& aEvent ); + void OnRedrawPanel( wxPaintEvent& event ); +}; + + +#endif // _DIALOG_IMAGE_EDITOR_H_ diff --git a/common/dialogs/dialog_image_editor_base.cpp b/common/dialogs/dialog_image_editor_base.cpp new file mode 100644 index 0000000000..7b05b29e44 --- /dev/null +++ b/common/dialogs/dialog_image_editor_base.cpp @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 30 2011) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_image_editor_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_IMAGE_EDITOR_BASE::DIALOG_IMAGE_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizerMain; + bSizerMain = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bUpperSizer; + bUpperSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizerLeft; + bSizerLeft = new wxBoxSizer( wxHORIZONTAL ); + + m_panelDraw = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); + m_panelDraw->SetMinSize( wxSize( 256,256 ) ); + + bSizerLeft->Add( m_panelDraw, 1, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizerRight; + bSizerRight = new wxBoxSizer( wxVERTICAL ); + + m_buttonMirrorX = new wxButton( this, wxID_ANY, _("Mirror X"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerRight->Add( m_buttonMirrorX, 0, wxEXPAND|wxALL, 5 ); + + m_buttonMirrorY = new wxButton( this, wxID_ANY, _("Mirror Y"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerRight->Add( m_buttonMirrorY, 0, wxEXPAND|wxALL, 5 ); + + m_buttonRotate = new wxButton( this, wxID_ANY, _("Rotate"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerRight->Add( m_buttonRotate, 0, wxALL|wxEXPAND, 5 ); + + m_staticTextScale = new wxStaticText( this, wxID_ANY, _("Image Scale:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextScale->Wrap( -1 ); + bSizerRight->Add( m_staticTextScale, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlScale = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizerRight->Add( m_textCtrlScale, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + bSizerLeft->Add( bSizerRight, 0, wxEXPAND, 5 ); + + bUpperSizer->Add( bSizerLeft, 1, wxEXPAND, 5 ); + + bSizerMain->Add( bUpperSizer, 1, wxEXPAND, 5 ); + + m_sdbSizer1 = new wxStdDialogButtonSizer(); + m_sdbSizer1OK = new wxButton( this, wxID_OK ); + m_sdbSizer1->AddButton( m_sdbSizer1OK ); + m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer1->AddButton( m_sdbSizer1Cancel ); + m_sdbSizer1->Realize(); + bSizerMain->Add( m_sdbSizer1, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizerMain ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_panelDraw->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnRedrawPanel ), NULL, this ); + m_buttonMirrorX->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnMirrorX_click ), NULL, this ); + m_buttonMirrorY->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnMirrorY_click ), NULL, this ); + m_buttonRotate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnRotateClick ), NULL, this ); + m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnCancel_Button ), NULL, this ); + m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnOK_Button ), NULL, this ); +} + +DIALOG_IMAGE_EDITOR_BASE::~DIALOG_IMAGE_EDITOR_BASE() +{ + // Disconnect Events + m_panelDraw->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnRedrawPanel ), NULL, this ); + m_buttonMirrorX->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnMirrorX_click ), NULL, this ); + m_buttonMirrorY->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnMirrorY_click ), NULL, this ); + m_buttonRotate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnRotateClick ), NULL, this ); + m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnCancel_Button ), NULL, this ); + m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMAGE_EDITOR_BASE::OnOK_Button ), NULL, this ); + +} diff --git a/common/dialogs/dialog_image_editor_base.h b/common/dialogs/dialog_image_editor_base.h new file mode 100644 index 0000000000..b4e2784a2b --- /dev/null +++ b/common/dialogs/dialog_image_editor_base.h @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 30 2011) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIALOG_IMAGE_EDITOR_BASE_H__ +#define __DIALOG_IMAGE_EDITOR_BASE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_IMAGE_EDITOR_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_IMAGE_EDITOR_BASE : public wxDialog +{ + private: + + protected: + wxPanel* m_panelDraw; + wxButton* m_buttonMirrorX; + wxButton* m_buttonMirrorY; + wxButton* m_buttonRotate; + wxStaticText* m_staticTextScale; + wxTextCtrl* m_textCtrlScale; + wxStdDialogButtonSizer* m_sdbSizer1; + wxButton* m_sdbSizer1OK; + wxButton* m_sdbSizer1Cancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnRedrawPanel( wxPaintEvent& event ) { event.Skip(); } + virtual void OnMirrorX_click( wxCommandEvent& event ) { event.Skip(); } + virtual void OnMirrorY_click( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRotateClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCancel_Button( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOK_Button( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_IMAGE_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Image Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 340,256 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_IMAGE_EDITOR_BASE(); + +}; + +#endif //__DIALOG_IMAGE_EDITOR_BASE_H__ diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index f5455307d6..32a3fde814 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -3,6 +3,7 @@ add_definitions(-DEESCHEMA) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/dialogs ${CMAKE_SOURCE_DIR}/common + ${CMAKE_SOURCE_DIR}/common/dialogs ${Boost_INCLUDE_DIR} ) @@ -71,6 +72,7 @@ set(EESCHEMA_SRCS dialogs/dialog_SVG_print.cpp dialogs/dialog_SVG_print_base.cpp edit_component_in_schematic.cpp + edit_bitmap.cpp edit_label.cpp eelibs_read_libraryfiles.cpp eeredraw.cpp @@ -112,6 +114,7 @@ set(EESCHEMA_SRCS onrightclick.cpp operations_on_items_lists.cpp pinedit.cpp + sch_bitmap.cpp sch_bus_entry.cpp sch_collectors.cpp sch_component.cpp diff --git a/eeschema/edit_bitmap.cpp b/eeschema/edit_bitmap.cpp new file mode 100644 index 0000000000..3088d8a0fe --- /dev/null +++ b/eeschema/edit_bitmap.cpp @@ -0,0 +1,199 @@ +/********************/ +/* edit_bitmap.cpp */ +/********************/ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "fctsys.h" +#include "gr_basic.h" +#include "macros.h" +#include "class_drawpanel.h" +#include "trigo.h" +#include "common.h" +#include "richio.h" +#include "plot_common.h" + +#include "wxEeschemaStruct.h" +#include "general.h" +#include "sch_bitmap.h" +#include "dialog_image_editor.h" + +static void abortMoveBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) +{ + SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen(); + SCH_BITMAP* item = (SCH_BITMAP*) screen->GetCurItem(); + SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent(); + + parent->SetRepeatItem( NULL ); + + if( item == NULL ) /* no current item */ + return; + + if( item->IsNew() ) + { + delete item; + item = NULL; + } + else // Move command on an existing text item, restore the data of the original. + { + item->ClearFlags(); + + SCH_BITMAP * olditem = (SCH_BITMAP*) parent->GetUndoItem(); + + wxCHECK_RET( olditem != NULL && item->Type() == olditem->Type() && + item->Type() == SCH_BITMAP_T, + wxT( "Cannot restore undefined last text item." ) ); + + // Never delete existing item, because it can be referenced by an undo/redo command + // Just restore its data + item->SwapData(olditem); + } + + screen->SetCurItem( item ); + aPanel->Refresh(); +} + +static void moveBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) +{ + SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen(); + SCH_BITMAP* image = (SCH_BITMAP*) screen->GetCurItem(); + + if( aErase ) + { + // Erase the current bitmap at its current position. + // Note also items flagged IS_MOVING are not drawn, + // and if image is new, it is not yet il draw list + // so image is erased from screen + EDA_RECT dirty = image->GetBoundingBox(); + dirty.Inflate( 4 ); // Give a margin + aPanel->SetMouseCapture( NULL, NULL ); // Avoid loop in redraw panel + + int flgs = image->GetFlags(); + image->m_Flags = 0; + aPanel->RefreshDrawingRect( dirty ); + image->SetFlags( flgs ); + aPanel->SetMouseCapture( moveBitmap, abortMoveBitmap ); + } + + // Draw the bitmap at it's new position. + image->m_Pos = screen->GetCrossHairPosition(); + image->Draw( aPanel, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); +} + + +SCH_BITMAP* SCH_EDIT_FRAME::CreateNewImage( wxDC* aDC ) +{ + wxFileDialog fileDlg( this, _( "Choose Image" ), wxEmptyString, wxEmptyString, + _( "Image Files " ) + wxImage::GetImageExtWildcard(), + wxFD_OPEN ); + int diag = fileDlg.ShowModal(); + + if( diag != wxID_OK ) + return NULL; + + wxString fullFilename = fileDlg.GetPath(); + + if( !wxFileExists( fullFilename ) ) + { + wxMessageBox( _( "Couldn't load image from <%s>" ), GetChars( fullFilename ) ); + return NULL; + } + + wxPoint pos = GetScreen()->GetCrossHairPosition(); + + SCH_BITMAP* image = new SCH_BITMAP( pos ); + if( !image->ReadImageFile( fullFilename ) ) + { + wxMessageBox( _( "Couldn't load image from <%s>" ), GetChars( fullFilename ) ); + delete image; + return NULL; + } + + + image->SetFlags( IS_NEW | IS_MOVED ); + image->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + + DrawPanel->SetMouseCapture( moveBitmap, abortMoveBitmap ); + GetScreen()->SetCurItem( image ); + + OnModify(); + return image; +} + +void SCH_EDIT_FRAME::MoveImage( SCH_BITMAP* aImageItem, wxDC* aDC ) +{ + aImageItem->SetFlags( IS_MOVED ); + + DrawPanel->SetMouseCapture( moveBitmap, abortMoveBitmap ); + GetScreen()->SetCurItem( aImageItem ); + m_itemToRepeat = NULL; + + SetUndoItem( aImageItem ); + + DrawPanel->CrossHairOff( aDC ); + GetScreen()->SetCrossHairPosition( aImageItem->m_Pos ); + DrawPanel->MoveCursorToCrossHair(); + DrawPanel->CrossHairOn( aDC ); + + OnModify(); +} + +void SCH_EDIT_FRAME::RotateImage( SCH_BITMAP* aItem ) +{ + if( aItem->GetFlags( ) == 0 ) + SaveCopyInUndoList( aItem, UR_ROTATED, aItem->m_Pos ); + + aItem->Rotate( aItem->m_Pos ); + OnModify(); + DrawPanel->Refresh(); +} + +void SCH_EDIT_FRAME::MirrorImage( SCH_BITMAP* aItem, bool Is_X_axis ) +{ + if( aItem->GetFlags( ) == 0 ) + SaveCopyInUndoList( aItem, UR_CHANGED ); + + if( Is_X_axis ) + aItem->Mirror_X( aItem->m_Pos.y ); + else + aItem->Mirror_Y( aItem->m_Pos.x ); + + OnModify(); + DrawPanel->Refresh(); +} + +void SCH_EDIT_FRAME::EditImage( SCH_BITMAP* aItem ) +{ + // TODO: change image scale or more + DIALOG_IMAGE_EDITOR dlg( this, aItem->m_Image ); + if( dlg.ShowModal() != wxID_OK ) + return; + + if( aItem->GetFlags( ) == 0 ) + SaveCopyInUndoList( aItem, UR_CHANGED ); + dlg.TransfertToImage(aItem->m_Image); + OnModify(); + DrawPanel->Refresh(); +} diff --git a/eeschema/edit_label.cpp b/eeschema/edit_label.cpp index 9e94770c47..1de5405814 100644 --- a/eeschema/edit_label.cpp +++ b/eeschema/edit_label.cpp @@ -47,40 +47,33 @@ static void moveText( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPositio static void abortMoveText( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) { SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen(); - SCH_ITEM* item = screen->GetCurItem(); + SCH_TEXT* item = (SCH_TEXT*)screen->GetCurItem(); SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent(); parent->SetRepeatItem( NULL ); + screen->SetCurItem( NULL ); if( item == NULL ) /* no current item */ return; - // Erase the text item and delete it if new (i.e. it was being just created). - item->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode ); - if( item->IsNew() ) { delete item; item = NULL; } - else // Move command on an existing text item, restore the copy of the original. + else // Move command on an existing text item, restore the values of the original. { - screen->RemoveFromDrawList( item ); - delete item; + SCH_TEXT* olditem = (SCH_TEXT* )parent->GetUndoItem(); + screen->SetCurItem( item ); - item = parent->GetUndoItem(); - - wxCHECK_RET( item != NULL, wxT( "Cannot restore undefined last text item." ) ); - - screen->AddToDrawList( item ); - // the owner of item is no more parent, this is the draw list of screen: - parent->SetUndoItem( NULL ); - - item->Draw( aPanel, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - item->ClearFlags(); + wxCHECK_RET( olditem != NULL && item->Type() == olditem->Type(), + wxT( "Cannot restore undefined or bad last text item." ) ); + // Never delete existing item, because it can be referenced by an undo/redo command + // Just restore its data + item->SwapData(olditem); } - screen->SetCurItem( item ); + aPanel->Refresh(); } @@ -93,7 +86,7 @@ void SCH_EDIT_FRAME::MoveText( SCH_TEXT* aTextItem, wxDC* aDC ) aTextItem->SetFlags( IS_MOVED ); - SetUndoItem( (SCH_ITEM*) aTextItem ); + SetUndoItem( aTextItem ); DrawPanel->CrossHairOff( aDC ); GetScreen()->SetCrossHairPosition( aTextItem->m_Pos ); @@ -190,7 +183,14 @@ SCH_TEXT* SCH_EDIT_FRAME::CreateNewText( wxDC* aDC, int aType ) return textItem; } - +/* + * OnConvertTextType is a command event handler to change a text type to an other one. + * The new text, label, hierarchical label, or global label is created from the old text + * The old text is deleted. + * A tricky case is when the 'old" text is being edited (i.e. moving) + * because we must create a new text, and prepare the undo/redo command data for this + * change and the current move/edit command + */ void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); @@ -279,27 +279,49 @@ void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent ) screen->RemoveFromDrawList( text ); screen->AddToDrawList( newtext ); GetScreen()->SetCurItem( newtext ); + m_itemToRepeat = NULL; OnModify(); newtext->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); DrawPanel->CrossHairOn( &dc ); // redraw schematic cursor - if( text->GetFlags() == 0 ) - { - m_itemToRepeat = NULL; - text->ClearFlags(); - text->SetNext( NULL ); - text->SetBack( NULL ); - newtext->ClearFlags(); - PICKED_ITEMS_LIST pickList; - ITEM_PICKER picker( newtext, UR_EXCHANGE_T ); - picker.SetLink( text ); - pickList.PushItem( picker ); - SaveCopyInUndoList( pickList, UR_EXCHANGE_T ); - } - else + if( text->IsNew() ) { + // if the previous text is new, no undo command to prepare here + // just delete this previous text. delete text; + return; } + + // previous text is not new and we replace text by new text. + // So this is equivalent to delete text and add newtext + // If text if being currently edited (i.e. moved) + // we also save the initial copy of text, and prepare undo command for new text modifications. + // we must save it as modified text (if currently beeing edited), then deleted text, + // and replace text with newtext + PICKED_ITEMS_LIST pickList; + ITEM_PICKER picker( text, UR_CHANGED ); + if( text->GetFlags() ) + { + // text is being edited, save initial text for undo command + picker.SetLink( GetUndoItem() ); + pickList.PushItem( picker ); + // the owner of undoItem is no more "this", it is now "picker": + SetUndoItem( NULL ); + // save current newtext copy for undo/abort current command + SetUndoItem( newtext ); + } + + // Prepare undo command for delete old text + picker.m_UndoRedoStatus = UR_DELETED; + picker.SetLink( NULL ); + pickList.PushItem( picker ); + + // Prepare undo command for new text + picker.m_UndoRedoStatus = UR_NEW; + picker.SetItem(newtext); + pickList.PushItem( picker ); + + SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); } diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index 3430485f03..34a3238be5 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -49,6 +49,7 @@ enum id_eeschema_frm ID_SHEET_SYMBOL_BUTT, ID_TEXT_COMMENT_BUTT, ID_LINE_COMMENT_BUTT, + ID_ADD_IMAGE_BUTT, ID_SCHEMATIC_DELETE_ITEM_BUTT, ID_SCHEMATIC_VERTICAL_TOOLBAR_END, @@ -100,6 +101,11 @@ enum id_eeschema_frm ID_POPUP_SCH_ADD_LABEL, ID_POPUP_SCH_ADD_GLABEL, ID_POPUP_SCH_GETINFO_MARKER, + // Edit or change image orientation or context menu command IDs. + ID_POPUP_SCH_EDIT_IMAGE, + ID_POPUP_SCH_ROTATE_IMAGE, + ID_POPUP_SCH_MIRROR_X_IMAGE, + ID_POPUP_SCH_MIRROR_Y_IMAGE, ID_POPUP_END_RANGE, ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, @@ -141,8 +147,8 @@ enum id_eeschema_frm ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, // Change component orientation context menu command IDs. - ID_POPUP_SCH_MIROR_X_CMP, - ID_POPUP_SCH_MIROR_Y_CMP, + ID_POPUP_SCH_MIRROR_X_CMP, + ID_POPUP_SCH_MIRROR_Y_CMP, ID_POPUP_SCH_ROTATE_CMP_CLOCKWISE, ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE, ID_POPUP_SCH_ORIENT_NORMAL_CMP, diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 271872d3fb..bf7ccd9748 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -272,11 +272,11 @@ void SCH_EDIT_FRAME::OnChangeComponentOrientation( wxCommandEvent& aEvent ) switch( aEvent.GetId() ) { - case ID_POPUP_SCH_MIROR_X_CMP: + case ID_POPUP_SCH_MIRROR_X_CMP: orientation = CMP_MIRROR_X; break; - case ID_POPUP_SCH_MIROR_Y_CMP: + case ID_POPUP_SCH_MIRROR_Y_CMP: orientation = CMP_MIRROR_Y; break; diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp index 49ba7216bd..867ef33fe4 100644 --- a/eeschema/hotkeys.cpp +++ b/eeschema/hotkeys.cpp @@ -597,6 +597,10 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, cmd.SetId( ID_POPUP_SCH_ROTATE_FIELD ); wxPostEvent( this, cmd ); + case SCH_BITMAP_T: + cmd.SetId( ID_POPUP_SCH_ROTATE_IMAGE ); + wxPostEvent( this, cmd ); + default: ; } @@ -616,7 +620,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, if( aItem ) { screen->SetCurItem( (SCH_ITEM*) aItem ); - cmd.SetId( ID_POPUP_SCH_MIROR_Y_CMP ); + cmd.SetId( ID_POPUP_SCH_MIRROR_Y_CMP ); GetEventHandler()->ProcessEvent( cmd ); } break; @@ -634,7 +638,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, if( aItem ) { screen->SetCurItem( (SCH_ITEM*) aItem ); - cmd.SetId( ID_POPUP_SCH_MIROR_X_CMP ); + cmd.SetId( ID_POPUP_SCH_MIRROR_X_CMP ); GetEventHandler()->ProcessEvent( cmd ); } break; @@ -740,6 +744,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, case SCH_TEXT_T: case SCH_FIELD_T: case SCH_BUS_ENTRY_T: + case SCH_BITMAP_T: cmd.SetId( HK_Descr->m_IdMenuEvent ); wxPostEvent( this, cmd ); break; @@ -808,6 +813,9 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EditComponentFieldText( (SCH_FIELD*) aItem, aDC ); break; + case SCH_BITMAP_T: + EditImage( (SCH_BITMAP*) aItem ); + break; default: ; } diff --git a/eeschema/load_one_schematic_file.cpp b/eeschema/load_one_schematic_file.cpp index 02a880ce88..8d22b28400 100644 --- a/eeschema/load_one_schematic_file.cpp +++ b/eeschema/load_one_schematic_file.cpp @@ -20,6 +20,7 @@ #include "sch_polyline.h" #include "sch_text.h" #include "sch_sheet.h" +#include "sch_bitmap.h" bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window ); @@ -128,6 +129,8 @@ again." ); item = new SCH_SHEET(); else if( line[1] == 'D' ) itemLoaded = ReadSchemaDescr( &reader, MsgDiag, aScreen ); + else if( line[1] == 'B' ) + item = new SCH_BITMAP(); break; case 'L': // Its a library item. diff --git a/eeschema/onleftclick.cpp b/eeschema/onleftclick.cpp index 58fbef0e28..62570f584a 100644 --- a/eeschema/onleftclick.cpp +++ b/eeschema/onleftclick.cpp @@ -20,6 +20,7 @@ #include "sch_no_connect.h" #include "sch_component.h" #include "sch_sheet.h" +#include "sch_bitmap.h" static wxArrayString s_CmpNameList; @@ -50,6 +51,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) case SCH_JUNCTION_T: case SCH_COMPONENT_T: case SCH_FIELD_T: + case SCH_BITMAP_T: item->Place( this, aDC ); GetScreen()->SetCurItem( NULL ); GetScreen()->TestDanglingEnds(); @@ -187,6 +189,19 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) } break; + case ID_ADD_IMAGE_BUTT: + if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) + { + GetScreen()->SetCurItem( CreateNewImage( aDC ) ); + DrawPanel->m_AutoPAN_Request = true; + } + else + { + item->Place( this, aDC ); + DrawPanel->m_AutoPAN_Request = false; + } + break; + case ID_LABEL_BUTT: if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) { @@ -343,6 +358,10 @@ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) EditSchematicText( (SCH_TEXT*) item ); break; + case SCH_BITMAP_T: + EditImage( (SCH_BITMAP*) item ); + break; + case SCH_FIELD_T: EditComponentFieldText( (SCH_FIELD*) item, aDC ); DrawPanel->MoveCursorToCrossHair(); diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index d77049d769..c211c40f43 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -10,7 +10,6 @@ #include "wxEeschemaStruct.h" #include "general.h" -#include "protos.h" #include "hotkeys.h" #include "class_library.h" #include "sch_bus_entry.h" @@ -22,10 +21,9 @@ #include "sch_no_connect.h" #include "sch_sheet.h" #include "sch_sheet_path.h" +#include "sch_bitmap.h" #include -using namespace std; - static void AddMenusForBlock( wxMenu* PopMenu, SCH_EDIT_FRAME* frame ); static void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame ); @@ -39,6 +37,8 @@ static void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* GLabel ); static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ); static void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ); static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame ); +static void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap ); + /* Prepare context menu when a click on the right mouse button occurs. @@ -163,6 +163,10 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item ); break; + case SCH_BITMAP_T: + AddMenusForBitmap( PopMenu, (SCH_BITMAP*) item ); + break; + case SCH_LINE_T: switch( item->GetLayer() ) { @@ -252,9 +256,9 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) AddMenuItem( orientmenu, ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE, msg, rotate_ccw_xpm ); AddMenuItem( orientmenu, ID_POPUP_SCH_ROTATE_CMP_CLOCKWISE, _( "Rotate -" ), rotate_cw_xpm ); msg = AddHotkeyName( _( "Mirror --" ), s_Schematic_Hokeys_Descr, HK_MIRROR_X_COMPONENT ); - AddMenuItem( orientmenu, ID_POPUP_SCH_MIROR_X_CMP, msg, mirror_v_xpm ); + AddMenuItem( orientmenu, ID_POPUP_SCH_MIRROR_X_CMP, msg, mirror_v_xpm ); msg = AddHotkeyName( _( "Mirror ||" ), s_Schematic_Hokeys_Descr, HK_MIRROR_Y_COMPONENT ); - AddMenuItem( orientmenu, ID_POPUP_SCH_MIROR_Y_CMP, msg, mirror_h_xpm ); + AddMenuItem( orientmenu, ID_POPUP_SCH_MIRROR_Y_CMP, msg, mirror_h_xpm ); msg = AddHotkeyName( _( "Normal" ), s_Schematic_Hokeys_Descr, HK_ORIENT_NORMAL_COMPONENT ); AddMenuItem( orientmenu, ID_POPUP_SCH_ORIENT_NORMAL_CMP, msg, normal_xpm ); AddMenuItem( PopMenu, orientmenu, ID_POPUP_SCH_GENERIC_ORIENT_CMP, @@ -670,3 +674,30 @@ void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* AddMenuItem( aPopMenu, ID_POPUP_SCH_DELETE, _( "Delete Marker" ), delete_xpm ); AddMenuItem( aPopMenu, ID_POPUP_SCH_GETINFO_MARKER, _( "Marker Error Info" ), info_xpm ); } + +void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap ) +{ + wxString msg; + if( aBitmap->GetFlags() == 0 ) + { + msg = AddHotkeyName( _( "Move Image" ), s_Schematic_Hokeys_Descr, + HK_MOVE_COMPONENT_OR_ITEM ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_MOVE_ITEM, msg, move_xpm ); + } + + msg = AddHotkeyName( _( "Rotate Image" ), s_Schematic_Hokeys_Descr, HK_ROTATE ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_ROTATE_IMAGE, msg, rotate_ccw_xpm ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_MIRROR_X_IMAGE, + _( "Mirror --" ), mirror_v_xpm ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_MIRROR_Y_IMAGE, + _( "Mirror ||" ), mirror_h_xpm ); + + if( aBitmap->GetFlags() == 0 ) + { + msg = AddHotkeyName( _( "Edit Image" ), s_Schematic_Hokeys_Descr, HK_EDIT ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_EDIT_IMAGE, msg, image_xpm ); + aPopMenu->AppendSeparator(); + msg = AddHotkeyName( _( "Delete Image" ), s_Schematic_Hokeys_Descr, HK_DELETE ); + AddMenuItem( aPopMenu, ID_POPUP_SCH_DELETE, msg, delete_xpm ); + } +} diff --git a/eeschema/sch_bitmap.cpp b/eeschema/sch_bitmap.cpp new file mode 100644 index 0000000000..233bfd4921 --- /dev/null +++ b/eeschema/sch_bitmap.cpp @@ -0,0 +1,336 @@ +/********************/ +/* sch_bitmap.cpp */ +/********************/ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "fctsys.h" +#include "gr_basic.h" +#include "macros.h" +#include "class_drawpanel.h" +#include "trigo.h" +#include "common.h" +#include "richio.h" +#include "plot_common.h" + +#include "wxEeschemaStruct.h" +#include "general.h" +#include "sch_bitmap.h" + +#include "protos.h" + +#include + + +/* + * class SCH_BITMAP + * This class handle a bitmap image that can be inserted in a schematic. + */ + +SCH_BITMAP::SCH_BITMAP( const wxPoint& pos ) : + SCH_ITEM( NULL, SCH_BITMAP_T ) +{ + m_Pos = pos; + m_Layer = LAYER_NOTES; // used only to draw/plot a rectangle, + // when a bitmap cannot be drawn or plotted + m_Image = new BITMAP_BASE(); +} + + +SCH_BITMAP::SCH_BITMAP( const SCH_BITMAP& aSchBitmap ) : + SCH_ITEM( aSchBitmap ) +{ + m_Pos = aSchBitmap.m_Pos; + m_Layer = aSchBitmap.m_Layer; + m_Image = new BITMAP_BASE( *aSchBitmap.m_Image ); +} + + +bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename ) +{ + return m_Image->ReadImageFile( aFullFilename ); +} + + +bool SCH_BITMAP::Save( FILE* aFile ) const +{ + if( fprintf( aFile, "$Bitmap\n" ) == EOF ) + return false; + + if( fprintf( aFile, "Pos %-4d %-4d\n", m_Pos.x, m_Pos.y ) == EOF ) + return false; + + if( fprintf( aFile, "Scale %f\n", m_Image->m_Scale ) == EOF ) + return false; + + if( fprintf( aFile, "Data\n" ) == EOF ) + return false; + + if( !m_Image->SaveData( aFile ) ) + return false; + + if( fprintf( aFile, "\nEndData\n" ) == EOF ) + return false; + + + if( fprintf( aFile, "$EndBitmap\n" ) == EOF ) + return false; + + return true; +} + + +void SCH_BITMAP::Place( SCH_EDIT_FRAME* frame, wxDC* DC ) +{ + if( !IsNew() ) + { + // save old bitmap in undo list + ClearFlags(); + SCH_ITEM* undoItem = frame->GetUndoItem(); + + wxCHECK_RET( undoItem != NULL && undoItem->Type() == Type(), + wxT( "Invalid bitmap undo item." ) ); + + undoItem->ClearFlags(); + PICKED_ITEMS_LIST pickList; + ITEM_PICKER picker( this, UR_CHANGED ); + picker.SetLink( undoItem ); + + // the owner of undoItem is no more frame, this is picker: + frame->SetUndoItem( NULL ); + + pickList.PushItem( picker ); + frame->SaveCopyInUndoList( pickList, UR_CHANGED ); + } + + SCH_ITEM::Place( frame, DC ); // For new items insert in draw list and in undo list +} + + +EDA_ITEM* SCH_BITMAP::doClone() const +{ + return new SCH_BITMAP( *this ); +} + + +void SCH_BITMAP::SwapData( SCH_ITEM* aItem ) +{ + wxCHECK_RET( aItem->Type() == SCH_BITMAP_T, + wxString::Format( wxT( "SCH_BITMAP object cannot swap data with %s object." ), + GetChars( aItem->GetClass() ) ) ); + + SCH_BITMAP* item = (SCH_BITMAP*) aItem; + EXCHG( m_Pos, item->m_Pos ); + EXCHG( m_Image, item->m_Image ); +} + + +bool SCH_BITMAP::Load( LINE_READER& aLine, wxString& aErrorMsg ) +{ + char* line = aLine.Line(); + + if( strnicmp( line, "$Bitmap", 7 ) != 0 ) + { + aErrorMsg.Printf( wxT( "EESchema file bitmap image load error at line %d, aborted" ), + aLine.LineNumber() ); + aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine ); + return false; + } + + for( ; ; ) + { + if( !aLine.ReadLine() ) + return false; + + line = aLine.Line(); + + if( strnicmp( line, "Pos", 3 ) == 0 ) + { + sscanf( line + 3, "%d %d", &m_Pos.x, &m_Pos.y ); + continue; + } + + if( strnicmp( line, "Scale", 5 ) == 0 ) + { + sscanf( line + 5, "%lf", &m_Image->m_Scale ); + continue; + } + + if( strnicmp( line, "Data", 4 ) == 0 ) + { + m_Image->LoadData( aLine, aErrorMsg ); + } + + if( strnicmp( line, "$EndBitmap", 4 ) == 0 ) + break; + } + + return true; +} + + +EDA_RECT SCH_BITMAP::GetBoundingBox() const +{ + EDA_RECT rect = m_Image->GetBoundingBox(); + + rect.Move( m_Pos ); + + return rect; +} + + +void SCH_BITMAP::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, + int aDrawMode, int aColor ) +{ + wxPoint pos = m_Pos + aOffset; + + GRSetDrawMode( aDC, aDrawMode ); + + if( aColor < 0 ) // Use normal drawing function + { + m_Image->DrawBitmap( aPanel, aDC, pos ); + } + else // draws bounding box only (used to move items) + { + // To draw the rect, pos is the upper left corner position + wxSize size = m_Image->GetSize(); + pos.x -= size.x / 2; + pos.y -= size.y / 2; + GRRect( &aPanel->m_ClipBox, aDC, pos.x, pos.y, + pos.x + size.x, pos.y + size.y, 0, aColor ); + } +} + + +/* Function GetSize + * returns the actual size (in user units, not in pixels) of the image + */ +wxSize SCH_BITMAP::GetSize() const +{ + return m_Image->GetSize(); +} + + +/* + * Mirror image relative to a horizontal X axis ) + */ +void SCH_BITMAP::Mirror_X( int aXaxis_position ) +{ + m_Pos.y -= aXaxis_position; + NEGATE( m_Pos.y ); + m_Pos.y += aXaxis_position; + + m_Image->Mirror( true ); +} + + +/* + * Mirror image relative to a vertical Y axis + */ +void SCH_BITMAP::Mirror_Y( int aYaxis_position ) +{ + m_Pos.x -= aYaxis_position; + NEGATE( m_Pos.x ); + m_Pos.x += aYaxis_position; + m_Image->Mirror( false ); +} + + +void SCH_BITMAP::Rotate( wxPoint rotationPoint ) +{ + RotatePoint( &m_Pos, rotationPoint, 900 ); + m_Image->Rotate( false ); +} + + +void SCH_BITMAP::GetEndPoints( std::vector & aItemList ) +{ +} + + +bool SCH_BITMAP::IsSelectStateChanged( const wxRect& aRect ) +{ + bool previousState = IsSelected(); + + if( aRect.Contains( m_Pos ) ) + m_Flags |= SELECTED; + else + m_Flags &= ~SELECTED; + + return previousState != IsSelected(); +} + + +void SCH_BITMAP::GetConnectionPoints( vector& aPoints ) const +{ +} + + +#if defined(DEBUG) +void SCH_BITMAP::Show( int nestLevel, std::ostream& os ) +{ + // XML output: + wxString s = GetClass(); + + NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_Pos << "/>\n"; +} + + +#endif + + +bool SCH_BITMAP::doHitTest( const wxPoint& aPoint, int aAccuracy ) const +{ + EDA_RECT rect = GetBoundingBox(); + + rect.Inflate( aAccuracy ); + + return rect.Contains( aPoint ); +} + + +bool SCH_BITMAP::doHitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + EDA_RECT rect = aRect; + + rect.Inflate( aAccuracy ); + + if( aContained ) + return rect.Contains( GetBoundingBox() ); + + return rect.Intersects( GetBoundingBox() ); +} + + +bool SCH_BITMAP::doIsConnected( const wxPoint& aPosition ) const +{ + return m_Pos == aPosition; +} + + +void SCH_BITMAP::doPlot( PLOTTER* aPlotter ) +{ + m_Image->PlotImage( aPlotter, m_Pos, ReturnLayerColor( GetLayer() ), GetPenSize() ); +} diff --git a/eeschema/sch_bitmap.h b/eeschema/sch_bitmap.h new file mode 100644 index 0000000000..cde1b9690e --- /dev/null +++ b/eeschema/sch_bitmap.h @@ -0,0 +1,183 @@ +/** + * @file sch_bitmap.h + * + */ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _SCH_BITMAP_H_ +#define _SCH_BITMAP_H_ + + +#include "sch_item_struct.h" +#include "class_bitmap_base.h" + + +class SCH_BITMAP : public SCH_ITEM +{ +public: + wxPoint m_Pos; // XY coordinates of center of the bitmap + BITMAP_BASE* m_Image; // the BITMAP_BASE item + + +public: SCH_BITMAP( const wxPoint& pos = wxPoint( 0, 0 ) ); + + SCH_BITMAP( const SCH_BITMAP& aSchBitmap ); + + ~SCH_BITMAP() + { + delete m_Image; + } + + + /* + * Accessors: + */ + double GetPixelScaleFactor() { return m_Image->GetPixelScaleFactor(); } + void SetPixelScaleFactor( double aSF ) { m_Image->SetPixelScaleFactor( aSF ); } + + /** + * Function GetScalingFactor + * @return the scaling factor from pixel size to actual draw size + * this scaling factor depend on m_pixelScaleFactor and m_Scale + * m_pixelScaleFactor gives the scaling factor between a pixel size and + * the internal schematic units + * m_Scale is an user dependant value, and gives the "zoom" value + * m_Scale = 1.0 = original size of bitmap. + * m_Scale < 1.0 = the bitmap is drawn smaller than its original size. + * m_Scale > 1.0 = the bitmap is drawn bigger than its original size. + */ + double GetScalingFactor() const + { + return m_Image->GetScalingFactor(); + } + + + virtual wxString GetClass() const + { + return wxT( "SCH_BITMAP" ); + } + + + /** + * Function GetSize + * @returns the actual size (in user units, not in pixels) of the image + */ + wxSize GetSize() const; + + /** + * Function GetBoundingBox + * returns the orthogonal, bounding box of this object for display + * purposes. This box should be an enclosing perimeter for visible + * components of this object, and the units should be in the pcb or + * schematic coordinate system. It is OK to overestimate the size + * by a few counts. + */ + EDA_RECT GetBoundingBox() const; + + virtual void SwapData( SCH_ITEM* aItem ); + + virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, + int aDrawMode, int aColor = -1 ); + + virtual void Place( SCH_EDIT_FRAME* frame, wxDC* DC ); + + /** + * Function ReadImageFile + * Reads and stores an image file. Init the bitmap used to draw this item + * format. + * @param aFullFilename The full filename of the image file to read. + * @return bool - true if success reading else false. + */ + bool ReadImageFile( const wxString& aFullFilename ); + + /** + * Function Save + * writes the data structures for this object out to a FILE in "*.sch" + * format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ + bool Save( FILE* aFile ) const; + + /** + * Load schematic junction entry from \a aLine in a .sch file. + * + * @param aLine - Essentially this is file to read schematic junction from. + * @param aErrorMsg - Description of the error if an error occurs while loading the + * schematic junction. + * @return True if the schematic junction loaded successfully. + */ + virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ); + + /** + * Function Move + * moves then item to a new position by \a aMoveVector. + * @param aMoveVector The displacement vector. + */ + virtual void Move( const wxPoint& aMoveVector ) + { + m_Pos += aMoveVector; + } + + + /** + * Function Mirror_Y + * mirrors the item relative to \a aYaxis_position. + * @param aYaxis_position = the y axis position + */ + virtual void Mirror_Y( int aYaxis_position ); + + virtual void Mirror_X( int aXaxis_position ); + + virtual void Rotate( wxPoint rotationPoint ); + + virtual void GetEndPoints( std::vector & aItemList ); + + virtual bool IsSelectStateChanged( const wxRect& aRect ); + + virtual bool IsConnectable() const { return false; } + + virtual void GetConnectionPoints( vector& aPoints ) const; + + virtual wxString GetSelectMenuText() const { return wxString( _( "Image" ) ); } + + virtual BITMAP_DEF GetMenuImage() const { return image_xpm; } + + #if defined(DEBUG) + void Show( int nestLevel, std::ostream& os ); + +#endif + +private: + virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const; + virtual bool doHitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const; + virtual bool doIsConnected( const wxPoint& aPosition ) const; + virtual EDA_ITEM* doClone() const; + virtual void doPlot( PLOTTER* aPlotter ); +}; + + +#endif // _SCH_BITMAP_H_ diff --git a/eeschema/sch_collectors.cpp b/eeschema/sch_collectors.cpp index 21603bff9a..aa7c1fd0e0 100644 --- a/eeschema/sch_collectors.cpp +++ b/eeschema/sch_collectors.cpp @@ -36,6 +36,7 @@ const KICAD_T SCH_COLLECTOR::AllItems[] = { SCH_BUS_ENTRY_T, SCH_LINE_T, SCH_POLYLINE_T, + SCH_BITMAP_T, SCH_TEXT_T, SCH_LABEL_T, SCH_GLOBAL_LABEL_T, @@ -56,6 +57,7 @@ const KICAD_T SCH_COLLECTOR::AllItemsButPins[] = { SCH_BUS_ENTRY_T, SCH_LINE_T, SCH_POLYLINE_T, + SCH_BITMAP_T, SCH_TEXT_T, SCH_LABEL_T, SCH_GLOBAL_LABEL_T, @@ -77,6 +79,7 @@ const KICAD_T SCH_COLLECTOR::EditableItems[] = { SCH_COMPONENT_T, SCH_SHEET_PIN_T, SCH_SHEET_T, + SCH_BITMAP_T, EOT }; @@ -88,6 +91,7 @@ const KICAD_T SCH_COLLECTOR::MovableItems[] = { SCH_BUS_ENTRY_T, // SCH_LINE_T, SCH_POLYLINE_T, + SCH_BITMAP_T, SCH_TEXT_T, SCH_LABEL_T, SCH_GLOBAL_LABEL_T, @@ -121,6 +125,7 @@ const KICAD_T SCH_COLLECTOR::RotatableItems[] = { SCH_FIELD_T, SCH_COMPONENT_T, SCH_SHEET_T, + SCH_BITMAP_T, EOT }; @@ -139,6 +144,7 @@ const KICAD_T SCH_COLLECTOR::ParentItems[] = { SCH_COMPONENT_T, SCH_SHEET_PIN_T, SCH_SHEET_T, + SCH_BITMAP_T, EOT }; diff --git a/eeschema/sch_junction.cpp b/eeschema/sch_junction.cpp index 75953c4ddc..799895d925 100644 --- a/eeschema/sch_junction.cpp +++ b/eeschema/sch_junction.cpp @@ -39,18 +39,6 @@ SCH_JUNCTION::SCH_JUNCTION( const SCH_JUNCTION& aJunction ) : } -SCH_JUNCTION* SCH_JUNCTION::GenCopy() -{ - SCH_JUNCTION* newitem = new SCH_JUNCTION( m_Pos ); - - newitem->m_Size = m_Size; - newitem->m_Layer = m_Layer; - newitem->m_Flags = m_Flags; - - return newitem; -} - - bool SCH_JUNCTION::Save( FILE* aFile ) const { bool success = true; diff --git a/eeschema/sch_junction.h b/eeschema/sch_junction.h index dfa33cb09c..3f38258c5c 100644 --- a/eeschema/sch_junction.h +++ b/eeschema/sch_junction.h @@ -38,8 +38,6 @@ public: */ EDA_RECT GetBoundingBox() const; - SCH_JUNCTION* GenCopy(); - virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, int aDrawMode, int aColor = -1 ); diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 8a800f3185..205de2ab21 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -231,6 +231,8 @@ bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem ) void SCH_SCREEN::AddToDrawList( SCH_ITEM* aItem ) { + if( aItem == NULL ) + return; aItem->SetNext( GetDrawItems() ); SetDrawItems( aItem ); } diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 228870d015..ee040316c8 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -328,15 +328,16 @@ void SCH_TEXT::SwapData( SCH_TEXT* copyitem ) void SCH_TEXT::Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { - /* save old text in undo list */ if( !IsNew() ) { + // For existing (not new texts: save in undo list the old text: ClearFlags(); PICKED_ITEMS_LIST pickList; - ITEM_PICKER picker( this, UR_EXCHANGE_T ); + ITEM_PICKER picker( this, UR_CHANGED); //UR_EXCHANGE_T ); SCH_ITEM* undoItem = frame->GetUndoItem(); - wxCHECK_RET( undoItem != NULL, wxT( "Invalid text undo item." ) ); + wxCHECK_RET( undoItem != NULL && undoItem->Type() == Type(), + wxT( "Invalid text undo item." ) ); undoItem->ClearFlags(); picker.SetLink( undoItem ); @@ -344,7 +345,7 @@ void SCH_TEXT::Place( SCH_EDIT_FRAME* frame, wxDC* DC ) frame->SetUndoItem( NULL ); pickList.PushItem( picker ); - frame->SaveCopyInUndoList( pickList, UR_EXCHANGE_T ); + frame->SaveCopyInUndoList( pickList, UR_CHANGED); //UR_EXCHANGE_T ); } SCH_ITEM::Place( frame, DC ); @@ -385,11 +386,9 @@ void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset, GRSetDrawMode( DC, DrawMode ); wxPoint text_offset = aOffset + GetSchematicTextOffset(); - EXCHG( linewidth, m_Thickness ); // Set the minimum width EDA_TEXT::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR ); EXCHG( linewidth, m_Thickness ); // set initial value - if( m_IsDangling ) DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color ); diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index 526c02d1ca..819d51fb99 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -99,8 +99,6 @@ public: */ virtual wxPoint GetSchematicTextOffset() const; - SCH_TEXT* GenCopy(); - virtual void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset, diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index 1cca4f065a..ddc6704463 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -81,6 +81,9 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_SCH_ADD_JUNCTION: case ID_POPUP_SCH_ADD_LABEL: case ID_POPUP_SCH_GETINFO_MARKER: + case ID_POPUP_SCH_ROTATE_IMAGE: + case ID_POPUP_SCH_MIRROR_X_IMAGE: + case ID_POPUP_SCH_MIRROR_Y_IMAGE: /* At this point: Do nothing. these commands do not need to stop the * current command (mainly a block command) or reset the current state @@ -435,6 +438,26 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; + case ID_POPUP_SCH_EDIT_IMAGE: + if( item && item->GetFlags() == 0 ) + EditImage( (SCH_BITMAP*) item ); + break; + + case ID_POPUP_SCH_ROTATE_IMAGE: + if( item ) + RotateImage( (SCH_BITMAP*) item ); + break; + + case ID_POPUP_SCH_MIRROR_X_IMAGE: + if( item ) + MirrorImage( (SCH_BITMAP*) item, true ); + break; + + case ID_POPUP_SCH_MIRROR_Y_IMAGE: + if( item ) + MirrorImage( (SCH_BITMAP*) item, false ); + break; + default: // Log error: DisplayError( this, wxT( "SCH_EDIT_FRAME::Process_Special_Functions error" ) ); break; @@ -475,6 +498,10 @@ void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent ) MoveText( (SCH_TEXT*) item, &dc ); break; + case SCH_BITMAP_T: + MoveImage( (SCH_BITMAP*) item, &dc ); + break; + case SCH_COMPONENT_T: StartMovePart( (SCH_COMPONENT*) item, &dc ); break; @@ -581,6 +608,10 @@ void SCH_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) ); break; + case ID_ADD_IMAGE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add image" ) ); + break; + case ID_WIRETOBUS_ENTRY_BUTT: SetToolID( id, wxCURSOR_PENCIL, _( "Add wire to bus entry" ) ); break; diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index f0f1668c71..676779a807 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -18,6 +18,7 @@ #include "sch_component.h" #include "sch_polyline.h" #include "sch_sheet.h" +#include "sch_bitmap.h" /* Functions to undo and redo edit commands. @@ -176,6 +177,14 @@ void SwapData( EDA_ITEM* aItem, EDA_ITEM* aImage ) EXCHG( SOURCE->m_Pos, DEST->m_Pos ); break; + case SCH_BITMAP_T: + #undef SOURCE + #undef DEST + #define SOURCE ( (SCH_BITMAP*) aItem ) + #define DEST ( (SCH_BITMAP*) aImage ) + DEST->SwapData( SOURCE ); + break; + case SCH_FIELD_T: break; @@ -224,6 +233,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, case UR_NEW: case UR_WIRE_IMAGE: case UR_DELETED: + case UR_ROTATED: case UR_MOVED: commandToUndo->PushItem( itemWrapper ); break; @@ -374,8 +384,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed case UR_ROTATED: { + // To undo a rotate 90 deg transform we must rotate 270 deg to undo + // and 90 deg to redo: wxPoint RotationPoint = aList->m_TransformPoint; item->Rotate( RotationPoint ); + if( aRedoCommand ) + break; // A only one rotate transform is OK + // Make 3 rotate 90 deg transforms is this is actually an undo command item->Rotate( RotationPoint ); item->Rotate( RotationPoint ); } @@ -398,11 +413,12 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed break; case UR_EXCHANGE_T: - GetScreen()->AddToDrawList( (SCH_ITEM*) aList->GetPickedItemLink( ii ) ); + alt_item = (SCH_ITEM*) aList->GetPickedItemLink( ii ); + alt_item->SetNext( NULL ); + alt_item->SetBack( NULL ); GetScreen()->RemoveFromDrawList( item ); - item->SetNext( NULL ); - item->SetBack( NULL ); - aList->SetPickedItem( aList->GetPickedItemLink( ii ), ii ); + GetScreen()->AddToDrawList( alt_item ); + aList->SetPickedItem( alt_item, ii ); aList->SetPickedItemLink( item, ii ); break; diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index d4a781fb5f..6ddfed1d8b 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -127,7 +127,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) SCH_EDIT_FRAME::OnSelectUnit ) EVT_MENU_RANGE( ID_POPUP_SCH_CHANGE_TYPE_TEXT, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, SCH_EDIT_FRAME::OnConvertTextType ) - EVT_MENU_RANGE( ID_POPUP_SCH_MIROR_X_CMP, ID_POPUP_SCH_ORIENT_NORMAL_CMP, + EVT_MENU_RANGE( ID_POPUP_SCH_MIRROR_X_CMP, ID_POPUP_SCH_ORIENT_NORMAL_CMP, SCH_EDIT_FRAME::OnChangeComponentOrientation ) // Multple item selection context menu commands. diff --git a/eeschema/tool_sch.cpp b/eeschema/tool_sch.cpp index 7885756d56..e210e259d7 100644 --- a/eeschema/tool_sch.cpp +++ b/eeschema/tool_sch.cpp @@ -5,12 +5,12 @@ #include "fctsys.h" #include "common.h" #include "class_drawpanel.h" -#include "confirm.h" +//#include "confirm.h" #include "bitmaps.h" #include "wxEeschemaStruct.h" #include "general.h" -#include "protos.h" +//#include "protos.h" #include "hotkeys.h" #include "eeschema_id.h" @@ -217,6 +217,9 @@ void SCH_EDIT_FRAME::ReCreateVToolbar() m_VToolBar->AddTool( ID_TEXT_COMMENT_BUTT, wxEmptyString, KiBitmap( add_text_xpm ), HELP_PLACE_GRAPHICTEXTS, wxITEM_CHECK ); + m_VToolBar->AddTool( ID_ADD_IMAGE_BUTT, wxEmptyString, wxBitmap( image_xpm ), + _("Add a bitmap image"), wxITEM_CHECK ); + m_VToolBar->AddTool( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxEmptyString, KiBitmap( delete_body_xpm ), HELP_DELETE_ITEMS, wxITEM_CHECK ); diff --git a/include/base_struct.h b/include/base_struct.h index c1591f09a6..0c184b1b10 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -55,6 +55,7 @@ enum KICAD_T { SCH_BUS_ENTRY_T, SCH_LINE_T, SCH_POLYLINE_T, + SCH_BITMAP_T, SCH_TEXT_T, SCH_LABEL_T, SCH_GLOBAL_LABEL_T, diff --git a/include/bitmaps.h b/include/bitmaps.h index 8904cc244c..0351be9556 100644 --- a/include/bitmaps.h +++ b/include/bitmaps.h @@ -212,6 +212,7 @@ EXTERN_BITMAP( icon_kicad_xpm ) EXTERN_BITMAP( icon_modedit_xpm ) EXTERN_BITMAP( icon_txt_xpm ) EXTERN_BITMAP( icon_3d_xpm ) +EXTERN_BITMAP( image_xpm ) EXTERN_BITMAP( import_cmp_from_lib_xpm ) EXTERN_BITMAP( import_footprint_names_xpm ) EXTERN_BITMAP( import_hierarchical_label_xpm ) diff --git a/include/class_bitmap_base.h b/include/class_bitmap_base.h new file mode 100644 index 0000000000..6d75a100cc --- /dev/null +++ b/include/class_bitmap_base.h @@ -0,0 +1,178 @@ +/** + * @file class_bitmap_base.h + * + */ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2011 jean-pierre.charras + * Copyright (C) 2011 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _BITMAP_BASE_H_ +#define _BITMAP_BASE_H_ + + +#include "sch_item_struct.h" + +/** + * This class handle bitmap images in kicad. + * It is not intended to be used alone, but inside an other class, + * so all methods are protected ( or private ) + * It is used in SCH_BITMAP class (and other in futute) + * + * Remember not all plotters are able to plot a bitmap + * Mainly GERBER plotters cannot. + */ +class BITMAP_BASE +{ +public: + double m_Scale; // The scaling factor of the bitmap + // With m_pixelScaleFactor, controls the actual draw size +private: + wxImage* m_image; // the raw image data (png format) + wxBitmap* m_bitmap; // the bitmap used to draw/plot image + double m_pixelScaleFactor; // The scaling factor of the bitmap + // to convert the bitmap size (in pixels) + // to internal Kicad units + // Usually does not change + + +public: BITMAP_BASE( const wxPoint& pos = wxPoint( 0, 0 ) ); + + BITMAP_BASE( const BITMAP_BASE& aSchBitmap ); + + ~BITMAP_BASE() + { + delete m_bitmap; + delete m_image; + } + + + /* + * Accessors: + */ + double GetPixelScaleFactor() { return m_pixelScaleFactor; } + void SetPixelScaleFactor( double aSF ) { m_pixelScaleFactor = aSF; } + + /** + * Function ImportData + * Copy aItem image to me and update m_bitmap + */ + void ImportData( BITMAP_BASE* aItem ); + + /** + * Function GetScalingFactor + * @return the scaling factor from pixel size to actual draw size + * this scaling factor depend on m_pixelScaleFactor and m_Scale + * m_pixelScaleFactor gives the scaling factor between a pixel size and + * the internal schematic units + * m_Scale is an user dependant value, and gives the "zoom" value + * m_Scale = 1.0 = original size of bitmap. + * m_Scale < 1.0 = the bitmap is drawn smaller than its original size. + * m_Scale > 1.0 = the bitmap is drawn bigger than its original size. + */ + double GetScalingFactor() const + { + return m_pixelScaleFactor * m_Scale; + } + + + /** + * Function GetSize + * @returns the actual size (in user units, not in pixels) of the image + */ + wxSize GetSize() const; + + /** + * Function GetBoundingBox + * returns the orthogonal, bounding box of this object for display + * purposes. This box should be an enclosing perimeter for visible + * components of this object, and the units should be in the pcb or + * schematic coordinate system. It is OK to overestimate the size + * by a few counts. + */ + EDA_RECT GetBoundingBox() const; + + void DrawBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPos ); + + /** + * Function ReadImageFile + * Reads and stores an image file. Init the bitmap used to draw this item + * format. + * supported images formats are format supported by wxImage + * if all handlers are loaded + * by default, .png, .jpeg are alway loaded + * @param aFullFilename The full filename of the image file to read. + * @return bool - true if success reading else false. + */ + bool ReadImageFile( const wxString& aFullFilename ); + + /** + * Function + * writes the bitmap data to aFile + * The format is png, in Hexadecimal form: + * If the hexadecimal data is converted to binary it gives exactly a .png image data + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ + bool SaveData( FILE* aFile ) const; + + /** + * Load an image data saved by SaveData (png, in Hexadecimal form) + * @param aLine - Essentially this is file to read schematic junction from. + * @param aErrorMsg - Description of the error if an error occurs while loading the + * png bimap data. + * @return true if the bitmap loaded successfully. + */ + bool LoadData( LINE_READER& aLine, wxString& aErrorMsg ); + + + /** + * Function Mirror + * Mirror image vertically (i.e. relative to its horizontal X axis ) + * or horizontally (i.e relative to its vertical Y axis) + * @param aVertically = false to mirror horizontally + * or true to mirror vertically + */ + void Mirror( bool aVertically ); + + /** + * Function Rotate + * Rotate image CW or CCW. + * @param aRotateCCW = true to rotate CCW + */ + void Rotate( bool aRotateCCW ); + + /** + * Function PlotImage + * Plot bitmap on plotter. + * If the plotter does not support bitmaps, plot a + * @param aPlotter = the plotter to use + * @param aPos = the position od the center of the bitmap + * @param aDefaultColor = the color used to plot the rectangle when bitmap is not supported + * @param aDefaultPensize = the pen size used to plot the rectangle when bitmap is not supported + */ + void PlotImage( PLOTTER* aPlotter, wxPoint aPos, int aDefaultColor, int aDefaultPensize ); +}; + + +#endif // _BITMAP_BASE_H_ diff --git a/include/pad_shapes.h b/include/pad_shapes.h index 6de1c67104..c0a7f3acef 100644 --- a/include/pad_shapes.h +++ b/include/pad_shapes.h @@ -21,9 +21,9 @@ #define PAD_STANDARD 0 // Usual pad #define PAD_SMD 1 // Smd pad, appears on the layer paste (default) #define PAD_CONN 2 // Like smd, does not appear on the layer paste (default) - -// reserved, but not yet really used: -#define PAD_HOLE_NOT_PLATED 3 // like PAD_STANDARD, but not plated (no connection between copper layers) +#define PAD_HOLE_NOT_PLATED 3 // like PAD_STANDARD, but not plated + // mechanical used only + // no connection allowed #endif /* #ifndef PAD_SHAPES_H_ */ diff --git a/include/plot_common.h b/include/plot_common.h index 67006003f9..41aa46b316 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -108,6 +108,18 @@ public: PLOTTER( PlotFormat aPlotType ); */ virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1 ) = 0; + /** + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * @brief Draw an image bitmap + * @param aImage = the bitmap + * @param aPos = position of the center of the bitmap + * @param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ + virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) = 0; + virtual void thick_segment( wxPoint start, wxPoint end, int width, GRTraceMode tracemode ); virtual void thick_arc( wxPoint centre, int StAngle, int EndAngle, int rayon, @@ -278,6 +290,18 @@ public: HPGL_PLOTTER() : PLOTTER( PLOT_FORMAT_HPGL ) */ virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1); + /* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * Draw an image bitmap + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ + virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ); + virtual void thick_segment( wxPoint start, wxPoint end, int width, GRTraceMode tracemode ); virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon, @@ -342,6 +366,18 @@ public: PS_PLOTTER() : PLOTTER( PLOT_FORMAT_POST ) */ virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1); + /* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * Draw an image bitmap + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ + virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ); + virtual void pen_to( wxPoint pos, char plume ); virtual void flash_pad_circle( wxPoint pos, int diametre, GRTraceMode trace_mode ); @@ -409,6 +445,18 @@ public: GERBER_PLOTTER() : PLOTTER( PLOT_FORMAT_GERBER ) */ virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1); + /* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * Draw an image bitmap + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ + virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ); + virtual void pen_to( wxPoint pos, char plume ); virtual void flash_pad_circle( wxPoint pos, int diametre, GRTraceMode trace_mode ); @@ -477,6 +525,18 @@ public: DXF_PLOTTER() : PLOTTER( PLOT_FORMAT_DXF ) */ virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1 ); + /* + * Function PlotImage + * Only Postscript plotters can plot bitmaps + * for plotters that cannot plot a bitmap, a rectangle is plotted + * Draw an image bitmap + * param aImage = the bitmap + * param aPos = position of the center of the bitmap + * param aScaleFactor = the scale factor to apply to the bitmap size + * (this is not the plot scale factor) + */ + virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ); + virtual void thick_segment( wxPoint start, wxPoint end, int width, GRTraceMode tracemode ); virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon, diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index ccf7789a72..945203ac4d 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -26,6 +26,7 @@ class EDA_ITEM; class SCH_BUS_ENTRY; class SCH_GLOBALLABEL; class SCH_TEXT; +class SCH_BITMAP; class SCH_SHEET; class SCH_SHEET_PATH; class SCH_SHEET_PIN; @@ -647,6 +648,20 @@ private: void Delete_Drawings_All_Layer( DRAWSEGMENT* Segment, wxDC* DC ); DRAWSEGMENT* Begin_Edge( DRAWSEGMENT* Segment, wxDC* DC ); + // Images: + SCH_BITMAP* CreateNewImage( wxDC* aDC ); + void MoveImage( SCH_BITMAP* aItem, wxDC* aDC ); + void RotateImage( SCH_BITMAP* aItem ); + /** + * Function MirrorImage + * Mirror a bitmap + * @param aItem = the SCH_BITMAP item to mirror + * @param Is_X_axis = true to mirror relative to Horizontal axis + * false to mirror relative to vertical axis + */ + void MirrorImage( SCH_BITMAP* aItem, bool Is_X_axis ); + void EditImage( SCH_BITMAP* aItem ); + // Hierarchical Sheet & PinSheet void InstallHierarchyFrame( wxDC* DC, wxPoint& pos ); SCH_SHEET* CreateSheet( wxDC* DC );