app: move process_event_queue() and flush_event_queue() to GimpMotionBuffer

and emit the buffer's "motion" signal when a motion is supposed
to happen. In GimpDisplayShell, connect to GimpMotionBuffer::motion()
and call the tool.
This commit is contained in:
Michael Natterer 2011-04-17 21:46:29 +02:00
parent d784ca0a59
commit 334e4c5d71
6 changed files with 143 additions and 116 deletions

View File

@ -54,6 +54,7 @@ VOID: OBJECT, POINTER
VOID: POINTER
VOID: POINTER, BOXED
VOID: POINTER, ENUM
VOID: POINTER, UINT, FLAGS
VOID: STRING
VOID: STRING, BOOLEAN, UINT, FLAGS
VOID: STRING, FLAGS

View File

@ -110,11 +110,6 @@ static void gimp_display_shell_untransform_event_coords (GimpDisplayShell
static void gimp_display_shell_toggle_hide_docks (GimpDisplayShell *shell);
static gboolean gimp_display_shell_flush_event_queue (GimpDisplayShell *shell);
static void gimp_display_shell_process_event_queue (GimpDisplayShell *shell,
GdkModifierType state,
guint32 time);
static GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
@ -663,7 +658,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{
if (gimp_tool_control_is_active (active_tool->control))
{
gimp_display_shell_flush_event_queue (shell);
gimp_motion_buffer_flush_event_queue (shell->motion_buffer);
tool_manager_button_release_active (gimp,
&image_coords,
@ -929,7 +924,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
TRUE,
history_events[i]->time))
{
gimp_display_shell_process_event_queue (shell,
gimp_motion_buffer_process_event_queue (shell->motion_buffer,
state,
history_events[i]->time);
}
@ -950,7 +945,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
event_fill,
time))
{
gimp_display_shell_process_event_queue (shell,
gimp_motion_buffer_process_event_queue (shell->motion_buffer,
state,
time);
}
@ -1216,6 +1211,28 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
return return_val;
}
void
gimp_display_shell_buffer_motion (GimpMotionBuffer *buffer,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplayShell *shell)
{
GimpDisplay *display = shell->display;
Gimp *gimp = gimp_display_get_gimp (display);
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimp);
if (active_tool &&
gimp_tool_control_is_active (active_tool->control))
{
tool_manager_motion_active (gimp,
coords, time, state,
display);
}
}
static gboolean
gimp_display_shell_ruler_button_press (GtkWidget *widget,
GdkEventButton *event,
@ -1716,95 +1733,6 @@ gimp_display_shell_untransform_event_coords (GimpDisplayShell *shell,
}
}
/* Event delay timeout handler & generic event flusher */
static gboolean
gimp_display_shell_flush_event_queue (GimpDisplayShell *shell)
{
GimpTool *active_tool = tool_manager_get_active (shell->display->gimp);
shell->motion_buffer->event_delay = FALSE;
/* Remove the timeout explicitly because this function might be
* called directly (not via the timeout)
*/
if (shell->motion_buffer->event_delay_timeout)
{
g_source_remove (shell->motion_buffer->event_delay_timeout);
shell->motion_buffer->event_delay_timeout = 0;
}
if (active_tool &&
gimp_tool_control_is_active (active_tool->control) &&
shell->motion_buffer->event_queue->len > 0)
{
GimpCoords last_coords = g_array_index (shell->motion_buffer->event_queue,
GimpCoords,
shell->motion_buffer->event_queue->len - 1);
gimp_motion_buffer_push_event_history (shell->motion_buffer, &last_coords);
gimp_display_shell_process_event_queue (shell,
shell->motion_buffer->last_active_state,
shell->motion_buffer->last_read_motion_time);
}
/* Return false so a potential timeout calling it gets removed */
return FALSE;
}
static void
gimp_display_shell_process_event_queue (GimpDisplayShell *shell,
GdkModifierType state,
guint32 time)
{
GdkModifierType event_state;
gint keep = 0;
if (shell->motion_buffer->event_delay)
{
/* If we are in delay we use LAST state, not current */
event_state = shell->motion_buffer->last_active_state;
keep = 1; /* Holding one event in buf */
}
else
{
/* Save the state */
event_state = state;
}
if (shell->motion_buffer->event_delay_timeout)
{
g_source_remove (shell->motion_buffer->event_delay_timeout);
shell->motion_buffer->event_delay_timeout = 0;
}
shell->motion_buffer->last_active_state = state;
while (shell->motion_buffer->event_queue->len > keep)
{
GimpCoords buf_coords;
gimp_motion_buffer_pop_event_queue (shell->motion_buffer,
&buf_coords);
tool_manager_motion_active (shell->display->gimp,
&buf_coords,
time,
event_state,
shell->display);
}
if (shell->motion_buffer->event_delay)
{
shell->motion_buffer->event_delay_timeout =
g_timeout_add (50,
(GSourceFunc) gimp_display_shell_flush_event_queue,
shell);
}
}
/* gimp_display_shell_compress_motion:
*
* This function walks the whole GDK event queue seeking motion events

View File

@ -26,6 +26,11 @@ gboolean gimp_display_shell_events (GtkWidget *widget,
gboolean gimp_display_shell_canvas_tool_events (GtkWidget *widget,
GdkEvent *event,
GimpDisplayShell *shell);
void gimp_display_shell_buffer_motion (GimpMotionBuffer *buffer,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplayShell *shell);
gboolean gimp_display_shell_hruler_button_press (GtkWidget *widget,
GdkEventButton *bevent,

View File

@ -307,6 +307,10 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->motion_buffer = gimp_motion_buffer_new ();
g_signal_connect (shell->motion_buffer, "motion",
G_CALLBACK (gimp_display_shell_buffer_motion),
shell);
shell->zoom_focus_pointer_queue = g_queue_new ();
gtk_widget_set_events (GTK_WIDGET (shell), (GDK_POINTER_MOTION_MASK |

View File

@ -90,8 +90,11 @@ gimp_motion_buffer_class_init (GimpMotionBufferClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpMotionBufferClass, motion),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_marshal_VOID__POINTER_UINT_FLAGS,
G_TYPE_NONE, 3,
G_TYPE_POINTER,
G_TYPE_UINT,
GDK_TYPE_MODIFIER_TYPE);
object_class->constructed = gimp_motion_buffer_constructed;
object_class->dispose = gimp_motion_buffer_dispose;
@ -179,8 +182,8 @@ gimp_motion_buffer_new (void)
}
/**
* gimp_display_shell_eval_event:
* @shell:
* gimp_motion_buffer_eval_event:
* @buffer:
* @coords:
* @inertia_factor:
* @time:
@ -412,6 +415,85 @@ gimp_motion_buffer_pop_event_queue (GimpMotionBuffer *buffer,
g_array_remove_index (buffer->event_queue, 0);
}
void
gimp_motion_buffer_process_event_queue (GimpMotionBuffer *buffer,
GdkModifierType state,
guint32 time)
{
GdkModifierType event_state;
gint keep = 0;
if (buffer->event_delay)
{
/* If we are in delay we use LAST state, not current */
event_state = buffer->last_active_state;
keep = 1; /* Holding one event in buf */
}
else
{
/* Save the state */
event_state = state;
}
if (buffer->event_delay_timeout)
{
g_source_remove (buffer->event_delay_timeout);
buffer->event_delay_timeout = 0;
}
buffer->last_active_state = state;
while (buffer->event_queue->len > keep)
{
GimpCoords buf_coords;
gimp_motion_buffer_pop_event_queue (buffer, &buf_coords);
g_signal_emit (buffer, motion_buffer_signals[MOTION], 0,
&buf_coords, time, event_state);
}
if (buffer->event_delay)
{
buffer->event_delay_timeout =
g_timeout_add (50,
(GSourceFunc) gimp_motion_buffer_flush_event_queue,
buffer);
}
}
gboolean
gimp_motion_buffer_flush_event_queue (GimpMotionBuffer *buffer)
{
buffer->event_delay = FALSE;
/* Remove the timeout explicitly because this function might be
* called directly (not via the timeout)
*/
if (buffer->event_delay_timeout)
{
g_source_remove (buffer->event_delay_timeout);
buffer->event_delay_timeout = 0;
}
if (buffer->event_queue->len > 0)
{
GimpCoords last_coords = g_array_index (buffer->event_queue,
GimpCoords,
buffer->event_queue->len - 1);
gimp_motion_buffer_push_event_history (buffer, &last_coords);
gimp_motion_buffer_process_event_queue (buffer,
buffer->last_active_state,
buffer->last_read_motion_time);
}
/* Return false so a potential timeout calling it gets removed */
return FALSE;
}
/* private functions */

