Hi,
I am trying to develop a power system software and need to draw movable components onto to the screen. However I face the following issues during implementation:
1. The object is displayed on mouse click. When I try to drag the custom object, the program crashes. If I remove the "moved_object->changed(true); " statement in the "on_canvas_motion_notify_event" function, the program runs but the object is not moved.
2. When I now minimize the window and then maximize the object has moved
3. When I try to move the object once again the get_item_at() returns 0
Can someone help me out here as I have no clue how to proceed further.
#include <gtkmm.h>
#include <goocanvasmm.h>
class MainWindow:public Gtk::Window
{
public:
Glib::RefPtr<Gtk::Builder> ref_glade;
MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
Goocanvas::Canvas canvas_area;
Glib::RefPtr<Goocanvas::Item> dragitem;
bool isDragged;
bool on_canvas_button_press_event(const Glib::RefPtr<Goocanvas::Item>& item, GdkEventButton* event);
bool on_canvas_button_release_event(const Glib::RefPtr<Goocanvas::Item>& item, GdkEventButton* event);
bool on_canvas_motion_notify_event(const Glib::RefPtr<Goocanvas::Item>& target, GdkEventMotion* event);
};
class SampleObject : public Goocanvas::ItemSimple
{
public:
SampleObject(double x = 0, double y = 0);
void simple_update_vfunc(const Cairo::RefPtr<Cairo::Context>& cr);
void simple_paint_vfunc(const Cairo::RefPtr<Cairo::Context>& cr, const Goocanvas::Bounds& bounds);
bool simple_is_item_at_vfunc(double x, double y, const Cairo::RefPtr< Cairo::Context >& cr, bool is_pointer_event);
double obj_x, obj_y;
};
MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
: Gtk::Window(cobject),
ref_glade(builder)
{
isDragged=false;
canvas_area.set_size_request(640, 480);
canvas_area.set_bounds(0, 0, 1000, 1000);
Gtk::ScrolledWindow* scroll_win = 0;
builder->get_widget("scrolledwindow1", scroll_win);
scroll_win->add(canvas_area);
show_all_children();
Glib::RefPtr<Goocanvas::Item> root = canvas_area.get_root_item();
root->signal_button_press_event().connect(sigc::mem_fun(*this, &MainWindow::on_canvas_button_press_event));
root->signal_button_release_event().connect(sigc::mem_fun(*this, &MainWindow::on_canvas_button_release_event));
root->signal_motion_notify_event().connect(sigc::mem_fun(*this, &MainWindow::on_canvas_motion_notify_event));
}
bool MainWindow::on_canvas_button_release_event(const Glib::RefPtr<Goocanvas::Item>& item, GdkEventButton* event)
{
isDragged=false;
dragitem.clear();
return true;
}
bool MainWindow::on_canvas_motion_notify_event(const Glib::RefPtr<Goocanvas::Item>& target, GdkEventMotion* event)
{
if(isDragged)
{
Glib::RefPtr<SampleObject> moved_object=Glib::RefPtr<SampleObject>::cast_dynamic(dragitem);
moved_object->obj_x=event->x;
moved_object->obj_y=event->y;
moved_object->changed(true);
}
return true;
}
bool MainWindow::on_canvas_button_press_event(const Glib::RefPtr<Goocanvas::Item>& item, GdkEventButton* event)
{
Glib::RefPtr<Goocanvas::Item> root = canvas_area.get_root_item();
Glib::RefPtr<Glib::Object> select_object=ref_glade->get_object("add_select");
Glib::RefPtr<Gtk::RadioAction> select_selected = Glib::RefPtr<Gtk::RadioAction>::cast_dynamic(select_object);
switch(select_selected->get_current_value())
{
case 1:
{
Glib::RefPtr<SampleObject> sobj=Glib::RefPtr<SampleObject>(new SampleObject(event->x,event->y));
root->add_child(sobj);
break;
}
default:
dragitem=canvas_area.get_item_at(event->x,event->y,true);
std::cout<<dragitem<<std::endl;
if(dragitem)
{
isDragged=true;
}
break;
}
return true;
}
Thanking You,
Shashank Bandari
shashank bandari ieee org