From fa7a94bcc97a410d8ce60b57c3265837e1910758 Mon Sep 17 00:00:00 2001 From: fliep Date: Tue, 5 May 2009 11:47:22 +0000 Subject: [PATCH] Now the size of text grid windows is updated when they are resized. --- src/chimara-glk.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- src/window.c | 39 ++++++++++++++++------------- 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/chimara-glk.c b/src/chimara-glk.c index 73c1287..889b4f2 100644 --- a/src/chimara-glk.c +++ b/src/chimara-glk.c @@ -330,7 +330,68 @@ allocate_recurse(winid_t win, GtkAllocation *allocation, guint spacing) allocate_recurse(win->window_node->children->next->data, &child2, spacing); } - /* For non-pair windows, just give them the size */ + else if(win->type == wintype_TextGrid) + { + /* Pass the size allocation on to the framing widget */ + gtk_widget_size_allocate(win->frame, allocation); + /* It says in the spec that when a text grid window is resized smaller, + the bottom or right area is thrown away; when it is resized larger, the + bottom or right area is filled with blanks. */ + glui32 newwidth = (glui32)(win->widget->allocation.width / win->unit_width); + glui32 newheight = (glui32)(win->widget->allocation.height / win->unit_height); + gint line; + GtkTextBuffer *textbuffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); + GtkTextIter start, end; + + for(line = 0; line < win->height; line++) + { + gtk_text_buffer_get_iter_at_line(textbuffer, &start, line); + if(line > newheight) + { + end = start; + gtk_text_iter_forward_to_line_end(&end); + gtk_text_iter_forward_char(&end); + gtk_text_buffer_delete(textbuffer, &start, &end); + break; + } + if(newwidth > win->width) + { + gchar *spaces = g_strnfill(newwidth - win->width, ' '); + gtk_text_iter_forward_to_line_end(&start); + gtk_text_buffer_insert(textbuffer, &start, spaces, -1); + g_free(spaces); + } + else if(newwidth < win->width) + { + end = start; + gtk_text_iter_forward_chars(&start, newwidth); + gtk_text_iter_forward_to_line_end(&end); + gtk_text_buffer_delete(textbuffer, &start, &end); + } + } + if(newheight > win->height) + { + gchar *blanks = g_strnfill(win->width, ' '); + gchar **blanklines = g_new0(gchar *, (newheight - win->height) + 1); + int count; + for(count = 0; count < newheight - win->height; count++) + blanklines[count] = blanks; + blanklines[newheight - win->height] = NULL; + gchar *text = g_strjoinv("\n", blanklines); + g_free(blanklines); /* not g_strfreev() */ + g_free(blanks); + + gtk_text_buffer_get_end_iter(textbuffer, &start); + gtk_text_buffer_insert(textbuffer, &start, "\n", -1); + gtk_text_buffer_insert(textbuffer, &start, text, -1); + g_free(text); + } + + win->width = newwidth; + win->height = newheight; + } + + /* For non-pair, non-text-grid windows, just give them the size */ else gtk_widget_size_allocate(win->frame, allocation); } diff --git a/src/window.c b/src/window.c index 67eec5b..4993667 100644 --- a/src/window.c +++ b/src/window.c @@ -510,34 +510,26 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype, gtk_widget_set_parent(win->frame, GTK_WIDGET(glk_data->self)); gtk_widget_queue_resize(GTK_WIDGET(glk_data->self)); + gdk_threads_leave(); + /* For text grid windows, wait until GTK draws the window (see note in glk_window_get_size() ), calculate the size and fill the buffer with blanks. */ if(wintype == wintype_TextGrid) { - while(win->widget->allocation.width == 1 && win->widget->allocation.height == 1) - { - /* Release the GDK lock momentarily */ - gdk_threads_leave(); - gdk_threads_enter(); - while(gtk_events_pending()) - gtk_main_iteration(); - } - win->width = (glui32)(win->widget->allocation.width / win->unit_width); - win->height = (glui32)(win->widget->allocation.height / win->unit_height); + /* Force the window to be drawn and cache its size */ + glk_window_get_size(win, NULL, NULL); - /* Mark the cursor position */ + /* Create the cursor position mark */ + gdk_threads_enter(); GtkTextIter begin; GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); gtk_text_buffer_get_start_iter(buffer, &begin); gtk_text_buffer_create_mark(buffer, "cursor_position", &begin, TRUE); - - /* Fill the buffer with blanks and move the cursor to the upper left */ gdk_threads_leave(); + + /* Fill the buffer with blanks and move the cursor to the upper left */ glk_window_clear(win); - gdk_threads_enter(); } - gdk_threads_leave(); - return win; } @@ -904,7 +896,20 @@ glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr) break; case wintype_TextGrid: - /* The text grid caches its width and height */ + gdk_threads_enter(); + /* Wait for the window to be drawn, and then cache the width and height */ + while(win->widget->allocation.width == 1 && win->widget->allocation.height == 1) + { + /* Release the GDK lock momentarily */ + gdk_threads_leave(); + gdk_threads_enter(); + while(gtk_events_pending()) + gtk_main_iteration(); + } + win->width = (glui32)(win->widget->allocation.width / win->unit_width); + win->height = (glui32)(win->widget->allocation.height / win->unit_height); + gdk_threads_leave(); + if(widthptr != NULL) *widthptr = win->width; if(heightptr != NULL) -- 2.30.2