View File

@ -62,26 +62,33 @@ struct _GimpMotionBufferClass
{
GtkBoxClass parent_class;
void (* motion) (GimpMotionBuffer *buffer,
const GimpCoords *coords,
guint32 time);
void (* motion) (GimpMotionBuffer *buffer,
const GimpCoords *coords,
guint32 time,
GdkModifierType state);
};
GType gimp_motion_buffer_get_type (void) G_GNUC_CONST;
GType gimp_motion_buffer_get_type (void) G_GNUC_CONST;
GimpMotionBuffer * gimp_motion_buffer_new (void);
GimpMotionBuffer * gimp_motion_buffer_new (void);
gboolean gimp_motion_buffer_eval_event (GimpMotionBuffer *buffer,
gdouble scale_x,
gdouble scale_y,
GimpCoords *coords,
gboolean event_fill,
guint32 time);
void gimp_motion_buffer_push_event_history (GimpMotionBuffer *buffer,
const GimpCoords *coords);
void gimp_motion_buffer_pop_event_queue (GimpMotionBuffer *buffer,
GimpCoords *coords);
gboolean gimp_motion_buffer_eval_event (GimpMotionBuffer *buffer,
gdouble scale_x,
gdouble scale_y,
GimpCoords *coords,
gboolean event_fill,
guint32 time);
void gimp_motion_buffer_push_event_history (GimpMotionBuffer *buffer,
const GimpCoords *coords);
void gimp_motion_buffer_pop_event_queue (GimpMotionBuffer *buffer,
GimpCoords *coords);
void gimp_motion_buffer_process_event_queue (GimpMotionBuffer *buffer,
GdkModifierType state,
guint32 time);
gboolean gimp_motion_buffer_flush_event_queue (GimpMotionBuffer *buffer);
#endif /* __GIMP_MOTION_BUFFER_H__ */