示例#1
0
    void dragable::
    on_mouse_move (
        unsigned long state,
        long x,
        long y
    )
    {
        if (drag && (state & base_window::LEFT) && enabled && !hidden)
        {
            // the user is trying to drag this object.  we should calculate the new
            // x and y positions for the upper left corner of this object's rectangle

            long new_x = x - this->x;
            long new_y = y - this->y;

            // make sure these points are inside the dragable area.  
            if (new_x < area.left())
                new_x = area.left();
            if (new_x + static_cast<long>(rect.width()) - 1 > area.right())
                new_x = area.right() - rect.width() + 1;

            if (new_y + static_cast<long>(rect.height()) - 1 > area.bottom())
                new_y = area.bottom() - rect.height() + 1;
            if (new_y < area.top())
                new_y = area.top();

            // now make the new rectangle for this object
            rectangle new_rect(
                new_x,
                new_y,
                new_x + rect.width() - 1,
                new_y + rect.height() - 1
            );

            // only do anything if this is a new rectangle and it is inside area
            if (new_rect != rect && area.intersect(new_rect) == new_rect)
            {
                parent.invalidate_rectangle(new_rect + rect);
                rect = new_rect;

                // call the on_drag() event handler
                on_drag();
            }
        }
        else
        {
            drag = false;
        }
    }
示例#2
0
// widget developer functions:
void UIWidget::mouse_axes_func(float x, float y, float dx, float dy)
{
   if (disabled) return;

   // start by transforming the coordinates for the children

   local_mouse_x = x;
   local_mouse_y = y;
   float tmdx = dx;
   float tmdy = dy;

   surface_area->placement.transform_coordinates(&local_mouse_x, &local_mouse_y);
   surface_area->placement.transform_coordinates(&tmdx, &tmdy);

   UIWidget *parent = static_cast<UIWidget *>(get_parent());
   if (parent && parent->mouse_is_blocked) mouse_is_blocked = true;
   else mouse_is_blocked = false;

   //for (int i=(int)children.size()-1; i>=0; i--)
      //children[i]->mouse_axes_func(local_mouse_x, local_mouse_y, dx, dy);  // I'm not sure why these are dx/dy, but it works correctly this way

   for (auto &child : ElementID::recast_collection<UIWidget>(get_children()))
      child->mouse_axes_func(local_mouse_x, local_mouse_y, dx, dy);  // I'm not sure why these are dx/dy, but it works correctly this way

   // then proceed with the execution of the function

   if (surface_area)
   {
      bool mouse_over_now = surface_area->collides(x, y);
      if (parent && parent->mouse_is_blocked) mouse_over_now = false;

      if (mouse_over_now && !mouse_over) on_mouse_enter();
      else if (!mouse_over_now && mouse_over) on_mouse_leave();

      mouse_over = mouse_over_now;
      if (parent && mouse_over) parent->mouse_is_blocked = true;
   }

   on_mouse_move(x, y, dx, dy); // TODO I think this needs to be the translated coordinates, and maybe even should be on the on_drag() call below as well
   if (mouse_down_on_over)
   {
      dragging = true;
      on_drag(x, y, dx, dy);
   }

   if (Framework::current_event->mouse.dz != 0 || Framework::current_event->mouse.dw != 0) on_mouse_wheel();
}
示例#3
0
文件: Item.cpp 项目: LADI/ladish
/** Event handler to fire (higher level, abstracted) Item signals from Gtk events.
 */
bool
Item::on_event(GdkEvent* event)
{
	boost::shared_ptr<Canvas> canvas = _canvas.lock();
	if (!canvas || !event)
		return false;

	static double x, y;
	static double drag_start_x, drag_start_y;
	static bool double_click = false;
	static bool dragging = false;
	double click_x, click_y;

	click_x = event->button.x;
	click_y = event->button.y;

	property_parent().get_value()->w2i(click_x, click_y);

	switch (event->type) {

	case GDK_2BUTTON_PRESS:
		if (dragging) {
			ungrab(event->button.time);
			dragging = false;
		}
		on_double_click(&event->button);
		double_click = true;
		break;

	case GDK_BUTTON_PRESS:
		if (!canvas->locked() && event->button.button == 1) {
			x = click_x;
			y = click_y;
			// Set these so we can tell on a button release if a drag actually
			// happened (if not, it's just a click)
			drag_start_x = x;
			drag_start_y = y;
			grab(GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK,
					Gdk::Cursor(Gdk::FLEUR), event->button.time);
			dragging = true;
		}
		break;

	case GDK_MOTION_NOTIFY:
		if ((dragging && (event->motion.state & GDK_BUTTON1_MASK))) {
			double new_x = click_x;
			double new_y = click_y;

			if (event->motion.is_hint) {
				int t_x;
				int t_y;
				GdkModifierType state;
				gdk_window_get_pointer(event->motion.window, &t_x, &t_y, &state);
				new_x = t_x;
				new_y = t_y;
			}

			on_drag(new_x - x, new_y - y);

			x = new_x;
			y = new_y;
		}
		break;

	case GDK_BUTTON_RELEASE:
		if (dragging) {
			ungrab(event->button.time);
			dragging = false;
			if (click_x != drag_start_x || click_y != drag_start_y) {
				on_drop();
			} else if (!double_click) {
				on_click(&event->button);
			}
		} else if (!double_click) {
			on_click(&event->button);
		}
		double_click = false;
		break;

	case GDK_ENTER_NOTIFY:
		canvas->signal_item_entered.emit(this);
		raise_to_top();
		break;

	case GDK_LEAVE_NOTIFY:
		canvas->signal_item_left.emit(this);
		break;

	default:
		break;
	}

	// Never stop event propagation so derived classes have full access
	// to GTK events.
	return false;
}