Blocked the tab key from getting inserted into the buffer since the

* widgets/e-text-event-processor-emacs-like.c: Blocked the tab key
	from getting inserted into the buffer since the renderer doesn't
	know what a tab is.

	* widgets/e-text.c, widgets/e-text.h: Fixed a memory leak.  Added
	a blinking cursor and scrolling for the text item.

svn path=/trunk/; revision=1554
This commit is contained in:
Chris Lahey
2000-01-11 22:10:20 +00:00
parent a01de808cd
commit a097129f68
11 changed files with 393 additions and 22 deletions

View File

@ -1,3 +1,12 @@
2000-01-11 <clahey@galapagos.helixcode.com>
* widgets/e-text-event-processor-emacs-like.c: Blocked the tab key
from getting inserted into the buffer since the renderer doesn't
know what a tab is.
* widgets/e-text.c, widgets/e-text.h: Fixed a memory leak. Added
a blinking cursor and scrolling for the text item.
2000-01-11 Christopher James Lahey <clahey@helixcode.com>
* widgets/test-minicard.c: Removed some code which got in the way

View File

@ -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:

View File

@ -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:

View File

@ -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, &current_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:

View File

@ -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 */
};

View File

@ -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:

View File

@ -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, &current_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:

View File

@ -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 */
};

View File

@ -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:

View File

@ -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, &current_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:

View File

@ -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 */
};