mirror of
git://projects.qi-hardware.com/fped.git
synced 2025-02-16 14:04:42 +02:00
Dragging a frame into the canvas now works. It's built on top of the frame
tool, with all the old code still around, so the code paths are a bit obscure. - gui_frame_drag.c: use GTK_DEST_DEFAULT_MOTION instead of GTK_DEST_DEFAULT_HIGHLIGHT - gui_frame_drag.c: put meat on the frame and canvas drag and drop skeleton - gui_frame_drag.c (setup_frame_drag, setup_canvas_drag): use GDK_ACTION_COPY instead of GDK_ACTION_PRIVATE - gui_frame_drag.h, gui_frame_drag.c (is_dragging_anything): new helper function to check if we're dragging anything, without specifying what - gui_canvas.h, gui_canvas.c: added thin interface layer between gui_frame.c and gui_tool.c - gui_canvas.c (enter_notify_event, leave_notify_event): return FALSE so that other widgets can get the events, too - gui_tool.h, gui_tool.c (tool_hover): return whether we found anything to hover on - gui_tool.h, gui_tool.c: added interface for dropping a frame on the canvas git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5932 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
a4d2926b2d
commit
0b241a14fe
42
gui_canvas.c
42
gui_canvas.c
@ -187,6 +187,41 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- drag and drop (frame to canvas) ----------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
void canvas_frame_begin(struct frame *frame)
|
||||||
|
{
|
||||||
|
tool_push_frame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int canvas_frame_motion(struct frame *frame, int x, int y)
|
||||||
|
{
|
||||||
|
struct coord pos = canvas_to_coord(x, y);
|
||||||
|
|
||||||
|
return tool_hover(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void canvas_frame_end(void)
|
||||||
|
{
|
||||||
|
tool_dehover();
|
||||||
|
tool_pop_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int canvas_frame_drop(struct frame *frame, int x, int y)
|
||||||
|
{
|
||||||
|
struct coord pos = canvas_to_coord(x, y);
|
||||||
|
|
||||||
|
if (!tool_place_frame(frame, pos))
|
||||||
|
return FALSE;
|
||||||
|
change_world();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- button press and release ------------------------------------------ */
|
/* ----- button press and release ------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
@ -254,6 +289,8 @@ static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
|
|||||||
DPRINTF("--- button release ---");
|
DPRINTF("--- button release ---");
|
||||||
switch (event->button) {
|
switch (event->button) {
|
||||||
case 1:
|
case 1:
|
||||||
|
if (is_dragging_anything())
|
||||||
|
return FALSE;
|
||||||
if (!dragging)
|
if (!dragging)
|
||||||
break;
|
break;
|
||||||
drag_left(pos);
|
drag_left(pos);
|
||||||
@ -448,8 +485,9 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
|
|||||||
static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
DPRINTF("--- enter ---");
|
||||||
gtk_widget_grab_focus(widget);
|
gtk_widget_grab_focus(widget);
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -461,7 +499,7 @@ static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
|||||||
tool_cancel_drag();
|
tool_cancel_drag();
|
||||||
tool_dehover();
|
tool_dehover();
|
||||||
dragging = 0;
|
dragging = 0;
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* gui_canvas.h - GUI, canvas
|
* gui_canvas.h - GUI, canvas
|
||||||
*
|
*
|
||||||
* Written 2009 by Werner Almesberger
|
* Written 2009, 2010 by Werner Almesberger
|
||||||
* Copyright 2009 by Werner Almesberger
|
* Copyright 2009, 2010 by Werner Almesberger
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -34,6 +34,11 @@ void zoom_out_center(void);
|
|||||||
void zoom_to_frame(void);
|
void zoom_to_frame(void);
|
||||||
void zoom_to_extents(void);
|
void zoom_to_extents(void);
|
||||||
|
|
||||||
|
void canvas_frame_begin(struct frame *frame);
|
||||||
|
int canvas_frame_motion(struct frame *frame, int x, int y);
|
||||||
|
void canvas_frame_end(void);
|
||||||
|
int canvas_frame_drop(struct frame *frame, int x, int y);
|
||||||
|
|
||||||
GtkWidget *make_canvas(void);
|
GtkWidget *make_canvas(void);
|
||||||
void init_canvas(void);
|
void init_canvas(void);
|
||||||
|
|
||||||
|
124
gui_frame_drag.c
124
gui_frame_drag.c
@ -15,8 +15,14 @@
|
|||||||
|
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
#include "gui_util.h"
|
#include "gui_util.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "gui_canvas.h"
|
||||||
#include "gui_frame_drag.h"
|
#include "gui_frame_drag.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include "icons/frame.xpm"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
target_id_var,
|
target_id_var,
|
||||||
@ -61,6 +67,12 @@ int is_dragging(void *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int is_dragging_anything(void)
|
||||||
|
{
|
||||||
|
return !!dragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- helper functions for indexed list and swapping -------------------- */
|
/* ----- helper functions for indexed list and swapping -------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -273,7 +285,7 @@ void setup_var_drag(struct var *var)
|
|||||||
box = box_of_label(var->widget);
|
box = box_of_label(var->widget);
|
||||||
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
||||||
&target_var, 1, GDK_ACTION_PRIVATE);
|
&target_var, 1, GDK_ACTION_PRIVATE);
|
||||||
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_HIGHLIGHT,
|
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_MOTION,
|
||||||
&target_var, 1, GDK_ACTION_PRIVATE);
|
&target_var, 1, GDK_ACTION_PRIVATE);
|
||||||
setup_drag_common(box, var);
|
setup_drag_common(box, var);
|
||||||
g_signal_connect(G_OBJECT(box), "drag-motion",
|
g_signal_connect(G_OBJECT(box), "drag-motion",
|
||||||
@ -342,7 +354,7 @@ void setup_value_drag(struct value *value)
|
|||||||
box = box_of_label(value->widget);
|
box = box_of_label(value->widget);
|
||||||
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
||||||
&target_value, 1, GDK_ACTION_PRIVATE);
|
&target_value, 1, GDK_ACTION_PRIVATE);
|
||||||
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_HIGHLIGHT,
|
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_MOTION,
|
||||||
&target_value, 1, GDK_ACTION_PRIVATE);
|
&target_value, 1, GDK_ACTION_PRIVATE);
|
||||||
setup_drag_common(box, value);
|
setup_drag_common(box, value);
|
||||||
g_signal_connect(G_OBJECT(box), "drag-motion",
|
g_signal_connect(G_OBJECT(box), "drag-motion",
|
||||||
@ -350,17 +362,66 @@ void setup_value_drag(struct value *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- frame to canvas helper functions ---------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static int frame_on_canvas = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void leave_canvas(void)
|
||||||
|
{
|
||||||
|
if (frame_on_canvas)
|
||||||
|
canvas_frame_end();
|
||||||
|
frame_on_canvas = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- drag frame labels ------------------------------------------------- */
|
/* ----- drag frame labels ------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setting our own icon looks nice but it slows things down to the point where
|
||||||
|
* cursor movements can lag noticeable and it adds yet another element to an
|
||||||
|
* already crowded cursor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void drag_frame_begin(GtkWidget *widget,
|
||||||
|
GtkTextDirection previous_direction, gpointer user_data)
|
||||||
|
{
|
||||||
|
GdkPixmap *pixmap;
|
||||||
|
GdkBitmap *mask;
|
||||||
|
GdkColormap *cmap;
|
||||||
|
|
||||||
|
pixmap = gdk_pixmap_create_from_xpm_d(DA, &mask, NULL, xpm_frame);
|
||||||
|
cmap = gdk_drawable_get_colormap(root->window);
|
||||||
|
gtk_drag_source_set_icon(widget, cmap, pixmap, mask);
|
||||||
|
g_object_unref(pixmap);
|
||||||
|
g_object_unref(mask);
|
||||||
|
|
||||||
|
dragging = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static gboolean drag_frame_motion(GtkWidget *widget,
|
static gboolean drag_frame_motion(GtkWidget *widget,
|
||||||
GdkDragContext *drag_context, gint x, gint y, guint time_,
|
GdkDragContext *drag_context, gint x, gint y, guint time_,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
if (!has_target(widget, drag_context, "frame"))
|
if (!has_target(widget, drag_context, "frame"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
//fprintf(stderr, "frame\n");
|
/* nothing else to do yet */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void drag_frame_end(GtkWidget *widget, GdkDragContext *drag_context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
leave_canvas();
|
||||||
|
drag_end(widget, drag_context, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -370,8 +431,17 @@ void setup_frame_drag(struct frame *frame)
|
|||||||
|
|
||||||
box = box_of_label(frame->label);
|
box = box_of_label(frame->label);
|
||||||
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
||||||
&target_frame, 1, GDK_ACTION_PRIVATE);
|
&target_frame, 1, GDK_ACTION_COPY);
|
||||||
setup_drag_common(box, frame);
|
setup_drag_common(box, frame);
|
||||||
|
|
||||||
|
/* override */
|
||||||
|
#if 0
|
||||||
|
g_signal_connect(G_OBJECT(box), "drag-begin",
|
||||||
|
G_CALLBACK(drag_frame_begin), frame);
|
||||||
|
#endif
|
||||||
|
g_signal_connect(G_OBJECT(box), "drag-end",
|
||||||
|
G_CALLBACK(drag_frame_end), frame);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(box), "drag-motion",
|
g_signal_connect(G_OBJECT(box), "drag-motion",
|
||||||
G_CALLBACK(drag_frame_motion), frame);
|
G_CALLBACK(drag_frame_motion), frame);
|
||||||
}
|
}
|
||||||
@ -386,16 +456,52 @@ static gboolean drag_canvas_motion(GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
if (!has_target(widget, drag_context, "frame"))
|
if (!has_target(widget, drag_context, "frame"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
//fprintf(stderr, "canvas\n");
|
gtk_drag_finish(drag_context, FALSE, FALSE, time_);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (!frame_on_canvas) {
|
||||||
|
frame_on_canvas = 1;
|
||||||
|
canvas_frame_begin(dragging);
|
||||||
|
}
|
||||||
|
if (canvas_frame_motion(dragging, x, y)) {
|
||||||
|
gdk_drag_status(drag_context, GDK_ACTION_COPY, time_);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
gdk_drag_status(drag_context, 0, time_);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void drag_canvas_leave(GtkWidget *widget, GdkDragContext *drag_context,
|
||||||
|
guint time_, gpointer user_data)
|
||||||
|
{
|
||||||
|
leave_canvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean drag_canvas_drop(GtkWidget *widget,
|
||||||
|
GdkDragContext *drag_context, gint x, gint y, guint time_,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (!has_target(widget, drag_context, "frame"))
|
||||||
|
return FALSE;
|
||||||
|
if (!canvas_frame_drop(dragging, x, y))
|
||||||
|
return FALSE;
|
||||||
|
gtk_drag_finish(drag_context, TRUE, FALSE, time_);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setup_canvas_drag(GtkWidget *canvas)
|
void setup_canvas_drag(GtkWidget *canvas)
|
||||||
{
|
{
|
||||||
gtk_drag_dest_set(canvas, GTK_DEST_DEFAULT_HIGHLIGHT,
|
gtk_drag_dest_set(canvas,
|
||||||
&target_frame, 1, GDK_ACTION_PRIVATE);
|
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
|
||||||
setup_drag_common(canvas, NULL);
|
&target_frame, 1, GDK_ACTION_COPY);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(canvas), "drag-motion",
|
g_signal_connect(G_OBJECT(canvas), "drag-motion",
|
||||||
G_CALLBACK(drag_canvas_motion), NULL);
|
G_CALLBACK(drag_canvas_motion), NULL);
|
||||||
|
g_signal_connect(G_OBJECT(canvas), "drag-leave",
|
||||||
|
G_CALLBACK(drag_canvas_leave), NULL);
|
||||||
|
g_signal_connect(G_OBJECT(canvas), "drag-drop",
|
||||||
|
G_CALLBACK(drag_canvas_drop), NULL);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
int is_dragging(void *this);
|
int is_dragging(void *this);
|
||||||
|
int is_dragging_anything(void);
|
||||||
|
|
||||||
void setup_var_drag(struct var *var);
|
void setup_var_drag(struct var *var);
|
||||||
void setup_value_drag(struct value *value);
|
void setup_value_drag(struct value *value);
|
||||||
|
75
gui_tool.c
75
gui_tool.c
@ -803,7 +803,7 @@ static struct inst *get_hover_inst(struct coord pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tool_hover(struct coord pos)
|
int tool_hover(struct coord pos)
|
||||||
{
|
{
|
||||||
struct inst *curr;
|
struct inst *curr;
|
||||||
|
|
||||||
@ -825,15 +825,84 @@ got:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (curr == hover_inst)
|
if (curr == hover_inst)
|
||||||
return;
|
return !!curr;
|
||||||
if (hover_inst) {
|
if (hover_inst) {
|
||||||
over_leave();
|
over_leave();
|
||||||
hover_inst = NULL;
|
hover_inst = NULL;
|
||||||
}
|
}
|
||||||
if (!curr)
|
if (!curr)
|
||||||
return;
|
return 0;
|
||||||
hover_inst = curr;
|
hover_inst = curr;
|
||||||
over_enter(hover_save_and_draw, NULL);
|
over_enter(hover_save_and_draw, NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- frame drag and drop ----------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When dragging a frame, we temporarily replace the selected tool (if any)
|
||||||
|
* with the frame tool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static struct tool_ops *pushed_ops;
|
||||||
|
|
||||||
|
|
||||||
|
void tool_push_frame(struct frame *frame)
|
||||||
|
{
|
||||||
|
pushed_ops = active_ops;
|
||||||
|
locked_frame = frame;
|
||||||
|
active_ops = &frame_ops;
|
||||||
|
/*
|
||||||
|
* We don't need to call tool_selected since, with drag and drop, the
|
||||||
|
* frame tools doesn't need activation anymore.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int do_place_frame(struct frame *frame, struct coord pos)
|
||||||
|
{
|
||||||
|
if (!get_hover_inst(pos))
|
||||||
|
return 0;
|
||||||
|
tool_consider_drag(pos);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gtk calls drag-leave, drag-end, and only then drag-drop. So we'll already
|
||||||
|
* have cleaned up in tool_pop_frame before we get here. In order to place the
|
||||||
|
* frame, we need to activate the frame tool again.
|
||||||
|
*
|
||||||
|
* @@@ bug: there's a tool_reset in this path, so we'll lose the widget of the
|
||||||
|
* tool that's really active. This problem will vanish when scrapping the
|
||||||
|
* old-style frame referenes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int tool_place_frame(struct frame *frame, struct coord pos)
|
||||||
|
{
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
active_ops = &frame_ops;
|
||||||
|
ok = do_place_frame(frame, pos);
|
||||||
|
active_ops = pushed_ops;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tool_pop_frame(void)
|
||||||
|
{
|
||||||
|
if (!active_tool)
|
||||||
|
return;
|
||||||
|
active_ops = pushed_ops;
|
||||||
|
/*
|
||||||
|
* We don't need to call tool_selected since the only tool that could
|
||||||
|
* use this would be the delete tool, and there the semantics would be
|
||||||
|
* undesirable. Also, the delete tool never stays active, so it can't
|
||||||
|
* appear together with drag and drop anyway.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ struct pix_buf *gui_hover_frame(struct inst *self);
|
|||||||
void do_move_to_arc(struct inst *inst, struct inst *to, int i);
|
void do_move_to_arc(struct inst *inst, struct inst *to, int i);
|
||||||
|
|
||||||
void tool_dehover(void);
|
void tool_dehover(void);
|
||||||
void tool_hover(struct coord pos);
|
int tool_hover(struct coord pos);
|
||||||
const char *tool_tip(struct coord pos);
|
const char *tool_tip(struct coord pos);
|
||||||
int tool_consider_drag(struct coord pos);
|
int tool_consider_drag(struct coord pos);
|
||||||
void tool_drag(struct coord to);
|
void tool_drag(struct coord to);
|
||||||
@ -73,6 +73,10 @@ struct pix_buf *drag_new_line(struct inst *from, struct coord to);
|
|||||||
void tool_frame_update(void);
|
void tool_frame_update(void);
|
||||||
void tool_frame_deleted(const struct frame *frame);
|
void tool_frame_deleted(const struct frame *frame);
|
||||||
|
|
||||||
|
void tool_push_frame(struct frame *frame);
|
||||||
|
int tool_place_frame(struct frame *frame, struct coord pos);
|
||||||
|
void tool_pop_frame(void);
|
||||||
|
|
||||||
void tool_selected_inst(struct inst *inst);
|
void tool_selected_inst(struct inst *inst);
|
||||||
|
|
||||||
GtkWidget *get_icon_by_inst(const struct inst *inst);
|
GtkWidget *get_icon_by_inst(const struct inst *inst);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user