diff options
author | Yevgen Muntyan <muntyan@tamu.edu> | 2007-06-12 05:32:57 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-06-12 05:32:57 +0000 |
commit | ef1e05f7ded60ec3551ec4ab57fded69437a6837 (patch) | |
tree | d4c976d8416c781a92cbe59dcb17bd4eee9e1b51 /gtk/gtktextdisplay.c | |
parent | 15c693477897eb1bbc8aebae880ef979eae1ba94 (diff) | |
download | gtk+-ef1e05f7ded60ec3551ec4ab57fded69437a6837.tar.gz |
Implement block-cursor for overwrite mode. (#80378)
2007-06-12 Yevgen Muntyan <muntyan@tamu.edu>
* gtk/gtkentry.c (gtk_entry_expose), (gtk_entry_toggle_overwrite),
(gtk_entry_draw_cursor):
* gtk/gtkstyle.c (_gtk_widget_get_cursor_gc),
(_gtk_widget_get_cursor_color):
* gtk/gtkstyle.h:
* gtk/gtktextdisplay.c (gtk_text_renderer_prepare_run),
(gtk_text_renderer_draw_shape), (text_renderer_set_state),
(render_para):
* gtk/gtktextlayout.c (gtk_text_layout_set_overwrite_mode),
(gtk_text_layout_invalidate_cache), (get_block_cursor),
(add_cursor), (gtk_text_layout_get_line_display),
(_gtk_text_layout_get_block_cursor):
* gtk/gtktextlayout.h:
* gtk/gtktextutil.c (layout_get_char_width),
(_gtk_text_util_get_block_cursor_location):
* gtk/gtktextutil.h:
* gtk/gtktextview.c (gtk_text_view_set_editable),
(gtk_text_view_toggle_overwrite), (gtk_text_view_set_overwrite),
(gtk_text_view_ensure_layout), (text_window_invalidate_cursors):
Implement block-cursor for overwrite mode. (#80378)
svn path=/trunk/; revision=18108
Diffstat (limited to 'gtk/gtktextdisplay.c')
-rw-r--r-- | gtk/gtktextdisplay.c | 88 |
1 files changed, 75 insertions, 13 deletions
diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c index d782efdc5c..e9da20e500 100644 --- a/gtk/gtktextdisplay.c +++ b/gtk/gtktextdisplay.c @@ -93,6 +93,12 @@ typedef struct _GtkTextRenderer GtkTextRenderer; typedef struct _GtkTextRendererClass GtkTextRendererClass; +enum { + NORMAL, + SELECTED, + CURSOR +}; + struct _GtkTextRenderer { GdkPangoRenderer parent_instance; @@ -106,7 +112,7 @@ struct _GtkTextRenderer GdkColor *error_color; /* Error underline color for this widget */ GList *widgets; /* widgets encountered when drawing */ - gboolean selected; + int state; }; struct _GtkTextRendererClass @@ -186,21 +192,23 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer, appearance = get_item_appearance (run->item); g_assert (appearance != NULL); - - if (appearance->draw_bg && !text_renderer->selected) + + if (appearance->draw_bg && text_renderer->state == NORMAL) bg_color = &appearance->bg_color; else bg_color = NULL; text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_color); - if (text_renderer->selected) + if (text_renderer->state == SELECTED) { if (GTK_WIDGET_HAS_FOCUS (text_renderer->widget)) fg_color = &text_renderer->widget->style->text[GTK_STATE_SELECTED]; else fg_color = &text_renderer->widget->style->text[GTK_STATE_ACTIVE]; } + else if (text_renderer->state == CURSOR && GTK_WIDGET_HAS_FOCUS (text_renderer->widget)) + fg_color = &text_renderer->widget->style->base[GTK_STATE_NORMAL]; else fg_color = &appearance->fg_color; @@ -249,13 +257,15 @@ gtk_text_renderer_draw_shape (PangoRenderer *renderer, GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer); GdkGC *fg_gc; - if (text_renderer->selected) + if (text_renderer->state == SELECTED) { if (GTK_WIDGET_HAS_FOCUS (text_renderer->widget)) fg_gc = text_renderer->widget->style->text_gc[GTK_STATE_SELECTED]; else fg_gc = text_renderer->widget->style->text_gc[GTK_STATE_SELECTED]; } + else if (text_renderer->state == CURSOR && GTK_WIDGET_HAS_FOCUS (text_renderer->widget)) + fg_gc = text_renderer->widget->style->base_gc[GTK_STATE_NORMAL]; else fg_gc = text_renderer->widget->style->text_gc[GTK_STATE_NORMAL]; @@ -358,10 +368,10 @@ _gtk_text_renderer_class_init (GtkTextRendererClass *klass) } static void -text_renderer_set_selected (GtkTextRenderer *text_renderer, - gboolean selected) +text_renderer_set_state (GtkTextRenderer *text_renderer, + int state) { - text_renderer->selected = selected; + text_renderer->state = state; } static void @@ -486,6 +496,7 @@ render_para (GtkTextRenderer *text_renderer, int first_y, last_y; PangoRectangle line_rect; int baseline; + gboolean at_last_line; pango_layout_iter_get_line_extents (iter, NULL, &line_rect); baseline = pango_layout_iter_get_baseline (iter); @@ -508,8 +519,9 @@ render_para (GtkTextRenderer *text_renderer, selection_y -= line_display->top_margin; selection_height += line_display->top_margin; } - - if (pango_layout_iter_at_last_line (iter)) + + at_last_line = pango_layout_iter_at_last_line (iter); + if (at_last_line) selection_height += line_display->bottom_margin; first = FALSE; @@ -525,7 +537,7 @@ render_para (GtkTextRenderer *text_renderer, screen_width, selection_height); - text_renderer_set_selected (text_renderer, TRUE); + text_renderer_set_state (text_renderer, SELECTED); pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer), line, PANGO_SCALE * x + line_rect.x, @@ -552,7 +564,7 @@ render_para (GtkTextRenderer *text_renderer, g_object_unref (bg_gc); } - text_renderer_set_selected (text_renderer, FALSE); + text_renderer_set_state (text_renderer, NORMAL); pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer), line, PANGO_SCALE * x + line_rect.x, @@ -589,7 +601,7 @@ render_para (GtkTextRenderer *text_renderer, PANGO_PIXELS (line_rect.width), selection_height); - text_renderer_set_selected (text_renderer, TRUE); + text_renderer_set_state (text_renderer, SELECTED); pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer), line, PANGO_SCALE * x + line_rect.x, @@ -636,6 +648,56 @@ render_para (GtkTextRenderer *text_renderer, selection_height); } } + else if (line_display->has_block_cursor && + GTK_WIDGET_HAS_FOCUS (text_renderer->widget) && + byte_offset <= line_display->insert_index && + (line_display->insert_index < byte_offset + line->length || + (at_last_line && line_display->insert_index == byte_offset + line->length))) + { + GdkRectangle cursor_rect; + GdkGC *cursor_gc; + + /* we draw text using base color on filled cursor rectangle of cursor color + * (normally white on black) */ + cursor_gc = _gtk_widget_get_cursor_gc (text_renderer->widget); + + cursor_rect.x = x + line_display->x_offset + line_display->block_cursor.x; + cursor_rect.y = selection_y; + cursor_rect.width = line_display->block_cursor.width; + cursor_rect.height = selection_height; + + gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (text_renderer), NULL); + gdk_gc_set_clip_rectangle (cursor_gc, &cursor_rect); + + gdk_draw_rectangle (text_renderer->drawable, + cursor_gc, + TRUE, + cursor_rect.x, + cursor_rect.y, + cursor_rect.width, + cursor_rect.height); + + /* draw text under the cursor if any */ + if (!line_display->cursor_at_line_end) + { + GdkGC *cursor_text_gc; + + cursor_text_gc = text_renderer->widget->style->base_gc[text_renderer->widget->state]; + gdk_gc_set_clip_rectangle (cursor_text_gc, &cursor_rect); + gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (text_renderer), cursor_text_gc); + text_renderer_set_state (text_renderer, CURSOR); + + pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer), + line, + PANGO_SCALE * x + line_rect.x, + PANGO_SCALE * y + baseline); + + gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (text_renderer), fg_gc); + gdk_gc_set_clip_region (cursor_text_gc, NULL); + } + + gdk_gc_set_clip_region (cursor_gc, NULL); + } } byte_offset += line->length; |