Drawing Area woes: Sample code (Gtk--)
- From: Robert_Gasch/PeopleSoft peoplesoft com
- To: gtk-list redhat com
- Subject: Drawing Area woes: Sample code (Gtk--)
- Date: Tue, 4 May 1999 15:40:17 +0200
Hi,
the following is a piece of code I've hacked together
in search of enlightenment (no, not the window manager).
It compiles without a hitch but gives a GDK-CRITICAL
error when attemping to size the drawing area
(ie: when attemping to create the backing pixmap).
I've used this specific code in GuiBufferedDrawingArea
for quite a while now without problems and I can't figure
out why it won't work with the example given below.
If any Gtk(--) gurus know the answer to this, I'd be
most appreciative as I've been stuck on this now
for more than a week and still have no clue what
I'm doing wrong ... the actual place where the thing
breaks is in GuiDialogPreview::insertPreview ().
I'm using RH 5.2, Gtk 1.2.1, Gtk-- 1.0.0 (vanilla), egcs 1.1
Thanks a lot
--> Robert
PS: Apologies for the mixture of Gtk-- and Gdk calls ...
------------------ cut here -----------------------
#include <gtk--.h>
#include <gtk/gtk.h>
/*
* GuiBufferedDrawingArea: provide an offscreen drawing area which
* is refreshes/repaints using an atomic copy operation from the
* offscreen pixmap to the on screen window.
*/
class GuiBufferedDrawingArea : public Gtk_DrawingArea
{
public:
GuiBufferedDrawingArea ();
~GuiBufferedDrawingArea ();
void clear (GdkColor *col=NULL);
void setColors (GdkColor *fg, GdkColor *bg=NULL);
void drawRectangle (int x1, int y1,
int width, int height, bool filled=TRUE);
void setUsize (int x, int y);
private:
int handleConfigureEvent (GdkEventConfigure *event);
int handleExposeEvent (GdkEventExpose *event);
GdkPixmap *d_pixmap; // pixmap buffer for drawing area
GdkGC *d_GC; // graphics content
};
GuiBufferedDrawingArea::GuiBufferedDrawingArea () : d_pixmap (0)
{
/* Signals used to handle backing pixmap */
connect_to_method (expose_event, this, &handleExposeEvent);
connect_to_method (configure_event, this, &handleConfigureEvent);
set_events (GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK);
d_GC=GTK_WIDGET (gtkobj())->style->black_gc;
}
GuiBufferedDrawingArea::~GuiBufferedDrawingArea ()
{
gdk_pixmap_unref (d_pixmap);
}
void GuiBufferedDrawingArea::clear (GdkColor *col)
{
GdkRectangle update_rect;
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = width();
update_rect.height = height();
if (!col)
gdk_draw_rectangle (d_pixmap,
GTK_WIDGET(gtkobj())->style->white_gc,
TRUE, 0, 0, this->width(), this->height());
else
{
setColors (col);
drawRectangle (0, 0, this->width(), this->height(), TRUE);
}
}
void GuiBufferedDrawingArea::setUsize (int x, int y)
{
if (x != width() || y != height())
{
if (d_pixmap)
gdk_pixmap_unref(d_pixmap);
d_pixmap = gdk_pixmap_new(get_window(), x, y, -1);
gdk_draw_rectangle (d_pixmap,
GTK_WIDGET(gtkobj())->style->white_gc,
TRUE, 0, 0, x, y);
this->set_usize (x, y);
}
this->show ();
}
void GuiBufferedDrawingArea::setColors (GdkColor *fg, GdkColor *bg)
{
if (fg)
gdk_gc_set_foreground (GTK_WIDGET (gtkobj())->style->black_gc, fg);
if (bg)
gdk_gc_set_foreground (GTK_WIDGET (gtkobj())->style->black_gc, bg);
}
int GuiBufferedDrawingArea::handleConfigureEvent (GdkEventConfigure *event)
{
//GtkWidget *widget = GTK_WIDGET(gtkobj());
if (event); // silence compiler warning
if (d_pixmap)
gdk_pixmap_unref(d_pixmap);
d_pixmap = gdk_pixmap_new(get_window(), width(), height(), -1);
gdk_draw_rectangle (d_pixmap,
GTK_WIDGET(gtkobj())->style->white_gc,
TRUE, 0, 0, width(), height());
return TRUE;
}
int GuiBufferedDrawingArea::handleExposeEvent (GdkEventExpose *event)
{
gdk_draw_pixmap(get_window(),
GTK_WIDGET (gtkobj())->style->fg_gc[GTK_WIDGET_STATE
(GTK_WIDGET(gtkobj()))],
d_pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
void GuiBufferedDrawingArea::drawRectangle (int x1, int y1,
int width, int height,
bool filled)
{
GdkRectangle update_rect;
update_rect.x = x1;
update_rect.y = y1;
update_rect.width = width;
update_rect.height = height;
gdk_draw_rectangle (d_pixmap,
GTK_WIDGET (gtkobj())->style->black_gc,
filled,
update_rect.x, update_rect.y,
update_rect.width, update_rect.height);
}
class GuiDialogPreview : public Gtk_Dialog
{
public:
GuiDialogPreview (char *winTitle, char *frameTitle,
int tableX, int tableY);
~GuiDialogPreview ();
protected:
void insertPreview ();
void clearPreview ();
void setupVBox ();
virtual void fillVBox ();
virtual void fillActionArea ();
virtual void buildDialogWindow ();
virtual void buttonCallbackOK ();
virtual void buttonCallbackApply ();
virtual void buttonCallbackCancel ();
virtual void checkboxCallbackPreview ();
virtual gint delete_event_impl (GdkEventAny *);
int d_size,
d_frameBorder;
Gtk_VBox d_vBoxPreview;
Gtk_Button d_btnOK,
d_btnApply,
d_btnCancel;
Gtk_CheckButton d_cbUsePreview;
Gtk_Frame *d_baseFrame,
*d_previewFrame,
*d_previewGroupFrame;
Gtk_Preview *d_preview;
GuiBufferedDrawingArea *d_drawArea;
Gtk_Table *d_table;
char *d_winTitle,
*d_frameTitle;
bool d_applyHit;
};
GuiDialogPreview::GuiDialogPreview (char *winTitle, char *frameTitle,
int tableX, int tableY) :
d_vBoxPreview (FALSE, 0),
d_btnOK ("OK"),
d_btnApply ("Apply"),
d_btnCancel ("Cancel"),
d_cbUsePreview ("Use Preview")
{
d_winTitle = strdup (winTitle);
d_frameTitle = strdup (frameTitle);
d_baseFrame = d_previewFrame = d_previewGroupFrame = NULL;
d_preview = NULL;
d_drawArea = NULL;
d_size = 100;
d_frameBorder = 4;
d_table = new Gtk_Table (tableX, tableY, FALSE);
d_applyHit = FALSE;
this->set_position (GTK_WIN_POS_MOUSE);
buildDialogWindow ();
}
GuiDialogPreview::~GuiDialogPreview ()
{
if (d_winTitle) free (d_winTitle); // c-type alloc from strdup
if (d_frameTitle) free (d_frameTitle); // c-type alloc from strdup
if (d_baseFrame) delete d_baseFrame;
if (d_previewFrame) delete d_previewFrame;
if (d_preview) delete d_preview;
if (d_table) delete d_table;
}
void GuiDialogPreview::buildDialogWindow ()
{
this->set_usize (300, 250);
this->set_title (d_winTitle);
this->get_vbox()->set_border_width (2);
setupVBox ();
insertPreview ();
fillVBox ();
fillActionArea ();
if (d_baseFrame)
d_baseFrame->show ();
this->show ();
}
void GuiDialogPreview::setupVBox ()
{
d_baseFrame = new Gtk_Frame (d_frameTitle);
d_baseFrame->set_shadow_type (GTK_SHADOW_ETCHED_IN);
d_baseFrame->set_border_width (0);
this->get_vbox()->pack_start (*d_baseFrame, TRUE, TRUE, 0);
d_baseFrame->show ();
this->get_vbox()->show ();
}
void GuiDialogPreview::insertPreview ()
{
// add main table
d_baseFrame->add (*d_table);
// add bounding frame + main preview vbox
d_previewGroupFrame = new Gtk_Frame ("Preview");
d_previewGroupFrame->set_border_width (d_frameBorder);
// add main VBox
d_previewGroupFrame->add (d_vBoxPreview);
d_previewGroupFrame->show ();
// add preview frame to table
d_table->attach (*d_previewGroupFrame, 1, 3, 1, 4);
// build preview Frame and add it to preview vbox
d_previewFrame = new Gtk_Frame ();
d_previewFrame->set_shadow_type (GTK_SHADOW_ETCHED_IN);
d_previewFrame->set_border_width (2);
d_vBoxPreview.pack_start (*d_previewFrame, FALSE, FALSE, 0);
d_previewFrame->show ();
// setup checkbutton
d_cbUsePreview.set_active (TRUE);
connect_to_method (d_cbUsePreview.clicked, this, &checkboxCallbackPreview);
d_vBoxPreview.pack_start (d_cbUsePreview, FALSE, FALSE, 0);
d_cbUsePreview.show ();
d_vBoxPreview.show ();
d_table->show ();
// add drawing area
d_drawArea = new GuiBufferedDrawingArea ();
d_previewFrame->add (*d_drawArea);
d_drawArea->show ();
printf ("F\n"); fflush (stdout);
// GDK ERROR is here
d_drawArea->setUsize (d_size, d_size);
printf ("G\n"); fflush (stdout);
}
void GuiDialogPreview::clearPreview ()
{
guchar *row = new unsigned char [3*d_size];
for (int i=0; i<d_size; i++)
for (int j=0; j<d_size; j++)
{
row[j*3]=(int) (255.0/d_size*i);
row[j*3+1]=(int) (255.0/d_size*i);
row[j*3+2]=(int) (255.0/d_size*i);
d_preview->draw_row (row, 0, i, d_size);
}
delete [] row;
}
void GuiDialogPreview::fillVBox ()
{
}
void GuiDialogPreview::fillActionArea ()
{
connect_to_method (d_btnOK.clicked, this, &buttonCallbackOK);
this->get_action_area()->pack_start (d_btnOK, TRUE, TRUE, 0);
d_btnOK.show ();
connect_to_method (d_btnApply.clicked, this, &buttonCallbackApply);
this->get_action_area()->pack_start (d_btnApply, TRUE, TRUE, 0);
d_btnApply.show ();
connect_to_method (d_btnCancel.clicked, this, &buttonCallbackCancel);
this->get_action_area()->pack_start (d_btnCancel, TRUE, TRUE, 0);
d_btnCancel.show ();
}
void GuiDialogPreview::buttonCallbackOK ()
{
cout << "GuiDialogPreview: Default Callback OK\n";
d_applyHit = FALSE;
}
void GuiDialogPreview::buttonCallbackApply ()
{
cout << "GuiDialogPreview: Default Callback Apply\n";
d_applyHit = TRUE;
}
void GuiDialogPreview::buttonCallbackCancel ()
{
this->hide ();
d_applyHit = FALSE;
}
void GuiDialogPreview::checkboxCallbackPreview ()
{
if (!d_cbUsePreview.get_active())
d_previewFrame->set_sensitive (FALSE);
else
d_previewFrame->set_sensitive (TRUE);
}
gint GuiDialogPreview::delete_event_impl (GdkEventAny *)
{
this->hide ();
return (0);
}
int main (int argc, char *argv[])
{
GuiDialogPreview *dp;
Gtk_Main dork (&argc, &argv);
dp = new GuiDialogPreview ("test", "preview", 4, 4);
dp->show();
dork.run();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]