Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_GTK_GTK_UTIL_H_
      6 #define CHROME_BROWSER_UI_GTK_GTK_UTIL_H_
      7 #pragma once
      8 
      9 #include <gtk/gtk.h>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/string16.h"
     14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h"
     15 #include "ui/base/x/x11_util.h"
     16 #include "ui/gfx/point.h"
     17 #include "ui/gfx/rect.h"
     18 #include "webkit/glue/window_open_disposition.h"
     19 
     20 typedef struct _cairo cairo_t;
     21 typedef struct _GdkColor GdkColor;
     22 typedef struct _GtkWidget GtkWidget;
     23 
     24 class BrowserWindow;
     25 class GtkThemeService;
     26 class GURL;
     27 class Profile;
     28 struct RendererPreferences;  // from common/renderer_preferences.h
     29 
     30 const int kSkiaToGDKMultiplier = 257;
     31 
     32 // Define a macro for creating GdkColors from RGB values.  This is a macro to
     33 // allow static construction of literals, etc.  Use this like:
     34 //   GdkColor white = GDK_COLOR_RGB(0xff, 0xff, 0xff);
     35 #define GDK_COLOR_RGB(r, g, b) {0, r * kSkiaToGDKMultiplier, \
     36         g * kSkiaToGDKMultiplier, b * kSkiaToGDKMultiplier}
     37 
     38 namespace event_utils {
     39 
     40 // Translates event flags into what kind of disposition they represent.
     41 // For example, a middle click would mean to open a background tab.
     42 // event_flags are the state in the GdkEvent structure.
     43 WindowOpenDisposition DispositionFromEventFlags(guint state);
     44 
     45 }  // namespace event_utils
     46 
     47 namespace gtk_util {
     48 
     49 extern const GdkColor kGdkWhite;
     50 extern const GdkColor kGdkGray;
     51 extern const GdkColor kGdkBlack;
     52 extern const GdkColor kGdkGreen;
     53 
     54 // Constants relating to the layout of dialog windows:
     55 // (See http://library.gnome.org/devel/hig-book/stable/design-window.html.en)
     56 
     57 // Spacing between controls of the same group.
     58 const int kControlSpacing = 6;
     59 
     60 // Horizontal spacing between a label and its control.
     61 const int kLabelSpacing = 12;
     62 
     63 // Indent of the controls within each group.
     64 const int kGroupIndent = 12;
     65 
     66 // Space around the outside of a dialog's contents.
     67 const int kContentAreaBorder = 12;
     68 
     69 // Spacing between groups of controls.
     70 const int kContentAreaSpacing = 18;
     71 
     72 // Horizontal Spacing between controls in a form.
     73 const int kFormControlSpacing = 10;
     74 
     75 // Create a table of labeled controls, using proper spacing and alignment.
     76 // Arguments should be pairs of const char*, GtkWidget*, concluding with a
     77 // NULL.  The first argument is a vector in which to place all labels
     78 // produced. It can be NULL if you don't need to keep track of the label
     79 // widgets. The second argument is a color to force the label text to. It can
     80 // be NULL to get the system default.
     81 //
     82 // For example:
     83 // controls = CreateLabeledControlsGroup(NULL,
     84 //                                       "Name:", title_entry_,
     85 //                                       "Folder:", folder_combobox_,
     86 //                                       NULL);
     87 GtkWidget* CreateLabeledControlsGroup(
     88     std::vector<GtkWidget*>* labels,
     89     const char* text, ...);
     90 
     91 // Create a GtkBin with |child| as its child widget.  This bin will paint a
     92 // border of color |color| with the sizes specified in pixels.
     93 GtkWidget* CreateGtkBorderBin(GtkWidget* child, const GdkColor* color,
     94                               int top, int bottom, int left, int right);
     95 
     96 // Left-align the given GtkMisc and return the same pointer.
     97 GtkWidget* LeftAlignMisc(GtkWidget* misc);
     98 
     99 // Create a left-aligned label with the given text in bold.
    100 GtkWidget* CreateBoldLabel(const std::string& text);
    101 
    102 // As above, but uses number of characters/lines directly rather than looking up
    103 // a resource.
    104 void GetWidgetSizeFromCharacters(GtkWidget* widget,
    105                                  double width_chars, double height_lines,
    106                                  int* width, int* height);
    107 
    108 // Calculates the size of given widget based on the size specified in number of
    109 // characters/lines (in locale specific resource file) and font metrics.
    110 // NOTE: Make sure to realize |widget| before using this method, or a default
    111 // font size will be used instead of the actual font size.
    112 void GetWidgetSizeFromResources(GtkWidget* widget,
    113                                 int width_chars, int height_lines,
    114                                 int* width, int* height);
    115 
    116 // As above, but a convenience method for configuring dialog size.
    117 // |width_id| and |height_id| are resource IDs for the size.  If either of these
    118 // are set to -1, the respective size will be set to the widget default.
    119 // |resizable| also controls whether the dialog will be resizable
    120 // (this info is also necessary for getting the width-setting code
    121 // right).
    122 void SetWindowSizeFromResources(GtkWindow* window,
    123                                 int width_id, int height_id, bool resizable);
    124 
    125 // Places |window| approximately over center of |parent|, it also moves window
    126 // to parent's desktop. Use this only for non-modal dialogs, such as the
    127 // options window and content settings window; otherwise you should be using
    128 // transient_for.
    129 void CenterOverWindow(GtkWindow* window, GtkWindow* parent);
    130 
    131 // Puts all browser windows in one window group; this will make any dialog
    132 // spawned app modal.
    133 void MakeAppModalWindowGroup();
    134 
    135 // Called after an app modal dialog that used MakeAppModalWindowGroup() was
    136 // dismissed. Returns each browser window to its own window group.
    137 void AppModalDismissedUngroupWindows();
    138 
    139 // Remove all children from this container.
    140 void RemoveAllChildren(GtkWidget* container);
    141 
    142 // Force the font size of the widget to |size_pixels|.
    143 void ForceFontSizePixels(GtkWidget* widget, double size_pixels);
    144 
    145 // Undoes the effects of a previous ForceFontSizePixels() call. Safe to call
    146 // even if ForceFontSizePixels() was never called.
    147 void UndoForceFontSize(GtkWidget* widget);
    148 
    149 // Gets the position of a gtk widget in screen coordinates.
    150 gfx::Point GetWidgetScreenPosition(GtkWidget* widget);
    151 
    152 // Returns the bounds of the specified widget in screen coordinates.
    153 gfx::Rect GetWidgetScreenBounds(GtkWidget* widget);
    154 
    155 // Retuns size of the |widget| without window manager decorations.
    156 gfx::Size GetWidgetSize(GtkWidget* widget);
    157 
    158 // Converts a point in a widget to screen coordinates.  The point |p| is
    159 // relative to the widget's top-left origin.
    160 void ConvertWidgetPointToScreen(GtkWidget* widget, gfx::Point* p);
    161 
    162 // Initialize some GTK settings so that our dialogs are consistent.
    163 void InitRCStyles();
    164 
    165 // Stick the widget in the given hbox without expanding vertically. The widget
    166 // is packed at the start of the hbox. This is useful for widgets that would
    167 // otherwise expand to fill the vertical space of the hbox
    168 // (e.g. buttons). Returns the vbox that widget was packed in.
    169 GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget,
    170                               bool pack_at_end, int padding);
    171 
    172 // Returns true if the screen is composited, false otherwise.
    173 bool IsScreenComposited();
    174 
    175 // Enumerates the top-level gdk windows of the current display.
    176 void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate);
    177 
    178 // Set that clicking the button with the given mouse buttons will cause a click
    179 // event.
    180 // NOTE: If you need to connect to the button-press-event or
    181 // button-release-event signals, do so before calling this function.
    182 void SetButtonClickableByMouseButtons(GtkWidget* button,
    183                                       bool left, bool middle, bool right);
    184 
    185 // Set that a button causes a page navigation. In particular, it will accept
    186 // middle clicks. Warning: only call this *after* you have connected your
    187 // own handlers for button-press and button-release events, or you will not get
    188 // those events.
    189 void SetButtonTriggersNavigation(GtkWidget* button);
    190 
    191 // Returns the mirrored x value for |bounds| if the layout is RTL; otherwise,
    192 // the original value is returned unchanged.
    193 int MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds);
    194 
    195 // Returns the mirrored x value for the point |x| if the layout is RTL;
    196 // otherwise, the original value is returned unchanged.
    197 int MirroredXCoordinate(GtkWidget* widget, int x);
    198 
    199 // Returns true if the pointer is currently inside the widget.
    200 bool WidgetContainsCursor(GtkWidget* widget);
    201 
    202 // Sets the icon of |window| to the product icon (potentially used in window
    203 // border or alt-tab list).
    204 void SetWindowIcon(GtkWindow* window);
    205 
    206 // Sets the default window icon for all windows created in this app. |window|
    207 // is used to determine if a themed icon exists. If so, we use that icon,
    208 // otherwise we use the icon packaged with Chrome.
    209 void SetDefaultWindowIcon(GtkWindow* window);
    210 
    211 // Adds an action button with the given text to the dialog. Only useful when you
    212 // want a stock icon but not the stock text to go with it. Returns the button.
    213 GtkWidget* AddButtonToDialog(GtkWidget* dialog, const gchar* text,
    214                              const gchar* stock_id, gint response_id);
    215 
    216 GtkWidget* BuildDialogButton(GtkWidget* dialog, int ids_id,
    217                              const gchar* stock_id);
    218 
    219 GtkWidget* CreateEntryImageHBox(GtkWidget* entry, GtkWidget* image);
    220 
    221 // Sets all the foreground color states of |label| to |color|.
    222 void SetLabelColor(GtkWidget* label, const GdkColor* color);
    223 
    224 // Adds the given widget to an alignment identing it by |kGroupIndent|.
    225 GtkWidget* IndentWidget(GtkWidget* content);
    226 
    227 // Sets (or resets) the font settings in |prefs| (used when creating new
    228 // renderers) based on GtkSettings (which itself comes from XSETTINGS).
    229 void UpdateGtkFontSettings(RendererPreferences* prefs);
    230 
    231 // Get the current location of the mouse cursor relative to the screen.
    232 gfx::Point ScreenPoint(GtkWidget* widget);
    233 
    234 // Get the current location of the mouse cursor relative to the widget.
    235 gfx::Point ClientPoint(GtkWidget* widget);
    236 
    237 // Reverses a point in RTL mode. Used in making vectors of GdkPoints for window
    238 // shapes.
    239 GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr);
    240 
    241 // Draws a GTK text entry with the style parameters of GtkEntry
    242 // |offscreen_entry| onto |widget_to_draw_on| in the rectangle |rec|. Drawing
    243 // is only done in the clip rectangle |dirty_rec|.
    244 void DrawTextEntryBackground(GtkWidget* offscreen_entry,
    245                              GtkWidget* widget_to_draw_on,
    246                              GdkRectangle* dirty_rec,
    247                              GdkRectangle* rec);
    248 
    249 // Draws the background of the toolbar area subject to the expose rectangle
    250 // |event| and starting image tiling from |tabstrip_origin|.
    251 void DrawThemedToolbarBackground(GtkWidget* widget,
    252                                  cairo_t* cr,
    253                                  GdkEventExpose* event,
    254                                  const gfx::Point& tabstrip_origin,
    255                                  GtkThemeService* provider);
    256 
    257 // Returns the two colors averaged together.
    258 GdkColor AverageColors(GdkColor color_one, GdkColor color_two);
    259 
    260 // Show the image for the given menu item, even if the user's default is to not
    261 // show images. Only to be used for favicons or other menus where the image is
    262 // crucial to its functionality.
    263 void SetAlwaysShowImage(GtkWidget* image_menu_item);
    264 
    265 // Get a rectangle corresponding to a widget's allocation relative to its
    266 // toplevel window's origin.
    267 gfx::Rect GetWidgetRectRelativeToToplevel(GtkWidget* widget);
    268 
    269 // Don't allow the widget to paint anything, and instead propagate the expose
    270 // to its children. This is similar to calling
    271 //
    272 //   gtk_widget_set_app_paintable(container, TRUE);
    273 //
    274 // except that it will always work, and it should be called after any custom
    275 // expose events are connected.
    276 void SuppressDefaultPainting(GtkWidget* container);
    277 
    278 // Get the window open disposition from the state in gtk_get_current_event().
    279 // This is designed to be called inside a "clicked" event handler. It is an
    280 // error to call it when gtk_get_current_event() won't return a GdkEventButton*.
    281 WindowOpenDisposition DispositionForCurrentButtonPressEvent();
    282 
    283 // Safely grabs all input (with X grabs and an application grab), returning true
    284 // for success.
    285 bool GrabAllInput(GtkWidget* widget);
    286 
    287 // Returns a rectangle that represents the widget's bounds. The rectangle it
    288 // returns is the same as widget->allocation, but anchored at (0, 0).
    289 gfx::Rect WidgetBounds(GtkWidget* widget);
    290 
    291 // Update the timestamp for the given window. This is usually the time of the
    292 // last user event, but on rare occasions we wish to update it despite not
    293 // receiving a user event.
    294 void SetWMLastUserActionTime(GtkWindow* window);
    295 
    296 // The current system time, using the format expected by the X server, but not
    297 // retrieved from the X server. NOTE: You should almost never need to use this
    298 // function, instead using the timestamp from the latest GDK event.
    299 guint32 XTimeNow();
    300 
    301 // Uses the autocomplete controller for |profile| to convert the contents of the
    302 // PRIMARY selection to a parsed URL. Returns true and sets |url| on success,
    303 // otherwise returns false.
    304 bool URLFromPrimarySelection(Profile* profile, GURL* url);
    305 
    306 // Set the colormap of the given window to rgba to allow transparency.
    307 bool AddWindowAlphaChannel(GtkWidget* window);
    308 
    309 // Get the default colors for a text entry.  Parameters may be NULL.
    310 void GetTextColors(GdkColor* normal_base,
    311                    GdkColor* selected_base,
    312                    GdkColor* normal_text,
    313                    GdkColor* selected_text);
    314 
    315 // Wrappers to show a GtkDialog. On Linux, it merely calls gtk_widget_show_all.
    316 // On ChromeOs, it calls ShowNativeDialog which hosts the its vbox
    317 // in a view based Window.
    318 void ShowDialog(GtkWidget* dialog);
    319 void ShowDialogWithLocalizedSize(GtkWidget* dialog,
    320                                  int width_id,
    321                                  int height_id,
    322                                  bool resizeable);
    323 void ShowDialogWithMinLocalizedWidth(GtkWidget* dialog,
    324                                      int width_id);
    325 
    326 // Wrapper to present a window. On Linux, it just calls gtk_window_present or
    327 // gtk_window_present_with_time for non-zero timestamp. For ChromeOS, it first
    328 // finds the host window of the dialog contents and then present it.
    329 void PresentWindow(GtkWidget* window, int timestamp);
    330 
    331 // Get real window for given dialog. On ChromeOS, this gives the native dialog
    332 // host window. On Linux, it merely returns the passed in dialog.
    333 GtkWindow* GetDialogWindow(GtkWidget* dialog);
    334 
    335 // Gets dialog window bounds.
    336 gfx::Rect GetDialogBounds(GtkWidget* dialog);
    337 
    338 // Returns the stock menu item label for the "preferences" item - returns an
    339 // empty string if no stock item found.
    340 string16 GetStockPreferencesMenuLabel();
    341 
    342 // Checks whether a widget is actually visible, i.e. whether it and all its
    343 // ancestors up to its toplevel are visible.
    344 bool IsWidgetAncestryVisible(GtkWidget* widget);
    345 
    346 // Sets the given label's size request to |pixel_width|. This will cause the
    347 // label to wrap if it needs to. The reason for this function is that some
    348 // versions of GTK mis-align labels that have a size request and line wrapping,
    349 // and this function hides the complexity of the workaround.
    350 void SetLabelWidth(GtkWidget* label, int pixel_width);
    351 
    352 // Make the |label| shrinkable within a GthChromeShrinkableHBox
    353 // It calculates the real size request of a label and set its ellipsize mode to
    354 // PANGO_ELLIPSIZE_END.
    355 // It must be done when the label is mapped (become visible on the screen),
    356 // to make sure the pango can get correct font information for the calculation.
    357 void InitLabelSizeRequestAndEllipsizeMode(GtkWidget* label);
    358 
    359 // Convenience methods for converting between web drag operations and the GDK
    360 // equivalent.
    361 GdkDragAction WebDragOpToGdkDragAction(WebKit::WebDragOperationsMask op);
    362 WebKit::WebDragOperationsMask GdkDragActionToWebDragOp(GdkDragAction action);
    363 
    364 // A helper function for gtk_message_dialog_new() to work around a few KDE 3
    365 // window manager bugs. You should always call it after creating a dialog with
    366 // gtk_message_dialog_new.
    367 void ApplyMessageDialogQuirks(GtkWidget* dialog);
    368 
    369 // Performs Cut/Copy/Paste operation on the |window|.
    370 void DoCut(BrowserWindow* window);
    371 void DoCopy(BrowserWindow* window);
    372 void DoPaste(BrowserWindow* window);
    373 
    374 }  // namespace gtk_util
    375 
    376 #endif  // CHROME_BROWSER_UI_GTK_GTK_UTIL_H_
    377