diff options
Diffstat (limited to 'widgets/e-text')
-rw-r--r-- | widgets/e-text/e-text-event-processor-emacs-like.c | 7 | ||||
-rw-r--r-- | widgets/e-text/e-text.c | 115 | ||||
-rw-r--r-- | widgets/e-text/e-text.h | 11 |
3 files changed, 127 insertions, 6 deletions
diff --git a/widgets/e-text/e-text-event-processor-emacs-like.c b/widgets/e-text/e-text-event-processor-emacs-like.c index 1d7d36d45f..6c7c86afdc 100644 --- a/widgets/e-text/e-text-event-processor-emacs-like.c +++ b/widgets/e-text/e-text-event-processor-emacs-like.c @@ -241,10 +241,9 @@ e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventPro } break; case GDK_Tab: - command.action = E_TEP_INSERT; + /* Don't insert literally */ + command.action = E_TEP_NOP; command.position = E_TEP_SELECTION; - command.value = 1; - command.string = "\t"; break; case GDK_Return: if (key.state & GDK_CONTROL_MASK) { @@ -258,9 +257,9 @@ e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventPro } break; case GDK_Escape: + /* Don't insert literally */ command.action = E_TEP_NOP; command.position = E_TEP_SELECTION; - /* Don't insert literally */ break; default: diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c index f6daa3f3cf..e4e8e11f9b 100644 --- a/widgets/e-text/e-text.c +++ b/widgets/e-text/e-text.c @@ -223,6 +223,19 @@ e_text_init (EText *text) text->selection_start = 0; text->selection_end = 0; text->select_by_word = FALSE; + + text->timeout_id = 0; + text->timer = NULL; + + text->lastx = 0; + text->lasty = 0; + text->last_state = 0; + + text->scroll_start = 0; + text->show_cursor = TRUE; + text->button_down = FALSE; + + text->tep = NULL; } /* Destroy handler for the text item */ @@ -239,6 +252,9 @@ e_text_destroy (GtkObject *object) if (text->text) g_free (text->text); + if (text->tep) + gtk_object_unref (GTK_OBJECT(text->tep)); + if (text->lines) g_free (text->lines); @@ -1049,11 +1065,12 @@ _get_tep(EText *text) { if (!text->tep) { text->tep = e_text_event_processor_emacs_like_new(); + gtk_object_ref (GTK_OBJECT (text->tep)); + gtk_object_sink (GTK_OBJECT (text->tep)); gtk_signal_connect(GTK_OBJECT(text->tep), "command", GTK_SIGNAL_FUNC(e_text_command), (gpointer) text); - } } @@ -1165,7 +1182,8 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable, } if (text->selection_start == text->selection_end && text->selection_start >= start_char && - text->selection_start <= end_char) { + text->selection_start <= end_char && + text->show_cursor) { gdk_draw_rectangle (drawable, text->gc, TRUE, @@ -1460,6 +1478,7 @@ _get_position_from_xy (EText *text, gint x, gint y) i = 0; lines = text->lines; lines += j; + x += text->xofs_edit; xpos = get_line_xpos (text, lines); for(i = 0; i < lines->length; i++) { int charwidth = gdk_text_width(text->font, @@ -1473,6 +1492,69 @@ _get_position_from_xy (EText *text, gint x, gint y) return lines->text + i - text->text; } +#define SCROLL_WAIT_TIME 30000 + +static gboolean +_blink_scroll_timeout (gpointer data) +{ + EText *text = E_TEXT(data); + gulong current_time; + gboolean scroll = FALSE; + gboolean redraw = FALSE; + + g_timer_elapsed(text->timer, ¤t_time); + + if (text->scroll_start + SCROLL_WAIT_TIME > 1000000) { + if (current_time > text->scroll_start - (1000000 - SCROLL_WAIT_TIME) && + current_time < text->scroll_start) + scroll = TRUE; + } else { + if (current_time > text->scroll_start + SCROLL_WAIT_TIME || + current_time < text->scroll_start) + scroll = TRUE; + } + if (scroll && text->button_down) { + if (text->lastx - text->clip_cx > text->clip_cwidth && + text->xofs_edit < text->max_width - text->clip_cwidth) { + text->xofs_edit += 4; + if (text->xofs_edit > text->max_width - text->clip_cwidth) + text->xofs_edit = text->max_width - text->clip_cwidth; + redraw = TRUE; + } + if (text->lastx - text->clip_cx < 0 && + text->xofs_edit > 0) { + text->xofs_edit -= 4; + if (text->xofs_edit < 0) + text->xofs_edit = 0; + redraw = TRUE; + } + if (redraw) { + ETextEventProcessorEvent e_tep_event; + e_tep_event.type = GDK_MOTION_NOTIFY; + e_tep_event.motion.state = text->last_state; + e_tep_event.motion.time = 0; + e_tep_event.motion.position = _get_position_from_xy(text, text->lastx, text->lasty); + _get_tep(text); + e_text_event_processor_handle_event (text->tep, + &e_tep_event); + text->scroll_start = current_time; + } + } + + if (!((current_time / 500000) % 2)) { + if (!text->show_cursor) + redraw = TRUE; + text->show_cursor = TRUE; + } else { + if (text->show_cursor) + redraw = TRUE; + text->show_cursor = FALSE; + } + if (redraw) + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text)); + return TRUE; +} + static gint e_text_event (GnomeCanvasItem *item, GdkEvent *event) { @@ -1494,9 +1576,23 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) text->selection_end = 0; text->select_by_word = FALSE; text->xofs_edit = 0; + if (text->timeout_id == 0) + text->timeout_id = g_timeout_add(10, _blink_scroll_timeout, text); + text->timer = g_timer_new(); + g_timer_elapsed(text->timer, &(text->scroll_start)); + g_timer_start(text->timer); } } else { text->editing = FALSE; + if (text->timeout_id) { + g_source_remove(text->timeout_id); + text->timeout_id = 0; + } + if (text->timer) { + g_timer_stop(text->timer); + g_timer_destroy(text->timer); + text->timer = NULL; + } } calc_line_widths (text); } @@ -1529,6 +1625,18 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) _get_tep(text); return_val = e_text_event_processor_handle_event (text->tep, &e_tep_event); + if (event->button.button == 1) { + if (event->type == GDK_BUTTON_PRESS) + text->button_down = TRUE; + else + text->button_down = FALSE; + } + text->lastx = button.x; + text->lasty = button.y; + text->last_state = button.state; + if (event->type == GDK_BUTTON_PRESS && text->timer) { + g_timer_reset(text->timer); + } } else if (text->editable && event->type == GDK_BUTTON_RELEASE) { gnome_canvas_item_grab_focus (item); return 1; @@ -1543,6 +1651,9 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) _get_tep(text); return_val = e_text_event_processor_handle_event (text->tep, &e_tep_event); + text->lastx = motion.x; + text->lasty = motion.y; + text->last_state = motion.state; } break; default: diff --git a/widgets/e-text/e-text.h b/widgets/e-text/e-text.h index b18b93d7f2..23713563c3 100644 --- a/widgets/e-text/e-text.h +++ b/widgets/e-text/e-text.h @@ -148,6 +148,17 @@ struct _EText { int selection_end; /* End of selection */ gboolean select_by_word; /* Current selection is by word */ + /* This section is for drag scrolling. */ + gint timeout_id; /* Current timeout id for scrolling */ + GTimer *timer; /* Timer for blinking cursor and scrolling */ + + gint lastx, lasty; /* Last x and y motion events */ + gint last_state; /* Last state */ + gulong scroll_start; /* Starting time for scroll (microseconds) */ + + gint show_cursor; /* Is cursor currently shown */ + gboolean button_down; /* Is mouse button 1 down */ + ETextEventProcessor *tep; /* Text Event Processor */ }; |