Resizing woes: 3 questions (+ sample code)





Hi Guys,

I'm having some trouble getting resizing to work properly. Specifically,
I have 2 problems:

1) It seems that my windows only want to grow. When I issue
a resize request that is smaller than the current size, nothing
happens. (The attached program reproduces this behaviour,
click on the button to resize). Why is this?

2) In my program (see the definitions in the program below to
get a rough idea of how things are set up; I use a drawing
area with a backing pixmap) I eventually do something like this:

     // set window size
     hfWin->setSize (d_xgsize, d_ygsize+menu_height);
     // set drawingArea/pixmap size
     drawing_area.setUsize (d_xgsize, d_ygsize);
     clear ();
     drawhf ();

Now interestingly enough, the perceived result I get is this:

     clear
     draw
     resize (thus recreating the pixmap and blanking out the window again)

I've tried adding a call to gdk_flush() (not really knowing what to
expect), but that changed nothing. How come the perceived
result is not quite what the order of the calls would have me
expect? I realize this description is vague, but I have a hard time
telling what is going on.

Thanks a lot
--> Robert

---------------------- sample resize program ----------------------
#include <gtk--.h>
#include <gtk/gtk.h>
#include <time.h>
#include <stdlib.h>


class bufferedDrawingArea : public Gtk_DrawingArea
{
     public:
                    bufferedDrawingArea ();
          void      setUsize (int x, int y);

     private:
          int       handle_configure_event (GdkEventConfigure *event);
          int       handle_expose_event (GdkEventExpose *event);
          void           draw_brush (gdouble x, gdouble y);
          gint           handle_button_press_event (GdkEventButton *event);
          gint           handle_motion_notify_event (GdkEventMotion *event);

          GdkPixmap      *pixmap;  // pixmap buffer for drawing area
          int       lastx, lasty;
};


class HFWindow : public Gtk_Window
{
     public:
                         HFWindow ();

     private:
          void                resize ();

          Gtk_VBox       vbox;
          bufferedDrawingArea      drawing_area;
          Gtk_Button          button;
};



bufferedDrawingArea::bufferedDrawingArea () : pixmap (0)
{
     /* Signals used to handle backing pixmap */
     connect_to_method (expose_event, this, &handle_expose_event);
     connect_to_method (configure_event, this, &handle_configure_event);

     /* Event signals */
     connect_to_method (motion_notify_event, this, &handle_motion_notify_event);
     connect_to_method (button_press_event, this, &handle_button_press_event);

     set_events (GDK_EXPOSURE_MASK
          | GDK_LEAVE_NOTIFY_MASK
          | GDK_BUTTON_PRESS_MASK
          | GDK_POINTER_MOTION_MASK
          | GDK_POINTER_MOTION_HINT_MASK);
}


/* Create a new backing pixmap of the appropriate size */
int bufferedDrawingArea::handle_configure_event (GdkEventConfigure *event)
{
     //GtkWidget    *widget = GTK_WIDGET(gtkobj());

     if (pixmap)
          gdk_pixmap_unref(pixmap);

     pixmap = gdk_pixmap_new(get_window(),  width(), height(), -1);
     gdk_draw_rectangle (pixmap,
          GTK_WIDGET(gtkobj())->style->white_gc,
          TRUE, 0, 0, width(), height());

     return TRUE;
}


/* Redraw the screen from the backing pixmap */
int bufferedDrawingArea::handle_expose_event (GdkEventExpose *event)
{
     gdk_draw_pixmap(get_window(),
         GTK_WIDGET (gtkobj())->style->fg_gc[GTK_WIDGET_STATE
(GTK_WIDGET(gtkobj()))],
         pixmap,
         event->area.x, event->area.y,
         event->area.x, event->area.y,
         event->area.width, event->area.height);
     return FALSE;
}


/* Draw a rectangle on the screen */
void bufferedDrawingArea::draw_brush (gdouble x, gdouble y)
{
     GdkRectangle update_rect;
     update_rect.x = (int)x - 5;
     update_rect.y = (int)y - 5;
     update_rect.width = 10;
     update_rect.height = 10;
     gdk_draw_rectangle (pixmap,
          GTK_WIDGET (gtkobj())->style->black_gc,
          TRUE,
          update_rect.x, update_rect.y,
          update_rect.width, update_rect.height);
     draw (&update_rect);
}


gint bufferedDrawingArea::handle_button_press_event (GdkEventButton *event)
{
     if (event->button == 1 && pixmap != NULL)
          draw_brush (event->x, event->y);

     return TRUE;
}


gint bufferedDrawingArea::handle_motion_notify_event (GdkEventMotion *event)
{
     int       x, y;
     GdkModifierType state;

     if (event->is_hint)
          gdk_window_get_pointer (event->window, &x, &y, &state);
     else
          {
          x = (int)event->x;
          y = (int)event->y;
          state = (GdkModifierType) event->state;
          }

     if (state & GDK_BUTTON1_MASK && pixmap != NULL)
          draw_brush (x, y);

     return TRUE;
}


void bufferedDrawingArea::setUsize (int x, int y)
{
     //printf ("\n--- curr: %d, %d;\treq: %d, %d\n", width(), height(), x, y);
     printf ("\n--- req: %d, %d\n", x, y);
     if (x != width() || y != height())
          {
          if (pixmap)
               gdk_pixmap_unref(pixmap);
          pixmap = gdk_pixmap_new(get_window(), x, y, -1);
          gdk_draw_rectangle (pixmap,
               GTK_WIDGET(gtkobj())->style->white_gc,
               TRUE, 0, 0, x, y);
          this->set_usize (x, y);
          }

     this->show ();
}


HFWindow::HFWindow() : Gtk_Window(GTK_WINDOW_TOPLEVEL),
                    vbox (FALSE, 0),
                    button ("resize")
{
     add (&vbox);

     /* Create the drawing area */
     drawing_area.size (100, 100);
     vbox.pack_start (drawing_area, TRUE, TRUE, 0);

     /* Add the button */
     vbox.pack_start (button, FALSE, FALSE, 0);

     connect_to_method (button.clicked, this, &resize);
     //connect_to_method (destroy, this, &resize);

     drawing_area.show();
     button.show();
     vbox.show();
}


void HFWindow::resize()
{
     int  x = rand()%400,
          y = rand()%400;
     this->set_usize (x, y+22);
     drawing_area.setUsize (x, y);

     this->show ();
     drawing_area.show ();
}


int main (int argc, char *argv[])
{
     HFWindow  *hfw;
     Gtk_Main  hfedit (&argc, &argv);

     srand (time(NULL));
     hfw = new HFWindow;
     hfw ->show();

     hfedit.run();

     return 0;
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]