mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-24 11:10:36 +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 ------------------------------------------ */
|
||||
|
||||
|
||||
@ -254,6 +289,8 @@ static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
|
||||
DPRINTF("--- button release ---");
|
||||
switch (event->button) {
|
||||
case 1:
|
||||
if (is_dragging_anything())
|
||||
return FALSE;
|
||||
if (!dragging)
|
||||
break;
|
||||
drag_left(pos);
|
||||
@ -448,8 +485,9 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
|
||||
static gboolean enter_notify_event(GtkWidget *widget, GdkEventCrossing *event,
|
||||
gpointer data)
|
||||
{
|
||||
DPRINTF("--- enter ---");
|
||||
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_dehover();
|
||||
dragging = 0;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* gui_canvas.h - GUI, canvas
|
||||
*
|
||||
* Written 2009 by Werner Almesberger
|
||||
* Copyright 2009 by Werner Almesberger
|
||||
* Written 2009, 2010 by Werner Almesberger
|
||||
* Copyright 2009, 2010 by Werner Almesberger
|
||||
*
|
||||
* 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
|
||||
@ -34,6 +34,11 @@ void zoom_out_center(void);
|
||||
void zoom_to_frame(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);
|
||||
void init_canvas(void);
|
||||
|
||||
|
122
gui_frame_drag.c
122
gui_frame_drag.c
@ -15,8 +15,14 @@
|
||||
|
||||
#include "obj.h"
|
||||
#include "gui_util.h"
|
||||
#include "gui.h"
|
||||
#include "gui_canvas.h"
|
||||
#include "gui_frame_drag.h"
|
||||
|
||||
#if 0
|
||||
#include "icons/frame.xpm"
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
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 -------------------- */
|
||||
|
||||
|
||||
@ -273,7 +285,7 @@ void setup_var_drag(struct var *var)
|
||||
box = box_of_label(var->widget);
|
||||
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
||||
&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);
|
||||
setup_drag_common(box, var);
|
||||
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);
|
||||
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
|
||||
&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);
|
||||
setup_drag_common(box, value);
|
||||
g_signal_connect(G_OBJECT(box), "drag-motion",
|
||||
@ -350,28 +362,86 @@ 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 ------------------------------------------------- */
|
||||
|
||||
|
||||
#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,
|
||||
GdkDragContext *drag_context, gint x, gint y, guint time_,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!has_target(widget, drag_context, "frame"))
|
||||
return FALSE;
|
||||
//fprintf(stderr, "frame\n");
|
||||
/* nothing else to do yet */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void drag_frame_end(GtkWidget *widget, GdkDragContext *drag_context,
|
||||
gpointer user_data)
|
||||
{
|
||||
leave_canvas();
|
||||
drag_end(widget, drag_context, user_data);
|
||||
}
|
||||
|
||||
|
||||
void setup_frame_drag(struct frame *frame)
|
||||
{
|
||||
GtkWidget *box;
|
||||
|
||||
box = box_of_label(frame->label);
|
||||
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);
|
||||
|
||||
/* 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_CALLBACK(drag_frame_motion), frame);
|
||||
}
|
||||
@ -386,16 +456,52 @@ static gboolean drag_canvas_motion(GtkWidget *widget,
|
||||
{
|
||||
if (!has_target(widget, drag_context, "frame"))
|
||||
return FALSE;
|
||||
//fprintf(stderr, "canvas\n");
|
||||
gtk_drag_finish(drag_context, FALSE, FALSE, time_);
|
||||
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)
|
||||
{
|
||||
gtk_drag_dest_set(canvas, GTK_DEST_DEFAULT_HIGHLIGHT,
|
||||
&target_frame, 1, GDK_ACTION_PRIVATE);
|
||||
setup_drag_common(canvas, NULL);
|
||||
gtk_drag_dest_set(canvas,
|
||||
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
|
||||
&target_frame, 1, GDK_ACTION_COPY);
|
||||
|
||||
g_signal_connect(G_OBJECT(canvas), "drag-motion",
|
||||
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_anything(void);
|
||||
|
||||
void setup_var_drag(struct var *var);
|
||||
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;
|
||||
|
||||
@ -825,15 +825,84 @@ got:
|
||||
#endif
|
||||
|
||||
if (curr == hover_inst)
|
||||
return;
|
||||
return !!curr;
|
||||
if (hover_inst) {
|
||||
over_leave();
|
||||
hover_inst = NULL;
|
||||
}
|
||||
if (!curr)
|
||||
return;
|
||||
return 0;
|
||||
hover_inst = curr;
|
||||
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 tool_dehover(void);
|
||||
void tool_hover(struct coord pos);
|
||||
int tool_hover(struct coord pos);
|
||||
const char *tool_tip(struct coord pos);
|
||||
int tool_consider_drag(struct coord pos);
|
||||
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_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);
|
||||
|
||||
GtkWidget *get_icon_by_inst(const struct inst *inst);
|
||||
|
Loading…
Reference in New Issue
Block a user