[gtkmm] beginner redraw question



I've been trying to use gtkmm 1.2.9 to devise a plotting routine.  I'm
inheriting a Plot class from DrawingArea.  I started by using the
DrawingArea example included in the package....  The actual drawing routines
are in a function called expose_event_impl.  My question is that - when I
want to update the plot with another one by changing the data, how to I do
it?  I am not sure how all this ties together.  The tutorial does not
provide enough info, and the api reference just lists the classes.

I'd appreciate any help, examples.  I've attached my relevant src if anyone
cares to look.

Joe

#ifndef _plot
#define _plot

#include <gtk--/drawingarea.h>
#include <string>
#include "Axis.h"

class Plot : public Gtk::DrawingArea
{
private:
 Gdk_GC       gc_;
 Gdk_Color    blue_, red_, grey_;
 Gdk_Window   window_;
 int size_x;
 int size_y;
 int border;
 int plot_size_x;
 int plot_size_y;
 float *xc;
 float *yc;
 int numpts;
 string title;
 Axis xaxis;
 Axis yaxis;

protected:
 virtual void realize_impl();
 virtual gint expose_event_impl(GdkEventExpose* e);

public:
 Plot( int, int );
 ~Plot();
 void setData( float *, float *, int );
 void setTitle( const string& );
 void setXaxis( float, float, float, float, const string& );
 void setYaxis( float, float, float, float, const string& );
};

#endif
#include <gtk--/style.h>
#include <gdk--/gc.h>
#include "Plot.h"
#include "libjoe.h"

Plot::Plot(int x, int y) {
 cout << "Plot:  constructor with args (" << x << ", " << y << ")\n";
 size_x = x;
 size_y = y;
 // in the ctor you can only allocate colors,
 // get_window() returns 0 because we have not be realized
 Gdk_Colormap colormap_=get_default_colormap ();

 blue_=Gdk_Color("blue");
 red_=Gdk_Color("red");
 grey_ = Gdk_Color("grey");

 colormap_.alloc(blue_);
 colormap_.alloc(red_);
 colormap_.alloc(grey_);
 cout << "canvas is " << size_x << " x " << size_y << endl;
 Gtk::DrawingArea::size(size_x, size_y);
 border = 20;
 plot_size_x = size_x - 2*border;
 plot_size_y = size_y - 2*border;
 cout << "plot is " << plot_size_x << " x " << plot_size_y << endl;
}

Plot::~Plot() {
 cout << "Plot:  destructing\n";
 delete [] xc;
 delete [] yc;
}

void Plot::realize_impl() {
 // we need to do the default realize
 Gtk::DrawingArea::realize_impl();

 // Now we can allocate any additional resources we need
}

gint Plot::expose_event_impl(GdkEventExpose* e) {
 // here is where we draw on the window
 window_=get_window();
 Gdk_GC some_gc;
 some_gc.create(get_window());
 //window_.set_background(grey_);
 //window_.clear();
 some_gc.set_foreground(red_);
 //window_.clear();
 // draw the background
 window_.draw_rectangle(this->get_style()->get_white_gc(), true, border-1,
border-1, plot_size_x+1, plot_size_y+1);
 window_.draw_rectangle(this->get_style()->get_black_gc(), false, border-1,
border-1, plot_size_x+1, plot_size_y+1);
 // draw the plot
 for (int i=0; i<numpts; i++) {
  window_.draw_point(some_gc, xc[i], yc[i]);
 }
 // window_.draw_line(gc_,1,1,400,100);
 // draw the title
 Gdk_Font text_font("10x20");
 window_.draw_string(text_font, this->get_style()->get_black_gc(), 100, 15,
title.c_str());
 return true;
}

void Plot::setData( float *x, float *y, int np ) {
 float scale_x = plot_size_x / (xaxis.getMax() - xaxis.getMin());
 float scale_y = plot_size_y / (yaxis.getMax() - yaxis.getMin());
 cout << "X Axis scale factor = " << scale_x << endl;
 cout << "Y Axis scale factor = " << scale_y << endl;
 xc = new float[np];
 yc = new float[np];
 for (int i=0; i<np; i++) {
  xc[i] = (x[i] - xaxis.getMin())* scale_x + border;
  yc[i] = size_y - ((y[i] - yaxis.getMin())* scale_y) - border;
  //cout << "point " << i << " (" << x[i] << ", " << y[i] << ") -> ("
  //  << xc[i] << ", " << yc[i] << ")\n";
 }
 numpts = np;
 GdkEventExpose* e;
 expose_event_impl(e);
}

void Plot::setTitle( const string& text ) {
 title = text;
}

void Plot::setXaxis( float xmin, float xmax, float xmjtics, float xmntics,
      const string& label ) {
 xaxis = Axis(xmin, xmax, xmjtics, xmntics, label);
 cout << "xaxis min is " << xaxis.getMin() << endl;
 cout << "xaxis max is " << xaxis.getMax() << endl;
}

void Plot::setYaxis( float ymin, float ymax, float ymjtics, float ymntics,
      const string& label ) {
 yaxis = Axis(ymin, ymax, ymjtics, ymntics, label);
 cout << "y-axis min is " << yaxis.getMin() << endl;
 cout << "y-axis max is " << yaxis.getMax() << endl;
}

#include <gtk--/main.h>
#include <gtk--/window.h>
#include <gtk--/button.h>
#include <gtk--/table.h>
#include "Plot.h"
#include "libjoe.h"

using std::cout;

using SigC::slot;
using SigC::bind;

//Quit app when user closes main window:
gint on_win_delete_event(GdkEventAny* event)
{
  Gtk::Main::quit();
  return FALSE;
}

class MyWin : public Gtk::Window
{
public:
  MyWin();
  ~MyWin();

  Gtk::Table m_table;
  Gtk::Button m_b1, m_bQuit;
  Plot *plot1;

  void callback(char* data);

  gint delete_event_impl(GdkEventAny*) {
    Gtk::Main::quit(); return 0;
  }

};

MyWin::MyWin() :
  m_table(2, 2, false),
  m_b1("Pause"),
  m_bQuit("Quit")
{

  plot1 = new Plot(300, 300);
  set_title("Quicklook testbed");
  set_border_width(20);

  add(m_table);

  m_table.attach(m_b1, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
  m_table.attach(*plot1, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 10, 10);
  m_table.attach(m_bQuit, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);

  m_b1.clicked.connect(bind<char*>(slot(this, &MyWin::callback), "Pause"));
  m_bQuit.clicked.connect(Gtk::Main::quit.slot());
  // the cast is needed to "help" template instantiation
  show_all();

  int np = 100;
  float x[np];
  float y[np];
  plot1->setXaxis(-10, 10, 1, 0, "x axis");
  plot1->setYaxis(-2, 2, 1, 0, "y axis");
  plot1->setTitle("title");
  for (int i=0; i<np; i++) {
   x[i] = ((float)i - 50) * .1;
   y[i] = sin(x[i]);
  }
  plot1->setData(x, y, np);
  sleep( (clock_t)3 * CLOCKS_PER_SEC );
  for (int i=0; i<np; i++) {
   x[i] = ((float)i - 50) * .1;
   y[i] = cos(x[i]);
  }
  plot1->setData(x, y, np);
}

MyWin::~MyWin() {
 cout << "MyWin:  destructing\n";
 delete plot1;
}

void
MyWin::callback(char* data)
{
  cout << data << " was pressed" << endl;
}

int main(int argc, char** argv)
  {
  Gtk::Main myapp(&argc, &argv);
  MyWin mywin;

  myapp.run();
  return 0;
  }





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