diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2011-11-02 22:26:59 -0400 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2011-11-03 13:15:09 -0400 |
commit | 585140eb253d28644f8abce66786128271378c0b (patch) | |
tree | 2787c7db4c3190eaea9cda5bdf7bb6a94649d415 | |
parent | 73980c1526e90a2b4dded074e39e76b54930dafc (diff) |
gtk3: implement rendering for Comboboxes
-rw-r--r-- | vcl/inc/unx/gtk/gtkgdi.hxx | 9 | ||||
-rw-r--r-- | vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx | 184 |
2 files changed, 175 insertions, 18 deletions
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx index 572484dbe54b..c7e1eb2ef054 100644 --- a/vcl/inc/unx/gtk/gtkgdi.hxx +++ b/vcl/inc/unx/gtk/gtkgdi.hxx @@ -77,11 +77,14 @@ private: static GtkStyleContext *mpMenuStyle; static GtkStyleContext *mpMenuItemStyle; static GtkStyleContext *mpSpinStyle; + static GtkStyleContext *mpComboboxStyle; void renderAreaToPix( cairo_t* cr, cairo_rectangle_int_t *region ); void getStyleContext( GtkStyleContext** style, GtkWidget* widget ); Rectangle NWGetScrollButtonRect( ControlPart nPart, Rectangle aAreaRect ); Rectangle NWGetSpinButtonRect( ControlPart nPart, Rectangle aAreaRect); + Rectangle NWGetComboBoxButtonRect( ControlPart nPart, Rectangle aAreaRect ); + void PaintScrollbar(GtkStyleContext *context, cairo_t *cr, const Rectangle& rControlRectangle, @@ -97,6 +100,12 @@ private: const Rectangle& rControlRectangle, ControlType nType, const ImplControlValue& aValue ); + void PaintCombobox( GtkStyleContext *context, + cairo_t *cr, + const Rectangle& rControlRectangle, + ControlType nType, + ControlPart nPart, + const ImplControlValue& aValue ); static bool style_loaded; }; diff --git a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx index 462a38aef05f..365f4701c549 100644 --- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx @@ -45,6 +45,7 @@ GtkStyleContext* GtkSalGraphics::mpMenuBarItemStyle = NULL; GtkStyleContext* GtkSalGraphics::mpMenuStyle = NULL; GtkStyleContext* GtkSalGraphics::mpMenuItemStyle = NULL; GtkStyleContext* GtkSalGraphics::mpSpinStyle = NULL; +GtkStyleContext* GtkSalGraphics::mpComboboxStyle = NULL; bool GtkSalGraphics::style_loaded = false; /************************************************************************ @@ -84,8 +85,40 @@ enum { RENDER_RADIO = 6, RENDER_SCROLLBAR = 7, RENDER_SPINBUTTON = 8, + RENDER_COMBOBOX = 9, }; +static void PrepareComboboxStyle( GtkStyleContext *context, + gboolean forEntry) +{ + GtkWidgetPath *path, *siblingsPath; + + path = gtk_widget_path_new(); + siblingsPath = gtk_widget_path_new(); + gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX); + gtk_widget_path_iter_add_class(path, 0, GTK_STYLE_CLASS_COMBOBOX_ENTRY); + + gtk_widget_path_append_type(siblingsPath, GTK_TYPE_ENTRY); + gtk_widget_path_append_type(siblingsPath, GTK_TYPE_BUTTON); + gtk_widget_path_iter_add_class(siblingsPath, 0, GTK_STYLE_CLASS_ENTRY); + gtk_widget_path_iter_add_class(siblingsPath, 1, GTK_STYLE_CLASS_BUTTON); + + if (forEntry) + { + gtk_widget_path_append_with_siblings(path, siblingsPath, 1); + gtk_widget_path_append_with_siblings(path, siblingsPath, 0); + } + else + { + gtk_widget_path_append_with_siblings(path, siblingsPath, 0); + gtk_widget_path_append_with_siblings(path, siblingsPath, 1); + } + + gtk_style_context_set_path(context, path); + gtk_widget_path_free(path); + gtk_widget_path_free(siblingsPath); +} + static void NWCalcArrowRect( const Rectangle& rButton, Rectangle& rArrow ) { // Size the arrow appropriately @@ -608,6 +641,106 @@ void GtkSalGraphics::PaintSpinButton(GtkStyleContext *context, PaintOneSpinButton(context, cr, downBtnPart, areaRect, downBtnState ); } +#define ARROW_SIZE 11 * 0.85 +Rectangle GtkSalGraphics::NWGetComboBoxButtonRect( ControlPart nPart, + Rectangle aAreaRect ) +{ + Rectangle aButtonRect; + gint nArrowWidth; + gint nButtonWidth; + gint nFocusWidth; + gint nFocusPad; + GtkBorder padding; + + // Grab some button style attributes + gtk_style_context_get_style( mpButtonStyle, + "focus-line-width", &nFocusWidth, + "focus-padding", &nFocusPad, + NULL ); + gtk_style_context_get_padding( mpButtonStyle, GTK_STATE_FLAG_NORMAL, &padding); + + nArrowWidth = ARROW_SIZE; + nButtonWidth = nArrowWidth + padding.left + padding.right + (2 * (nFocusWidth+nFocusPad)); + if( nPart == PART_BUTTON_DOWN ) + { + aButtonRect.SetSize( Size( nButtonWidth, aAreaRect.GetHeight() ) ); + aButtonRect.SetPos( Point( aAreaRect.Left() + aAreaRect.GetWidth() - nButtonWidth, + aAreaRect.Top() ) ); + } + else if( nPart == PART_SUB_EDIT ) + { + gint adjust_x = (gint) ((padding.left + padding.right) / 2) + nFocusWidth + nFocusPad; + gint adjust_y = (gint) ((padding.top + padding.bottom) / 2) + nFocusWidth + nFocusPad; + + aButtonRect.SetSize( Size( aAreaRect.GetWidth() - nButtonWidth - 2 * adjust_x, + aAreaRect.GetHeight() - 2 * adjust_y ) ); + Point aEditPos = aAreaRect.TopLeft(); + aEditPos.X() += adjust_x; + aEditPos.Y() += adjust_y; + aButtonRect.SetPos( aEditPos ); + } + + return( aButtonRect ); +} + +void GtkSalGraphics::PaintCombobox( GtkStyleContext *context, + cairo_t *cr, + const Rectangle& rControlRectangle, + ControlType nType, + ControlPart nPart, + const ImplControlValue& aValue ) +{ + Rectangle areaRect; + Rectangle buttonRect; + Rectangle arrowRect; + gint x,y; + + // Find the overall bounding rect of the buttons's drawing area, + // plus its actual draw rect excluding adornment + areaRect = rControlRectangle; + x = 1; + y = 1; + + buttonRect = NWGetComboBoxButtonRect( PART_BUTTON_DOWN, areaRect ); + if( nPart == PART_BUTTON_DOWN ) + buttonRect.Left() += 1; + + Rectangle aEditBoxRect( areaRect ); + aEditBoxRect.SetSize( Size( areaRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) ); + + if( nPart == PART_ENTIRE_CONTROL ) + { + PrepareComboboxStyle(context, true); + gtk_render_background(context, cr, + x, y, + aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() ); + gtk_render_frame(context, cr, + x, y, + aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() ); + } + + arrowRect.SetSize( Size( (gint)(ARROW_SIZE), + (gint)(ARROW_SIZE) ) ); + arrowRect.SetPos( Point( buttonRect.Left() + (gint)((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2), + buttonRect.Top() + (gint)((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) ); + + PrepareComboboxStyle(context, false); + + gtk_render_background(context, cr, + x+(buttonRect.Left() - areaRect.Left()), + y+(buttonRect.Top() - areaRect.Top()), + buttonRect.GetWidth(), buttonRect.GetHeight() ); + gtk_render_frame(context, cr, + x+(buttonRect.Left() - areaRect.Left()), + y+(buttonRect.Top() - areaRect.Top()), + buttonRect.GetWidth(), buttonRect.GetHeight() ); + + gtk_render_arrow(context, cr, + G_PI, + x+(arrowRect.Left() - areaRect.Left()), y+(arrowRect.Top() - areaRect.Top()), + arrowRect.GetWidth() ); +} + sal_Bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& ) @@ -636,6 +769,10 @@ sal_Bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart case CTRL_EDITBOX: context = mpEntryStyle; break; + case CTRL_COMBOBOX: + context = mpComboboxStyle; + renderType = RENDER_COMBOBOX; + break; case CTRL_MENU_POPUP: /* FIXME: missing ENTIRE_CONTROL, as it doesn't seem to work */ switch(nPart) @@ -781,6 +918,9 @@ sal_Bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart case RENDER_SPINBUTTON: PaintSpinButton(context, cr, rControlRegion, nType, aValue); break; + case RENDER_COMBOBOX: + PaintCombobox(context, cr, rControlRegion, nType, nPart, aValue); + break; default: break; } @@ -922,6 +1062,12 @@ sal_Bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart { aEditRect = NWGetSpinButtonRect( nPart, rControlRegion ); } + else if ( (nType==CTRL_COMBOBOX) && + ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) ) + { + aEditRect = NWGetComboBoxButtonRect( nPart, rControlRegion ); + } + else { return sal_False; } @@ -1239,27 +1385,24 @@ sal_Bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPar { printf("Is native supported for Type: %d, Part %d\n", nType, nPart); if( + (nType == CTRL_EDITBOX) || (nType == CTRL_PUSHBUTTON && nPart == PART_ENTIRE_CONTROL) || (nType == CTRL_CHECKBOX && nPart == PART_ENTIRE_CONTROL) || - (nType == CTRL_RADIOBUTTON && nPart == PART_ENTIRE_CONTROL) || - ((nType==CTRL_SPINBOX) && - ((nPart==PART_ENTIRE_CONTROL) - || (nPart==PART_ALL_BUTTONS) - || (nPart==HAS_BACKGROUND_TEXTURE))) || - ((nType==CTRL_SCROLLBAR) && - ( (nPart==PART_DRAW_BACKGROUND_HORZ) - || (nPart==PART_DRAW_BACKGROUND_VERT) - || (nPart==PART_ENTIRE_CONTROL) - || (nPart==HAS_THREE_BUTTONS))) || - (nType == CTRL_EDITBOX) || - (nType == CTRL_MENU_POPUP && - (nPart == PART_MENU_ITEM_CHECK_MARK || - nPart == PART_MENU_ITEM_RADIO_MARK || - nPart == PART_MENU_SEPARATOR || - nPart == PART_MENU_SUBMENU_ARROW)) || + (nType == CTRL_RADIOBUTTON && nPart == PART_ENTIRE_CONTROL) | (nType == CTRL_TOOLBAR && - (nPart == PART_BUTTON || - nPart == PART_ENTIRE_CONTROL))) + (nPart == PART_BUTTON || nPart == PART_ENTIRE_CONTROL)) || + ((nType == CTRL_SPINBOX) && + ((nPart == PART_ENTIRE_CONTROL) || (nPart == PART_ALL_BUTTONS) || + (nPart == HAS_BACKGROUND_TEXTURE))) || + ((nType == CTRL_COMBOBOX) && + ((nPart == PART_ENTIRE_CONTROL) || (nPart == PART_ALL_BUTTONS) || + (nPart == HAS_BACKGROUND_TEXTURE))) || + ((nType == CTRL_SCROLLBAR) && + ( (nPart == PART_DRAW_BACKGROUND_HORZ) || (nPart == PART_DRAW_BACKGROUND_VERT) || + (nPart == PART_ENTIRE_CONTROL) || (nPart == HAS_THREE_BUTTONS))) || + (nType == CTRL_MENU_POPUP && + ((nPart == PART_MENU_ITEM_CHECK_MARK) || (nPart == PART_MENU_ITEM_RADIO_MARK) || + (nPart == PART_MENU_SEPARATOR) || (nPart == PART_MENU_SUBMENU_ARROW)))) return sal_True; return sal_False; @@ -1343,6 +1486,11 @@ GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow ) /* Spinbutton */ getStyleContext(&mpSpinStyle, gtk_spin_button_new(NULL, 0, 0)); + + /* Combobox */ + mpComboboxStyle = gtk_style_context_new(); + PrepareComboboxStyle(mpComboboxStyle, true); + } static void print_cairo_region (cairo_region_t *region, const char *msg) |