From cf7a7e133be36522ec3afd0417f1d2bd860b4f6c Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Thu, 3 Sep 1998 21:46:47 +0000 Subject: [PATCH] It's possible now to save to a PNG. OK, I still have performance problems, but it's a start. Updated install.txt. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@662 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/gtk/install.txt | 53 ++++++++++++++------ include/wx/gtk/bitmap.h | 2 +- include/wx/gtk/dc.h | 2 +- include/wx/gtk1/bitmap.h | 2 +- include/wx/gtk1/dc.h | 2 +- samples/png/pngdemo.cpp | 29 +++++++++++ samples/png/pngdemo.h | 2 + src/gtk/bitmap.cpp | 101 ++++++++++++++++++++++++++++++++++++++- src/gtk/dc.cpp | 6 +++ src/gtk/dcclient.cpp | 68 ++++++++++++++++++-------- src/gtk/dcmemory.cpp | 14 ++++++ src/gtk/menu.cpp | 40 +++++++++++++++- src/gtk1/bitmap.cpp | 101 ++++++++++++++++++++++++++++++++++++++- src/gtk1/dc.cpp | 6 +++ src/gtk1/dcclient.cpp | 68 ++++++++++++++++++-------- src/gtk1/dcmemory.cpp | 14 ++++++ src/gtk1/menu.cpp | 40 +++++++++++++++- 17 files changed, 487 insertions(+), 63 deletions(-) diff --git a/docs/gtk/install.txt b/docs/gtk/install.txt index 24286b8abf..0eb9f235a2 100644 --- a/docs/gtk/install.txt +++ b/docs/gtk/install.txt @@ -4,11 +4,20 @@ If you compile wxWindows on Unix for the first time and don't like to read install instructions just do (in the base dir): -./configure --with-gtk --with-shared --without-threads +./configure --without-threads make -and drink 10 coffees. +and drink 10 coffees. Then you may log in as root and type +make install + +You can leave out the --without-threads option if you have a NEW +Linux distribution based on glibc (e.g. RedHat 5.1) or any other +Unix that comes with Posix threads or SGI threads. + +Now create your super-application myfoo.app and compile anywhere with + +gcc -o -c myfoo.cpp -I/usr/local/include -L/usr/local/lib -lwx_gtk * General ----------------------- @@ -141,8 +150,10 @@ not been defined. And Make in some circumstances as well... * General options ------------------- -Obviously, you have to choose a toolkit. You must do this by -running configure with either of +Normally, you won't have to choose a toolkit, because when +you download wxGTK, it will default to --with-gtk etc. But +if you use all of our CVS repository you have to choose a +toolkit. You must do this by running configure with either of: --with-gtk Use the GIMP ToolKit (GTK) @@ -155,7 +166,7 @@ The following options handle the kind of library you want to build. --without-threads Compile without thread support. - --with-shared Create shared libraries. + --without-shared Do not create shared libraries. --without-optimise Do not optimise the code. @@ -191,25 +202,21 @@ implemented. ------------- The following must be done in the base directory (e.g. ~/wxGTK -or ~/wxWin) - -First you have to create all makefiles in all subdirectories: - - make Makefiles +or ~/wxWin or whatever) Dependencies are generated automatically using make depend -(For some reason, this doesn't seem to work completely.) +(For some reason, this doesn't seem to work.) Now the makefiles are created you can compile everything is as simple as typing: make -make yourself some coffee, as it will try to compile -ALL the files in this distribution. +make yourself some coffee, as it will try to compile ALL the +files in this distribution. if you want to be more selective: @@ -219,6 +226,13 @@ if you want to be more selective: make other will build the other samples make user will build the files in the directory other +Then you may install the library and it's header files under +/usr/local/include/wx and /usr/local/lib respectively. You +have to log in as root (i.e. run "su" and enter the root +password) and type + + make install + Depending on the configuration of some files, the libraries and binaries will be placed in different directories. The "global" binaries and libraries will be placed in: @@ -242,8 +256,10 @@ will do the work for you. * Creating a new Project -------------------------- -I propose to put all contributed programs in the directory -"~/wxWin/user", with a directory of its own. +There are two ways to create your own project. The first creates +a project within the source code directories of wxWindows: In this +case I propose to put all contributed programs in the directory +"/user", with a directory of its own. This directory then should include the following files: @@ -258,6 +274,13 @@ Makefile.in (This is the base application-Makefile template, from put ALL your source code along with all the other stuff you need for your application in this directory (subdirectories are welcome). +The other way uses the installed libraries and header files in +/usr/local/include/wx and /usr/local/lib. In this case, just +compile your program like this: + +gcc -o -c myfoo.cpp -I/usr/local/include -L/usr/local/lib -lwx_gtk + + ** Something about Makefiles ------------------------------ diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index 18f13ad7e3..dcf1d23268 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -131,7 +131,7 @@ class wxBitmap: public wxObject GdkPixmap *GetPixmap() const; GdkBitmap *GetBitmap() const; - + void DestroyImage(); void RecreateImage(); void Render(); diff --git a/include/wx/gtk/dc.h b/include/wx/gtk/dc.h index 683413cd67..2e3fe8290e 100644 --- a/include/wx/gtk/dc.h +++ b/include/wx/gtk/dc.h @@ -66,7 +66,7 @@ class wxDC: public wxObject void BeginDrawing(void) {}; void EndDrawing(void) {}; - virtual bool Ok(void) const { return m_ok; }; + virtual bool Ok(void) const; virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0; virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0; diff --git a/include/wx/gtk1/bitmap.h b/include/wx/gtk1/bitmap.h index 18f13ad7e3..dcf1d23268 100644 --- a/include/wx/gtk1/bitmap.h +++ b/include/wx/gtk1/bitmap.h @@ -131,7 +131,7 @@ class wxBitmap: public wxObject GdkPixmap *GetPixmap() const; GdkBitmap *GetBitmap() const; - + void DestroyImage(); void RecreateImage(); void Render(); diff --git a/include/wx/gtk1/dc.h b/include/wx/gtk1/dc.h index 683413cd67..2e3fe8290e 100644 --- a/include/wx/gtk1/dc.h +++ b/include/wx/gtk1/dc.h @@ -66,7 +66,7 @@ class wxDC: public wxObject void BeginDrawing(void) {}; void EndDrawing(void) {}; - virtual bool Ok(void) const { return m_ok; }; + virtual bool Ok(void) const; virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0; virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0; diff --git a/samples/png/pngdemo.cpp b/samples/png/pngdemo.cpp index edbaea70a2..d97f4058dd 100644 --- a/samples/png/pngdemo.cpp +++ b/samples/png/pngdemo.cpp @@ -52,6 +52,7 @@ bool MyApp::OnInit(void) wxMenu *help_menu = new wxMenu; file_menu->Append(PNGDEMO_LOAD_FILE, "&Load file", "Load file"); + file_menu->Append(PNGDEMO_SAVE_FILE, "&Save file", "Save file"); file_menu->Append(PNGDEMO_QUIT, "E&xit", "Quit program"); help_menu->Append(PNGDEMO_ABOUT, "&About", "About PNG demo"); @@ -80,6 +81,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(PNGDEMO_QUIT, MyFrame::OnQuit) EVT_MENU(PNGDEMO_ABOUT, MyFrame::OnAbout) EVT_MENU(PNGDEMO_LOAD_FILE, MyFrame::OnLoadFile) + EVT_MENU(PNGDEMO_SAVE_FILE, MyFrame::OnSaveFile) END_EVENT_TABLE() // Define my frame constructor @@ -100,6 +102,33 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) "About PNG Demo", wxOK); } +void MyFrame::OnSaveFile(wxCommandEvent& WXUNUSED(event)) +{ + char *f = wxFileSelector( "Save Image", (const char *)NULL, (const char *)NULL, + "png", "PNG files (*.png)|*.png" ); + + if (!f) return; + + wxBitmap *backstore = new wxBitmap( 150, 150 ); + + wxMemoryDC memDC; + memDC.SelectObject( *backstore ); + memDC.Clear(); + memDC.SetBrush( *wxBLACK_BRUSH ); + memDC.SetPen( *wxWHITE_PEN ); + memDC.DrawRectangle( 0, 0, 150, 150 ); + memDC.SetPen( *wxBLACK_PEN ); + memDC.DrawLine( 0, 0, 0, 10 ); + memDC.SetTextForeground( *wxWHITE ); + memDC.DrawText( "This is a memory dc.", 10, 10 ); + + memDC.SelectObject( wxNullBitmap ); + + backstore->SaveFile( f, wxBITMAP_TYPE_PNG, (wxPalette*)NULL ); + + delete backstore; +} + void MyFrame::OnLoadFile(wxCommandEvent& WXUNUSED(event)) { // Show file selector. diff --git a/samples/png/pngdemo.h b/samples/png/pngdemo.h index e4be03ed4b..eef3432f11 100644 --- a/samples/png/pngdemo.h +++ b/samples/png/pngdemo.h @@ -35,6 +35,7 @@ class MyFrame: public wxFrame bool OnClose(void); void OnActivate(bool) {} void OnLoadFile(wxCommandEvent& event); + void OnSaveFile(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); DECLARE_EVENT_TABLE() @@ -54,4 +55,5 @@ DECLARE_EVENT_TABLE() #define PNGDEMO_QUIT 100 #define PNGDEMO_ABOUT 101 #define PNGDEMO_LOAD_FILE 102 +#define PNGDEMO_SAVE_FILE 103 diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp index b06f111e55..e4adea4dd1 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -17,7 +17,12 @@ #include "gdk/gdkprivate.h" #ifdef USE_GDK_IMLIB + #include "../gdk_imlib/gdk_imlib.h" +#include "gdk/gdkx.h" // GDK_DISPLAY +#include +#include + #endif //----------------------------------------------------------------------------- @@ -223,7 +228,8 @@ bool wxBitmap::operator != ( const wxBitmap& bmp ) bool wxBitmap::Ok(void) const { - return m_refData != NULL; + wxASSERT_MSG( m_refData != NULL, "invalid bitmap" ); + return (m_refData != NULL); } int wxBitmap::GetHeight(void) const @@ -247,18 +253,27 @@ int wxBitmap::GetDepth(void) const void wxBitmap::SetHeight( int height ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetHeight not implemented" ); + M_BMPDATA->m_height = height; } void wxBitmap::SetWidth( int width ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetWidth not implemented" ); + M_BMPDATA->m_width = width; } void wxBitmap::SetDepth( int depth ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetDepth not implemented" ); + M_BMPDATA->m_bpp = depth; } @@ -274,6 +289,7 @@ void wxBitmap::SetMask( wxMask *mask ) if (!Ok()) return; if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask; + M_BMPDATA->m_mask = mask; } @@ -298,6 +314,10 @@ void wxBitmap::Resize( int height, int width ) Render(); +#else + + wxFAIL_MSG( "wxBitmap::Resize not implemented without GdkImlib" ); + #endif } @@ -312,6 +332,10 @@ bool wxBitmap::SaveFile( const wxString &name, int WXUNUSED(type), return gdk_imlib_save_image( M_BMPDATA->m_image, WXSTRINGCAST name, (GdkImlibSaveInfo *) NULL ); +#else + + wxFAIL_MSG( "wxBitmap::SaveFile not implemented without GdkImlib" ); + #endif return FALSE; @@ -338,6 +362,11 @@ bool wxBitmap::LoadFile( const wxString &name, int WXUNUSED(type) ) M_BMPDATA->m_bpp = 24; // ? return TRUE; + +#else + + wxFAIL_MSG( "wxBitmap::LoadFile not implemented without GdkImlib" ); + #endif return FALSE; @@ -352,6 +381,9 @@ wxPalette *wxBitmap::GetPalette(void) const GdkPixmap *wxBitmap::GetPixmap(void) const { if (!Ok()) return (GdkPixmap *) NULL; + +// if (!M_BMPDATA->m_image) RecreateImage(); + return M_BMPDATA->m_pixmap; } @@ -375,6 +407,53 @@ void wxBitmap::DestroyImage(void) void wxBitmap::RecreateImage(void) { + if (!Ok()) return; + +#ifdef USE_GDK_IMLIB + + DestroyImage(); + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" ); + + long size = (long)(M_BMPDATA->m_width)*(long)(M_BMPDATA->m_height)*(long)3; + unsigned char *data = new unsigned char[size]; + for (long i = 0; i < size; i++) data[i] = 100; + + GdkImage *image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height ); + + long pos = 0; + for (int j = 0; j < M_BMPDATA->m_height; j++) + { + for (int i = 0; i < M_BMPDATA->m_width; i++) + { + XColor xcol; + xcol.pixel = gdk_image_get_pixel( image, i, j ); + Colormap cm = ((GdkColormapPrivate*)gdk_imlib_get_colormap())->xcolormap; + XQueryColor( gdk_display, cm, &xcol ); + + data[pos] = xcol.red; + data[pos+1] = xcol.green; + data[pos+2] = xcol.blue; + pos += 3; + } + } + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" ); + + M_BMPDATA->m_image = gdk_imlib_create_image_from_data( + data, (unsigned char*)NULL, M_BMPDATA->m_width, M_BMPDATA->m_height ); + + delete[] data; + + gdk_image_destroy( image ); + + Render(); + +#else + + wxFAIL_MSG( "wxBitmap::RecreateImage not implemented without GdkImlib" ); + +#endif } void wxBitmap::Render(void) @@ -383,10 +462,26 @@ void wxBitmap::Render(void) #ifdef USE_GDK_IMLIB + if (!M_BMPDATA->m_image) RecreateImage(); + + if (M_BMPDATA->m_pixmap) + { + gdk_imlib_free_pixmap( M_BMPDATA->m_pixmap ); + M_BMPDATA->m_pixmap = (GdkPixmap*) NULL; + } + if (M_BMPDATA->m_mask) + { + delete M_BMPDATA->m_mask; + M_BMPDATA->m_mask = (wxMask*) NULL; + } + gdk_imlib_render( M_BMPDATA->m_image, M_BMPDATA->m_image->rgb_width, M_BMPDATA->m_image->rgb_height ); M_BMPDATA->m_width = M_BMPDATA->m_image->rgb_width; M_BMPDATA->m_height = M_BMPDATA->m_image->rgb_height; M_BMPDATA->m_pixmap = gdk_imlib_move_image( M_BMPDATA->m_image ); + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "pixmap rendering failed" ) + GdkBitmap *mask = gdk_imlib_move_mask( M_BMPDATA->m_image ); if (mask) { @@ -394,6 +489,10 @@ void wxBitmap::Render(void) M_BMPDATA->m_mask->m_bitmap = mask; } +#else + + wxFAIL_MSG( "wxBitmap::Render not implemented without GdkImlib" ); + #endif } diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index ff6f369904..a7c77998bc 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -83,6 +83,12 @@ wxDC::~wxDC(void) { } +bool wxDC::Ok(void) const +{ + wxASSERT_MSG( !ok, "invalid display context" ); + return m_ok; +} + void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), double WXUNUSED(xc), double WXUNUSED(yc) ) { diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index ca39cfbb84..70bd684c16 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -124,10 +124,12 @@ wxPaintDC::~wxPaintDC(void) void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col), int WXUNUSED(style) ) { + wxFAIL_MSG( "wxPaintDC::FloodFill not implemented" ); } bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const { + wxFAIL_MSG( "wxPaintDC::GetPixel not implemented" ); return FALSE; } @@ -135,6 +137,8 @@ void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) { gdk_draw_line( m_window, m_penGC, @@ -146,6 +150,8 @@ void wxPaintDC::CrossHair( long x, long y ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) { int w = 0; @@ -164,6 +170,8 @@ void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double y { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx1 = XLOG2DEV(x1); long yy1 = YLOG2DEV(y1); long xx2 = XLOG2DEV(x2); @@ -212,6 +220,8 @@ void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -234,6 +244,8 @@ void wxPaintDC::DrawPoint( long x, long y ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) ); } @@ -242,6 +254,8 @@ void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() == wxTRANSPARENT) return; for (int i = 0; i < n-1; i++) @@ -258,6 +272,8 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() == wxTRANSPARENT) return; wxNode *node = points->First(); @@ -274,10 +290,12 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) } } -void wxPaintDC::DrawPolygon( int n, wxPoint points[], - long xoffset, long yoffset, int WXUNUSED(fillStyle) ) - { - if (!Ok()) return; +void wxPaintDC::DrawPolygon( int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle) ) +{ + if (!Ok()) return; + + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (!n) return; // Nothing to draw GdkPoint *gdkpoints = new GdkPoint[n+1]; int i; @@ -299,12 +317,13 @@ void wxPaintDC::DrawPolygon( int n, wxPoint points[], delete[] gdkpoints; } -void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, - long yoffset, int WXUNUSED(fillStyle)) - { +void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, long yoffset, int WXUNUSED(fillStyle)) +{ + if (!Ok()) return; + + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + int n = lines->Number(); - - if (!Ok()) return; GdkPoint *gdkpoints = new GdkPoint[n]; wxNode *node = lines->First(); int cnt=0; @@ -336,6 +355,8 @@ void wxPaintDC::DrawRectangle( long x, long y, long width, long height ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -359,6 +380,8 @@ void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, d { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (radius < 0.0) radius = - radius * ((width < height) ? width : height); long xx = XLOG2DEV(x); @@ -424,6 +447,8 @@ void wxPaintDC::DrawEllipse( long x, long y, long width, long height ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -451,6 +476,8 @@ void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask ) if (!icon.Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -478,21 +505,22 @@ bool wxPaintDC::Blit( long xdest, long ydest, long width, long height, { if (!Ok()) return FALSE; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + // CMB 20/5/98: add blitting of bitmaps if (source->IsKindOf(CLASSINFO(wxMemoryDC))) { wxMemoryDC* srcDC = (wxMemoryDC*)source; - GdkBitmap* bmap = srcDC->m_selected.GetBitmap(); + GdkBitmap* bmap = srcDC->m_selected.GetBitmap(); if (bmap) { - gdk_draw_bitmap ( - m_window, - m_textGC, - bmap, - source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc), - XLOG2DEV(xdest), YLOG2DEV(ydest), - source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height) - ); + gdk_draw_bitmap( m_window, m_textGC, bmap, + source->DeviceToLogicalX(xsrc), + source->DeviceToLogicalY(ysrc), + XLOG2DEV(xdest), + YLOG2DEV(ydest), + source->DeviceToLogicalXRel(width), + source->DeviceToLogicalYRel(height) ); return TRUE; } } @@ -519,6 +547,8 @@ void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(us { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + GdkFont *font = m_font.GetInternalFont( m_scaleY ); x = XLOG2DEV(x); @@ -588,7 +618,7 @@ void wxPaintDC::Clear(void) { if (!Ok()) return; -// DestroyClippingRegion(); + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); if (m_isDrawable) { diff --git a/src/gtk/dcmemory.cpp b/src/gtk/dcmemory.cpp index 5a6e982f9e..4b19f89c29 100644 --- a/src/gtk/dcmemory.cpp +++ b/src/gtk/dcmemory.cpp @@ -14,6 +14,10 @@ #include "wx/dcmemory.h" +#ifdef USE_GDK_IMLIB +#include "../gdk_imlib/gdk_imlib.h" +#endif + //----------------------------------------------------------------------------- // wxMemoryDC //----------------------------------------------------------------------------- @@ -23,13 +27,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC) wxMemoryDC::wxMemoryDC(void) { m_ok = FALSE; + +#ifdef USE_GDK_IMLIB + m_cmap = gdk_imlib_get_colormap(); +#else m_cmap = gdk_colormap_get_system(); +#endif } wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) ) { m_ok = FALSE; + +#ifdef USE_GDK_IMLIB + m_cmap = gdk_imlib_get_colormap(); +#else m_cmap = gdk_colormap_get_system(); +#endif } wxMemoryDC::~wxMemoryDC(void) diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index fad9d5bb8e..9465c44a37 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -150,7 +150,7 @@ bool wxMenuBar::Enabled( int id ) const } //----------------------------------------------------------------------------- -// wxMenu +// "activate" //----------------------------------------------------------------------------- static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) @@ -161,7 +161,35 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (!menu->IsEnabled(id)) return; - wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id ); + wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, id ); + event.SetEventObject( menu ); + event.SetInt(id ); + + if (menu->m_callback) + { + (void) (*(menu->m_callback)) (*menu, event); + return; + } + + if (menu->GetEventHandler()->ProcessEvent(event)) return; + + wxWindow *win = menu->GetInvokingWindow(); + if (win) win->GetEventHandler()->ProcessEvent( event ); +} + +//----------------------------------------------------------------------------- +// "select" +//----------------------------------------------------------------------------- + +static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) +{ + int id = menu->FindMenuIdByMenuItem(widget); + + wxASSERT( id != -1 ); // should find it! + + if (!menu->IsEnabled(id)) return; + + wxCommandEvent event( wxEVT_MENU_HIGHLIGHT, id ); event.SetEventObject( menu ); event.SetInt(id ); @@ -177,6 +205,10 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (win) win->GetEventHandler()->ProcessEvent( event ); } +//----------------------------------------------------------------------------- +// wxMenu +//----------------------------------------------------------------------------- + IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject) wxMenuItem::wxMenuItem() @@ -283,6 +315,10 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(menuItem), "select", + GTK_SIGNAL_FUNC(gtk_menu_hilight_callback), + (gpointer*)this ); + gtk_menu_append( GTK_MENU(m_menu), menuItem ); gtk_widget_show( menuItem ); m_items.Append( mitem ); diff --git a/src/gtk1/bitmap.cpp b/src/gtk1/bitmap.cpp index b06f111e55..e4adea4dd1 100644 --- a/src/gtk1/bitmap.cpp +++ b/src/gtk1/bitmap.cpp @@ -17,7 +17,12 @@ #include "gdk/gdkprivate.h" #ifdef USE_GDK_IMLIB + #include "../gdk_imlib/gdk_imlib.h" +#include "gdk/gdkx.h" // GDK_DISPLAY +#include +#include + #endif //----------------------------------------------------------------------------- @@ -223,7 +228,8 @@ bool wxBitmap::operator != ( const wxBitmap& bmp ) bool wxBitmap::Ok(void) const { - return m_refData != NULL; + wxASSERT_MSG( m_refData != NULL, "invalid bitmap" ); + return (m_refData != NULL); } int wxBitmap::GetHeight(void) const @@ -247,18 +253,27 @@ int wxBitmap::GetDepth(void) const void wxBitmap::SetHeight( int height ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetHeight not implemented" ); + M_BMPDATA->m_height = height; } void wxBitmap::SetWidth( int width ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetWidth not implemented" ); + M_BMPDATA->m_width = width; } void wxBitmap::SetDepth( int depth ) { if (!Ok()) return; + + wxFAIL_MSG( "wxBitmap::SetDepth not implemented" ); + M_BMPDATA->m_bpp = depth; } @@ -274,6 +289,7 @@ void wxBitmap::SetMask( wxMask *mask ) if (!Ok()) return; if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask; + M_BMPDATA->m_mask = mask; } @@ -298,6 +314,10 @@ void wxBitmap::Resize( int height, int width ) Render(); +#else + + wxFAIL_MSG( "wxBitmap::Resize not implemented without GdkImlib" ); + #endif } @@ -312,6 +332,10 @@ bool wxBitmap::SaveFile( const wxString &name, int WXUNUSED(type), return gdk_imlib_save_image( M_BMPDATA->m_image, WXSTRINGCAST name, (GdkImlibSaveInfo *) NULL ); +#else + + wxFAIL_MSG( "wxBitmap::SaveFile not implemented without GdkImlib" ); + #endif return FALSE; @@ -338,6 +362,11 @@ bool wxBitmap::LoadFile( const wxString &name, int WXUNUSED(type) ) M_BMPDATA->m_bpp = 24; // ? return TRUE; + +#else + + wxFAIL_MSG( "wxBitmap::LoadFile not implemented without GdkImlib" ); + #endif return FALSE; @@ -352,6 +381,9 @@ wxPalette *wxBitmap::GetPalette(void) const GdkPixmap *wxBitmap::GetPixmap(void) const { if (!Ok()) return (GdkPixmap *) NULL; + +// if (!M_BMPDATA->m_image) RecreateImage(); + return M_BMPDATA->m_pixmap; } @@ -375,6 +407,53 @@ void wxBitmap::DestroyImage(void) void wxBitmap::RecreateImage(void) { + if (!Ok()) return; + +#ifdef USE_GDK_IMLIB + + DestroyImage(); + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" ); + + long size = (long)(M_BMPDATA->m_width)*(long)(M_BMPDATA->m_height)*(long)3; + unsigned char *data = new unsigned char[size]; + for (long i = 0; i < size; i++) data[i] = 100; + + GdkImage *image = gdk_image_get( M_BMPDATA->m_pixmap, 0, 0, M_BMPDATA->m_width, M_BMPDATA->m_height ); + + long pos = 0; + for (int j = 0; j < M_BMPDATA->m_height; j++) + { + for (int i = 0; i < M_BMPDATA->m_width; i++) + { + XColor xcol; + xcol.pixel = gdk_image_get_pixel( image, i, j ); + Colormap cm = ((GdkColormapPrivate*)gdk_imlib_get_colormap())->xcolormap; + XQueryColor( gdk_display, cm, &xcol ); + + data[pos] = xcol.red; + data[pos+1] = xcol.green; + data[pos+2] = xcol.blue; + pos += 3; + } + } + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "invalid bitmap" ); + + M_BMPDATA->m_image = gdk_imlib_create_image_from_data( + data, (unsigned char*)NULL, M_BMPDATA->m_width, M_BMPDATA->m_height ); + + delete[] data; + + gdk_image_destroy( image ); + + Render(); + +#else + + wxFAIL_MSG( "wxBitmap::RecreateImage not implemented without GdkImlib" ); + +#endif } void wxBitmap::Render(void) @@ -383,10 +462,26 @@ void wxBitmap::Render(void) #ifdef USE_GDK_IMLIB + if (!M_BMPDATA->m_image) RecreateImage(); + + if (M_BMPDATA->m_pixmap) + { + gdk_imlib_free_pixmap( M_BMPDATA->m_pixmap ); + M_BMPDATA->m_pixmap = (GdkPixmap*) NULL; + } + if (M_BMPDATA->m_mask) + { + delete M_BMPDATA->m_mask; + M_BMPDATA->m_mask = (wxMask*) NULL; + } + gdk_imlib_render( M_BMPDATA->m_image, M_BMPDATA->m_image->rgb_width, M_BMPDATA->m_image->rgb_height ); M_BMPDATA->m_width = M_BMPDATA->m_image->rgb_width; M_BMPDATA->m_height = M_BMPDATA->m_image->rgb_height; M_BMPDATA->m_pixmap = gdk_imlib_move_image( M_BMPDATA->m_image ); + + wxCHECK_RET( M_BMPDATA->m_pixmap != NULL, "pixmap rendering failed" ) + GdkBitmap *mask = gdk_imlib_move_mask( M_BMPDATA->m_image ); if (mask) { @@ -394,6 +489,10 @@ void wxBitmap::Render(void) M_BMPDATA->m_mask->m_bitmap = mask; } +#else + + wxFAIL_MSG( "wxBitmap::Render not implemented without GdkImlib" ); + #endif } diff --git a/src/gtk1/dc.cpp b/src/gtk1/dc.cpp index ff6f369904..a7c77998bc 100644 --- a/src/gtk1/dc.cpp +++ b/src/gtk1/dc.cpp @@ -83,6 +83,12 @@ wxDC::~wxDC(void) { } +bool wxDC::Ok(void) const +{ + wxASSERT_MSG( !ok, "invalid display context" ); + return m_ok; +} + void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), double WXUNUSED(xc), double WXUNUSED(yc) ) { diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index ca39cfbb84..70bd684c16 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -124,10 +124,12 @@ wxPaintDC::~wxPaintDC(void) void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col), int WXUNUSED(style) ) { + wxFAIL_MSG( "wxPaintDC::FloodFill not implemented" ); } bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const { + wxFAIL_MSG( "wxPaintDC::GetPixel not implemented" ); return FALSE; } @@ -135,6 +137,8 @@ void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) { gdk_draw_line( m_window, m_penGC, @@ -146,6 +150,8 @@ void wxPaintDC::CrossHair( long x, long y ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) { int w = 0; @@ -164,6 +170,8 @@ void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double y { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx1 = XLOG2DEV(x1); long yy1 = YLOG2DEV(y1); long xx2 = XLOG2DEV(x2); @@ -212,6 +220,8 @@ void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -234,6 +244,8 @@ void wxPaintDC::DrawPoint( long x, long y ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() != wxTRANSPARENT) gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) ); } @@ -242,6 +254,8 @@ void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() == wxTRANSPARENT) return; for (int i = 0; i < n-1; i++) @@ -258,6 +272,8 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (m_pen.GetStyle() == wxTRANSPARENT) return; wxNode *node = points->First(); @@ -274,10 +290,12 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) } } -void wxPaintDC::DrawPolygon( int n, wxPoint points[], - long xoffset, long yoffset, int WXUNUSED(fillStyle) ) - { - if (!Ok()) return; +void wxPaintDC::DrawPolygon( int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle) ) +{ + if (!Ok()) return; + + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (!n) return; // Nothing to draw GdkPoint *gdkpoints = new GdkPoint[n+1]; int i; @@ -299,12 +317,13 @@ void wxPaintDC::DrawPolygon( int n, wxPoint points[], delete[] gdkpoints; } -void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, - long yoffset, int WXUNUSED(fillStyle)) - { +void wxPaintDC::DrawPolygon( wxList *lines, long xoffset, long yoffset, int WXUNUSED(fillStyle)) +{ + if (!Ok()) return; + + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + int n = lines->Number(); - - if (!Ok()) return; GdkPoint *gdkpoints = new GdkPoint[n]; wxNode *node = lines->First(); int cnt=0; @@ -336,6 +355,8 @@ void wxPaintDC::DrawRectangle( long x, long y, long width, long height ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -359,6 +380,8 @@ void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, d { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + if (radius < 0.0) radius = - radius * ((width < height) ? width : height); long xx = XLOG2DEV(x); @@ -424,6 +447,8 @@ void wxPaintDC::DrawEllipse( long x, long y, long width, long height ) { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + long xx = XLOG2DEV(x); long yy = YLOG2DEV(y); long ww = m_signX * XLOG2DEVREL(width); @@ -451,6 +476,8 @@ void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask ) if (!icon.Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -478,21 +505,22 @@ bool wxPaintDC::Blit( long xdest, long ydest, long width, long height, { if (!Ok()) return FALSE; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + // CMB 20/5/98: add blitting of bitmaps if (source->IsKindOf(CLASSINFO(wxMemoryDC))) { wxMemoryDC* srcDC = (wxMemoryDC*)source; - GdkBitmap* bmap = srcDC->m_selected.GetBitmap(); + GdkBitmap* bmap = srcDC->m_selected.GetBitmap(); if (bmap) { - gdk_draw_bitmap ( - m_window, - m_textGC, - bmap, - source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc), - XLOG2DEV(xdest), YLOG2DEV(ydest), - source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height) - ); + gdk_draw_bitmap( m_window, m_textGC, bmap, + source->DeviceToLogicalX(xsrc), + source->DeviceToLogicalY(ysrc), + XLOG2DEV(xdest), + YLOG2DEV(ydest), + source->DeviceToLogicalXRel(width), + source->DeviceToLogicalYRel(height) ); return TRUE; } } @@ -519,6 +547,8 @@ void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(us { if (!Ok()) return; + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); + GdkFont *font = m_font.GetInternalFont( m_scaleY ); x = XLOG2DEV(x); @@ -588,7 +618,7 @@ void wxPaintDC::Clear(void) { if (!Ok()) return; -// DestroyClippingRegion(); + if (!m_isDrawable) ((wxMemoryDC*)this)->m_selected.DestroyImage(); if (m_isDrawable) { diff --git a/src/gtk1/dcmemory.cpp b/src/gtk1/dcmemory.cpp index 5a6e982f9e..4b19f89c29 100644 --- a/src/gtk1/dcmemory.cpp +++ b/src/gtk1/dcmemory.cpp @@ -14,6 +14,10 @@ #include "wx/dcmemory.h" +#ifdef USE_GDK_IMLIB +#include "../gdk_imlib/gdk_imlib.h" +#endif + //----------------------------------------------------------------------------- // wxMemoryDC //----------------------------------------------------------------------------- @@ -23,13 +27,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC) wxMemoryDC::wxMemoryDC(void) { m_ok = FALSE; + +#ifdef USE_GDK_IMLIB + m_cmap = gdk_imlib_get_colormap(); +#else m_cmap = gdk_colormap_get_system(); +#endif } wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) ) { m_ok = FALSE; + +#ifdef USE_GDK_IMLIB + m_cmap = gdk_imlib_get_colormap(); +#else m_cmap = gdk_colormap_get_system(); +#endif } wxMemoryDC::~wxMemoryDC(void) diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp index fad9d5bb8e..9465c44a37 100644 --- a/src/gtk1/menu.cpp +++ b/src/gtk1/menu.cpp @@ -150,7 +150,7 @@ bool wxMenuBar::Enabled( int id ) const } //----------------------------------------------------------------------------- -// wxMenu +// "activate" //----------------------------------------------------------------------------- static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) @@ -161,7 +161,35 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (!menu->IsEnabled(id)) return; - wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id ); + wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, id ); + event.SetEventObject( menu ); + event.SetInt(id ); + + if (menu->m_callback) + { + (void) (*(menu->m_callback)) (*menu, event); + return; + } + + if (menu->GetEventHandler()->ProcessEvent(event)) return; + + wxWindow *win = menu->GetInvokingWindow(); + if (win) win->GetEventHandler()->ProcessEvent( event ); +} + +//----------------------------------------------------------------------------- +// "select" +//----------------------------------------------------------------------------- + +static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) +{ + int id = menu->FindMenuIdByMenuItem(widget); + + wxASSERT( id != -1 ); // should find it! + + if (!menu->IsEnabled(id)) return; + + wxCommandEvent event( wxEVT_MENU_HIGHLIGHT, id ); event.SetEventObject( menu ); event.SetInt(id ); @@ -177,6 +205,10 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (win) win->GetEventHandler()->ProcessEvent( event ); } +//----------------------------------------------------------------------------- +// wxMenu +//----------------------------------------------------------------------------- + IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject) wxMenuItem::wxMenuItem() @@ -283,6 +315,10 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(menuItem), "select", + GTK_SIGNAL_FUNC(gtk_menu_hilight_callback), + (gpointer*)this ); + gtk_menu_append( GTK_MENU(m_menu), menuItem ); gtk_widget_show( menuItem ); m_items.Append( mitem ); -- 2.45.2