# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1326824280 0 # Node ID 46e34bd92336cab9d0848baed2e57b39748aab29 # Parent ee47bda2691696eb1f329dd02b380155d5dc2232 Implemented guessing size of MLE on GTK... not as accurate as the other platforms... but until the bugs are fixed in GTK this is the best we can do. Also make dw_window_get_preferred_size() return our guesses. Added a piece of safety code on Windows... just in case. diff -r ee47bda26916 -r 46e34bd92336 gtk/dw.c --- a/gtk/dw.c Tue Jan 17 16:33:21 2012 +0000 +++ b/gtk/dw.c Tue Jan 17 18:18:00 2012 +0000 @@ -10019,6 +10019,85 @@ } } +/* Internal function to get the recommended size of scrolled items */ +void _get_scrolled_size(GtkWidget *item, gint *thiswidth, gint *thisheight) +{ + GtkWidget *widget = gtk_object_get_user_data(GTK_OBJECT(item)); + + /* Try to figure out the contents for MLE and Container */ + if(widget && (GTK_IS_TEXT_VIEW(widget) || GTK_IS_CLIST(widget))) + { + if(GTK_IS_CLIST(widget)) + { + GtkRequisition req; + + gtk_widget_size_request(widget, &req); + + *thiswidth = req.width + 20; + *thisheight = req.height + 20; + } + else + { + unsigned long bytes; + int height, width; + char *buf, *ptr; + int basicwidth; + int wrap = (gtk_text_view_get_wrap_mode(GTK_TEXT_VIEW(widget)) == GTK_WRAP_WORD); + static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + *thisheight = 20; + basicwidth = *thiswidth = 20; + + dw_mle_get_size(item, &bytes, NULL); + + ptr = buf = alloca(bytes + 2); + dw_mle_export(item, buf, 0, (int)bytes); + buf[bytes] = 0; + strcat(buf, "\n"); + + /* MLE */ + while((ptr = strstr(buf, "\n"))) + { + ptr[0] = 0; + width = 0; + if(strlen(buf)) + dw_font_text_extents_get(item, NULL, buf, &width, &height); + else + dw_font_text_extents_get(item, NULL, testtext, NULL, &height); + + width += basicwidth; + + if(wrap && width > _DW_SCROLLED_MAX_WIDTH) + { + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + *thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH); + } + else + { + if(width > *thiswidth) + *thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width; + } + *thisheight += height; + buf = &ptr[1]; + } + } + } + else + { + /* Set to max for others */ + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + *thisheight = _DW_SCROLLED_MAX_HEIGHT; + } + if(*thiswidth < _DW_SCROLLED_MIN_WIDTH) + *thiswidth = _DW_SCROLLED_MIN_WIDTH; + if(*thiswidth > _DW_SCROLLED_MAX_WIDTH) + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + if(*thisheight < _DW_SCROLLED_MIN_HEIGHT) + *thisheight = _DW_SCROLLED_MIN_HEIGHT; + if(*thisheight > _DW_SCROLLED_MAX_HEIGHT) + *thisheight = _DW_SCROLLED_MAX_HEIGHT; +} + /* Internal box packing function called by the other 3 functions */ void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname) { @@ -10121,42 +10200,16 @@ /* If it is a scrolled item and not expandable... * Clamp to minumum or maximum. */ - if(GTK_IS_SCROLLED_WINDOW(item)) + if(GTK_IS_SCROLLED_WINDOW(item) && ((width < 1 && !hsize) || (height < 1 && !vsize))) { - GtkWidget *widget = gtk_object_get_user_data(GTK_OBJECT(item)); - - /* Try to figure out the contents for MLE and Container */ - if(widget && (GTK_IS_TEXT_VIEW(widget) || GTK_IS_CLIST(widget))) - { - GtkRequisition req; - - gtk_widget_size_request(widget, &req); - - if(thiswidth < 1 && !hsize) - { - thiswidth = req.width + 20; - if(thiswidth < _DW_SCROLLED_MIN_WIDTH) - thiswidth = _DW_SCROLLED_MIN_WIDTH; - if(thiswidth > _DW_SCROLLED_MAX_WIDTH) - thiswidth = _DW_SCROLLED_MAX_WIDTH; - } - if(thisheight < 1 && !vsize) - { - thisheight = req.height + 20; - if(thisheight < _DW_SCROLLED_MIN_HEIGHT) - thisheight = _DW_SCROLLED_MIN_HEIGHT; - if(thisheight > _DW_SCROLLED_MAX_HEIGHT) - thisheight = _DW_SCROLLED_MAX_HEIGHT; - } - } - else - { - /* Set to max for others */ - if(thiswidth < 1 && !hsize) - thiswidth = _DW_SCROLLED_MAX_WIDTH; - if(thisheight < 1 && !vsize) - thisheight = _DW_SCROLLED_MAX_HEIGHT; - } + gint scrolledwidth = 0, scrolledheight = 0; + + _get_scrolled_size(item, &scrolledwidth, &scrolledheight); + + if(width < 1 && !hsize) + thiswidth = scrolledwidth; + if(height < 1 && !vsize) + thisheight = scrolledheight; } gtk_widget_set_usize(item, thiswidth, thisheight); } @@ -10408,11 +10461,25 @@ int _locked_by_me = FALSE; DW_MUTEX_LOCK; - gtk_widget_size_request(handle, &req); - if(width) - *width = req.width; - if(height) - *height = req.height; + if(GTK_IS_SCROLLED_WINDOW(handle)) + { + gint scrolledwidth, scrolledheight; + + _get_scrolled_size(handle, &scrolledwidth, &scrolledheight); + + if(width) + *width = scrolledwidth; + if(height) + *height = scrolledheight; + } + else + { + gtk_widget_size_request(handle, &req); + if(width) + *width = req.width; + if(height) + *height = req.height; + } DW_MUTEX_UNLOCK; } diff -r ee47bda26916 -r 46e34bd92336 gtk3/dw.c --- a/gtk3/dw.c Tue Jan 17 16:33:21 2012 +0000 +++ b/gtk3/dw.c Tue Jan 17 18:18:00 2012 +0000 @@ -8337,6 +8337,94 @@ exit(exitcode); } +/* Internal function to get the recommended size of scrolled items */ +void _get_scrolled_size(GtkWidget *item, gint *thiswidth, gint *thisheight) +{ + GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user"); + + *thisheight = *thiswidth = 0; + + if(widget) + { + if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) + { + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + *thisheight = _DW_SCROLLED_MAX_HEIGHT; + } + else if(GTK_IS_TEXT_VIEW(widget)) + { + unsigned long bytes; + int height, width; + char *buf, *ptr; + int wrap = (gtk_text_view_get_wrap_mode(GTK_TEXT_VIEW(widget)) == GTK_WRAP_WORD); + static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int hscrolled = FALSE; + + *thiswidth = *thisheight = 0; + + dw_mle_get_size(item, &bytes, NULL); + + ptr = buf = alloca(bytes + 2); + dw_mle_export(item, buf, 0, (int)bytes); + buf[bytes] = 0; + strcat(buf, "\n"); + + /* MLE */ + while((ptr = strstr(buf, "\r"))) + { + ptr[0] = 0; + width = 0; + if(strlen(buf)) + dw_font_text_extents_get(item, NULL, buf, &width, &height); + else + dw_font_text_extents_get(item, NULL, testtext, NULL, &height); + + if(wrap && width > _DW_SCROLLED_MAX_WIDTH) + { + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + *thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH); + } + else + { + if(width > *thiswidth) + { + if(width > _DW_SCROLLED_MAX_WIDTH) + { + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + hscrolled = TRUE; + } + else + *thiswidth = width; + } + } + *thisheight += height; + if(ptr[1] == '\n') + buf = &ptr[2]; + else + buf = &ptr[1]; + } + if(hscrolled) + *thisheight += 20; + } + else + { + gtk_widget_get_preferred_height(GTK_WIDGET(widget), NULL, thisheight); + gtk_widget_get_preferred_width(GTK_WIDGET(widget), NULL, thiswidth); + + *thisheight += 20; + *thiswidth += 20; + } + } + if(*thiswidth < _DW_SCROLLED_MIN_WIDTH) + *thiswidth = _DW_SCROLLED_MIN_WIDTH; + if(*thiswidth > _DW_SCROLLED_MAX_WIDTH) + *thiswidth = _DW_SCROLLED_MAX_WIDTH; + if(*thisheight < _DW_SCROLLED_MIN_HEIGHT) + *thisheight = _DW_SCROLLED_MIN_HEIGHT; + if(*thisheight > _DW_SCROLLED_MAX_HEIGHT) + *thisheight = _DW_SCROLLED_MAX_HEIGHT; +} + /* Internal box packing function called by the other 3 functions */ void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname) { @@ -8467,48 +8555,20 @@ /* Special case for scrolled windows */ if(GTK_IS_SCROLLED_WINDOW(item)) { + gint scrolledwidth = 0, scrolledheight = 0; + + /* Pre-run the calculation code for MLE/Container/Tree if needed */ + if((width < 1 && !hsize) || (height < 1 && !vsize)) + _get_scrolled_size(item, &scrolledwidth, &scrolledheight); + if(width > 0) gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), width); else if(!hsize) - { - /* If we aren't expandable set the minimum width */ - gint thiswidth = 0; - GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user"); - - if(widget) - { - if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) - thiswidth = _DW_SCROLLED_MAX_WIDTH; - else - gtk_widget_get_preferred_width(GTK_WIDGET(widget), NULL, &thiswidth); - } - if(thiswidth < _DW_SCROLLED_MIN_WIDTH) - thiswidth = _DW_SCROLLED_MIN_WIDTH; - if(thiswidth > _DW_SCROLLED_MAX_WIDTH) - thiswidth = _DW_SCROLLED_MAX_WIDTH; - gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), thiswidth); - } + gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), scrolledwidth); if(height > 0) gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), height); else if(!vsize) - { - /* If we aren't expandable set the minimum height */ - gint thisheight = 0; - GtkWidget *widget = g_object_get_data(G_OBJECT(item), "_dw_user"); - - if(widget) - { - if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) - thisheight = _DW_SCROLLED_MAX_HEIGHT; - else - gtk_widget_get_preferred_height(GTK_WIDGET(widget), NULL, &thisheight); - } - if(thisheight < _DW_SCROLLED_MIN_HEIGHT) - thisheight = _DW_SCROLLED_MIN_HEIGHT; - if(thisheight > _DW_SCROLLED_MAX_HEIGHT) - thisheight = _DW_SCROLLED_MAX_HEIGHT; - gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), thisheight); - } + gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), scrolledheight); } else { @@ -8765,10 +8825,24 @@ int _locked_by_me = FALSE; DW_MUTEX_LOCK; - if(width) - gtk_widget_get_preferred_width(handle, NULL, width); - if(height) - gtk_widget_get_preferred_height(handle, NULL, height); + if(GTK_IS_SCROLLED_WINDOW(handle)) + { + gint scrolledwidth, scrolledheight; + + _get_scrolled_size(handle, &scrolledwidth, &scrolledheight); + + if(width) + *width = scrolledwidth; + if(height) + *height = scrolledheight; + } + else + { + if(width) + gtk_widget_get_preferred_width(handle, NULL, width); + if(height) + gtk_widget_get_preferred_height(handle, NULL, height); + } DW_MUTEX_UNLOCK; } diff -r ee47bda26916 -r 46e34bd92336 win/dw.c --- a/win/dw.c Tue Jan 17 16:33:21 2012 +0000 +++ b/win/dw.c Tue Jan 17 18:18:00 2012 +0000 @@ -4528,6 +4528,7 @@ ptr = buf = _alloca(bytes + 2); dw_mle_export(handle, buf, 0, (int)bytes); + buf[bytes] = 0; strcat(buf, "\n"); /* MLE */