r5930 - trunk/eda/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Sat Apr 24 00:01:56 CEST 2010
Author: werner
Date: 2010-04-24 00:01:56 +0200 (Sat, 24 Apr 2010)
New Revision: 5930
Modified:
trunk/eda/fped/gui_canvas.c
trunk/eda/fped/gui_frame.c
trunk/eda/fped/gui_frame_drag.c
trunk/eda/fped/gui_frame_drag.h
Log:
Working towards the dragging of frames. Changed the press/drag/release logic of
tables such that items are selected on release and we can thus drag without
selecting. (From a user point of view, selecting would be fine. But selecting
may sometimes cause a change_world or similar, destroying the widget, which
upsets drag and drop.)
- gui_frame_drag.c (setup_var_drag, setup_value_drag): moved targets to file
scope
- gui_frame_drag.c (has_target, drag_var_motion, drag_value_motion): Gtk
doesn't check target compatibility for us, so we have to do this explicitly
- gui_frame_drag.c (drag_begin): don't leak the pixbuf
- gui_frame_drag.c (is_dragging, drag_end), gui_frame_drag.h: for drag vs.
activations on button release, we now can test what is being dragged. For
this, we have to explicitly clear the variable "dragging" when done.
- gui_frame_drag.c (setup_var_drag, setup_value_drag): moved common setup to
setup_drag_common
- gui_frame_drag.c (setup_frame_drag, drag_frame_motion), gui_frame_drag.h,
gui_frame.c (frame_select_event, build_frame_label): added infrastructure for
dragging frames
- gui_frame_drag.c (setup_canvas_drag, drag_canvas_motion), gui_frame_drag.h,
gui_canvas.c (motion_notify_event, make_canvas): added infrastructure for
dragging to the canvas
- gui_frame.c (table_var_select_event, table_value_select_event, build_table):
split logic into press and release action, so that we can drag without
implicitly selecting
Modified: trunk/eda/fped/gui_canvas.c
===================================================================
--- trunk/eda/fped/gui_canvas.c 2010-04-23 13:43:19 UTC (rev 5929)
+++ trunk/eda/fped/gui_canvas.c 2010-04-23 22:01:56 UTC (rev 5930)
@@ -24,6 +24,7 @@
#include "gui_status.h"
#include "gui_tool.h"
#include "gui.h"
+#include "gui_frame_drag.h"
#include "gui_canvas.h"
@@ -182,7 +183,7 @@
if (event->state & GDK_BUTTON2_MASK)
drag_middle(pos);
update_pos(pos);
- return TRUE;
+ return FALSE;
}
@@ -541,6 +542,8 @@
gtk_widget_set_double_buffered(canvas, FALSE);
+ setup_canvas_drag(canvas);
+
draw_ctx.widget = canvas;
return canvas;
Modified: trunk/eda/fped/gui_frame.c
===================================================================
--- trunk/eda/fped/gui_frame.c 2010-04-23 13:43:19 UTC (rev 5929)
+++ trunk/eda/fped/gui_frame.c 2010-04-23 22:01:56 UTC (rev 5930)
@@ -886,30 +886,59 @@
}
-static gboolean table_var_select_event(GtkWidget *widget,
+static gboolean table_var_press_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
struct var *var = data;
switch (event->button) {
+ case 3:
+ pop_up_table_var(var, event);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean table_var_release_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct var *var = data;
+
+ switch (event->button) {
case 1:
+ if (is_dragging(var))
+ return FALSE;
edit_var(var, set_col_values, var, -1);
- return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean table_value_press_event(GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
+{
+ struct value *value = data;
+
+ switch (event->button) {
case 3:
- pop_up_table_var(var, event);
- break;
+ pop_up_table_value(value, event);
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
-static gboolean table_value_select_event(GtkWidget *widget,
+static gboolean table_value_release_event(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
struct value *value = data;
switch (event->button) {
case 1:
+ if (is_dragging(value))
+ return FALSE;
if (!value->row ||
value->row->table->active_row == value->row) {
edit_nothing();
@@ -919,12 +948,9 @@
select_row(value->row);
change_world();
}
- return FALSE;
- case 3:
- pop_up_table_value(value, event);
- break;
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
@@ -1009,8 +1035,11 @@
label_in_box_bg(field, COLOR_VAR_PASSIVE);
g_signal_connect(G_OBJECT(box_of_label(field)),
"button_press_event",
- G_CALLBACK(table_var_select_event), var);
+ G_CALLBACK(table_var_press_event), var);
g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_release_event",
+ G_CALLBACK(table_var_release_event), var);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
"scroll_event",
G_CALLBACK(table_scroll_event), table);
var->widget = field;
@@ -1034,8 +1063,11 @@
COLOR_ROW_SELECTED : COLOR_ROW_UNSELECTED);
g_signal_connect(G_OBJECT(box_of_label(field)),
"button_press_event",
- G_CALLBACK(table_value_select_event), value);
+ G_CALLBACK(table_value_press_event), value);
g_signal_connect(G_OBJECT(box_of_label(field)),
+ "button_release_event",
+ G_CALLBACK(table_value_release_event), value);
+ g_signal_connect(G_OBJECT(box_of_label(field)),
"scroll_event",
G_CALLBACK(table_scroll_event), table);
value->widget = field;
@@ -1653,13 +1685,29 @@
}
-static gboolean frame_select_event(GtkWidget *widget, GdkEventButton *event,
+static gboolean frame_press_event(GtkWidget *widget, GdkEventButton *event,
gpointer data)
{
struct frame *frame = data;
switch (event->button) {
+ case 3:
+ pop_up_frame(frame, event);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean frame_release_event(GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ struct frame *frame = data;
+
+ switch (event->button) {
case 1:
+ if (is_dragging(frame))
+ return FALSE;
if (active_frame != frame)
select_frame(frame);
else {
@@ -1668,12 +1716,9 @@
edit_frame(frame);
}
}
- break;
- case 3:
- pop_up_frame(frame, event);
- break;
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
@@ -1691,9 +1736,13 @@
COLOR_FRAME_SELECTED : COLOR_FRAME_UNSELECTED);
g_signal_connect(G_OBJECT(box_of_label(label)),
- "button_press_event", G_CALLBACK(frame_select_event), frame);
+ "button_press_event", G_CALLBACK(frame_press_event), frame);
+ g_signal_connect(G_OBJECT(box_of_label(label)),
+ "button_release_event", G_CALLBACK(frame_release_event), frame);
frame->label = label;
+ setup_frame_drag(frame);
+
return box_of_label(label);
}
Modified: trunk/eda/fped/gui_frame_drag.c
===================================================================
--- trunk/eda/fped/gui_frame_drag.c 2010-04-23 13:43:19 UTC (rev 5929)
+++ trunk/eda/fped/gui_frame_drag.c 2010-04-23 22:01:56 UTC (rev 5930)
@@ -18,12 +18,49 @@
#include "gui_frame_drag.h"
+enum {
+ target_id_var,
+ target_id_value,
+ target_id_frame,
+ target_id_canvas,
+};
+
+
+static GtkTargetEntry target_var = {
+ .target = "var",
+ .flags = GTK_TARGET_SAME_APP,
+ .info = target_id_var,
+};
+
+static GtkTargetEntry target_value = {
+ .target = "value",
+ .flags = GTK_TARGET_SAME_APP,
+ .info = target_id_value,
+};
+
+static GtkTargetEntry target_frame = {
+ .target = "frame",
+ .flags = GTK_TARGET_SAME_APP,
+ .info = target_id_frame,
+};
+
+
+/* ----- dragging status --------------------------------------------------- */
+
+
/*
- * Pointer to whatever it is we're dragging. Undefined if not dragging.
+ * Pointer to whatever it is we're dragging. NULL if not dragging.
*/
+
static void *dragging;
+int is_dragging(void *this)
+{
+ return this == dragging;
+}
+
+
/* ----- helper functions for indexed list and swapping -------------------- */
@@ -148,9 +185,29 @@
}
-/* ----- common callback --------------------------------------------------- */
+/* ----- common functions -------------------------------------------------- */
+/*
+ * according to
+ * http://www.pubbs.net/201004/gtk/22819-re-drag-and-drop-drag-motion-cursor-lockup-fixed-.html
+ * http://www.cryingwolf.org/articles/gtk-dnd.html
+ */
+
+static int has_target(GtkWidget *widget, GdkDragContext *drag_context,
+ const char *name)
+{
+ GdkAtom target;
+
+ target = gtk_drag_dest_find_target(widget, drag_context, NULL);
+
+ /*
+ * Force allocation so that we don't have to check for GDK_NONE.
+ */
+ return target == gdk_atom_intern(name, FALSE);
+}
+
+
static void drag_begin(GtkWidget *widget,
GtkTextDirection previous_direction, gpointer user_data)
{
@@ -163,11 +220,28 @@
pixbuf =
gdk_pixbuf_get_from_drawable(NULL, DA, NULL, 0, 0, 0, 0, 1, 1);
gtk_drag_source_set_icon_pixbuf(widget, pixbuf);
+ g_object_unref(pixbuf);
dragging = user_data;
}
+static void drag_end(GtkWidget *widget, GdkDragContext *drag_context,
+ gpointer user_data)
+{
+ dragging = NULL;
+}
+
+
+static void setup_drag_common(GtkWidget *widget, void *user_arg)
+{
+ g_signal_connect(G_OBJECT(widget), "drag-begin",
+ G_CALLBACK(drag_begin), user_arg);
+ g_signal_connect(G_OBJECT(widget), "drag-end",
+ G_CALLBACK(drag_end), user_arg);
+}
+
+
/* ----- drag variables ---------------------------------------------------- */
@@ -179,6 +253,8 @@
struct var *to = user_data;
int from_n, to_n, i;
+ if (!has_target(widget, drag_context, "var"))
+ return FALSE;
if (from == to || from->table != to->table)
return FALSE;
from_n = NDX(from->table->vars, from);
@@ -192,19 +268,14 @@
void setup_var_drag(struct var *var)
{
- static GtkTargetEntry target = {
- .target = "var",
- .flags = GTK_TARGET_SAME_APP,
- };
GtkWidget *box;
box = box_of_label(var->widget);
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
- &target, 1, GDK_ACTION_PRIVATE);
+ &target_var, 1, GDK_ACTION_PRIVATE);
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_HIGHLIGHT,
- &target, 1, GDK_ACTION_PRIVATE);
- g_signal_connect(G_OBJECT(box), "drag-begin",
- G_CALLBACK(drag_begin), var);
+ &target_var, 1, GDK_ACTION_PRIVATE);
+ setup_drag_common(box, var);
g_signal_connect(G_OBJECT(box), "drag-motion",
G_CALLBACK(drag_var_motion), var);
}
@@ -219,10 +290,13 @@
{
struct value *from = dragging;
struct value *to = user_data;
- struct table *table = from->row->table;
+ struct table *table;
struct row **row, *end;
int from_n, to_n, i;
+ if (!has_target(widget, drag_context, "value"))
+ return FALSE;
+ table = from->row->table;
if (table != to->row->table)
return FALSE;
@@ -263,19 +337,65 @@
void setup_value_drag(struct value *value)
{
- static GtkTargetEntry target = {
- .target = "value",
- .flags = GTK_TARGET_SAME_APP,
- };
GtkWidget *box;
box = box_of_label(value->widget);
gtk_drag_source_set(box, GDK_BUTTON1_MASK,
- &target, 1, GDK_ACTION_PRIVATE);
+ &target_value, 1, GDK_ACTION_PRIVATE);
gtk_drag_dest_set(box, GTK_DEST_DEFAULT_HIGHLIGHT,
- &target, 1, GDK_ACTION_PRIVATE);
- g_signal_connect(G_OBJECT(box), "drag-begin",
- G_CALLBACK(drag_begin), value);
+ &target_value, 1, GDK_ACTION_PRIVATE);
+ setup_drag_common(box, value);
g_signal_connect(G_OBJECT(box), "drag-motion",
G_CALLBACK(drag_value_motion), value);
}
+
+
+/* ----- drag frame labels ------------------------------------------------- */
+
+
+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");
+return FALSE;
+}
+
+
+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);
+ setup_drag_common(box, frame);
+ g_signal_connect(G_OBJECT(box), "drag-motion",
+ G_CALLBACK(drag_frame_motion), frame);
+}
+
+
+/* ----- drag to the canvas ------------------------------------------------ */
+
+
+static gboolean drag_canvas_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, "canvas\n");
+return FALSE;
+}
+
+
+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);
+ g_signal_connect(G_OBJECT(canvas), "drag-motion",
+ G_CALLBACK(drag_canvas_motion), NULL);
+}
Modified: trunk/eda/fped/gui_frame_drag.h
===================================================================
--- trunk/eda/fped/gui_frame_drag.h 2010-04-23 13:43:19 UTC (rev 5929)
+++ trunk/eda/fped/gui_frame_drag.h 2010-04-23 22:01:56 UTC (rev 5930)
@@ -19,7 +19,11 @@
#include "obj.h"
+int is_dragging(void *this);
+
void setup_var_drag(struct var *var);
void setup_value_drag(struct value *value);
+void setup_frame_drag(struct frame *frame);
+void setup_canvas_drag(GtkWidget *canvas);
#endif /* !GUI_FRAME_DRAG_H */
More information about the commitlog
mailing list