Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2012 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 
      8 #include <gtk/gtk.h>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/strings/string16.h"
     13 #include "ui/base/window_open_disposition.h"
     14 #include "ui/base/x/x11_util.h"
     15 #include "ui/gfx/point.h"
     16 #include "ui/gfx/rect.h"
     17 
     18 typedef struct _cairo cairo_t;
     19 typedef struct _GtkWidget GtkWidget;
     20 
     21 class BrowserWindow;
     22 class GtkThemeService;
     23 class GURL;
     24 class Profile;
     25 
     26 namespace gfx {
     27 class Image;
     28 }
     29 
     30 namespace gtk_util {
     31 
     32 // Create a table of labeled controls, using proper spacing and alignment.
     33 // Arguments should be pairs of const char*, GtkWidget*, concluding with a
     34 // NULL.  The first argument is a vector in which to place all labels
     35 // produced. It can be NULL if you don't need to keep track of the label
     36 // widgets. The second argument is a color to force the label text to. It can
     37 // be NULL to get the system default.
     38 //
     39 // For example:
     40 // controls = CreateLabeledControlsGroup(NULL,
     41 //                                       "Name:", title_entry_,
     42 //                                       "Folder:", folder_combobox_,
     43 //                                       NULL);
     44 GtkWidget* CreateLabeledControlsGroup(
     45     std::vector<GtkWidget*>* labels,
     46     const char* text, ...);
     47 
     48 // Create a GtkBin with |child| as its child widget.  This bin will paint a
     49 // border of color |color| with the sizes specified in pixels.
     50 GtkWidget* CreateGtkBorderBin(GtkWidget* child, const GdkColor* color,
     51                               int top, int bottom, int left, int right);
     52 
     53 // Left-align the given GtkMisc and return the same pointer.
     54 GtkWidget* LeftAlignMisc(GtkWidget* misc);
     55 
     56 // Create a left-aligned label with the given text in bold.
     57 GtkWidget* CreateBoldLabel(const std::string& text);
     58 
     59 // As above, but uses number of characters/lines directly rather than looking up
     60 // a resource.
     61 void GetWidgetSizeFromCharacters(GtkWidget* widget,
     62                                  double width_chars, double height_lines,
     63                                  int* width, int* height);
     64 
     65 // Calculates the size of given widget based on the size specified in number of
     66 // characters/lines (in locale specific resource file) and font metrics.
     67 // NOTE: Make sure to realize |widget| before using this method, or a default
     68 // font size will be used instead of the actual font size.
     69 void GetWidgetSizeFromResources(GtkWidget* widget,
     70                                 int width_chars, int height_lines,
     71                                 int* width, int* height);
     72 
     73 // As above, but a convenience method for configuring dialog size.
     74 // |width_id| and |height_id| are resource IDs for the size.  If either of these
     75 // are set to -1, the respective size will be set to the widget default.
     76 // |resizable| also controls whether the dialog will be resizable
     77 // (this info is also necessary for getting the width-setting code
     78 // right).
     79 void SetWindowSizeFromResources(GtkWindow* window,
     80                                 int width_id, int height_id, bool resizable);
     81 
     82 // Puts all browser windows in one window group; this will make any dialog
     83 // spawned app modal.
     84 void MakeAppModalWindowGroup();
     85 
     86 // Called after an app modal dialog that used MakeAppModalWindowGroup() was
     87 // dismissed. Returns each browser window to its own window group.
     88 void AppModalDismissedUngroupWindows();
     89 
     90 // Remove all children from this container.
     91 void RemoveAllChildren(GtkWidget* container);
     92 
     93 // Force the font size of the widget to |size_pixels|.
     94 void ForceFontSizePixels(GtkWidget* widget, double size_pixels);
     95 
     96 // Undoes the effects of a previous ForceFontSizePixels() call. Safe to call
     97 // even if ForceFontSizePixels() was never called.
     98 void UndoForceFontSize(GtkWidget* widget);
     99 
    100 // Retuns size of the |widget| without window manager decorations.
    101 gfx::Size GetWidgetSize(GtkWidget* widget);
    102 
    103 // Converts a point in a widget to screen coordinates.  The point |p| is
    104 // relative to the widget's top-left origin.
    105 void ConvertWidgetPointToScreen(GtkWidget* widget, gfx::Point* p);
    106 
    107 // Stick the widget in the given hbox without expanding vertically. The widget
    108 // is packed at the start of the hbox. This is useful for widgets that would
    109 // otherwise expand to fill the vertical space of the hbox
    110 // (e.g. buttons). Returns the vbox that widget was packed in.
    111 GtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget,
    112                               bool pack_at_end, int padding);
    113 
    114 // Set that clicking the button with the given mouse buttons will cause a click
    115 // event.
    116 // NOTE: If you need to connect to the button-press-event or
    117 // button-release-event signals, do so before calling this function.
    118 void SetButtonClickableByMouseButtons(GtkWidget* button,
    119                                       bool left, bool middle, bool right);
    120 
    121 // Set that a button causes a page navigation. In particular, it will accept
    122 // middle clicks. Warning: only call this *after* you have connected your
    123 // own handlers for button-press and button-release events, or you will not get
    124 // those events.
    125 void SetButtonTriggersNavigation(GtkWidget* button);
    126 
    127 // Returns the mirrored x value for |bounds| if the layout is RTL; otherwise,
    128 // the original value is returned unchanged.
    129 int MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds);
    130 
    131 // Returns the mirrored right value for |bounds| if the layout is RTL;
    132 // otherwise, the original value is returned unchanged.
    133 int MirroredRightPointForRect(GtkWidget* widget, const gfx::Rect& bounds);
    134 
    135 // Returns the mirrored x value for the point |x| if the layout is RTL;
    136 // otherwise, the original value is returned unchanged.
    137 int MirroredXCoordinate(GtkWidget* widget, int x);
    138 
    139 // Returns true if the pointer is currently inside the widget.
    140 bool WidgetContainsCursor(GtkWidget* widget);
    141 
    142 // Sets the default window icon for all windows created in this app. This icon
    143 // will only be used if a window has not explicitly been assigned an icon
    144 // (e.g. by SetWindowIcon()).
    145 //
    146 // |window| is only used to determine if a themed icon exists. If so, we use
    147 // that icon, otherwise we use the icon packaged with Chrome.
    148 void SetDefaultWindowIcon(GtkWindow* window);
    149 
    150 // Sets the icon of |window| to the Chrome product icon, overlaid with
    151 // |profile|'s avatar icon (or the Incognito icon for Incognito windows). It
    152 // first looks for a themed icon, then falls back to the product icons
    153 // packaged with Chrome.
    154 void SetWindowIcon(GtkWindow* window, Profile* profile);
    155 
    156 // Sets the icon of |window| to |icon|, overlaid with |profile|'s avatar icon
    157 // (or the Incognito icon for Incognito windows). It first looks for a themed
    158 // icon, then falls back to the product icons packaged with Chrome.
    159 //
    160 // Note that |icon| will be modified by this function.
    161 void SetWindowIcon(GtkWindow* window, Profile* profile, GdkPixbuf* icon);
    162 
    163 // Adds an action button with the given text to the dialog. Only useful when you
    164 // want a stock icon but not the stock text to go with it. Returns the button.
    165 GtkWidget* AddButtonToDialog(GtkWidget* dialog, const gchar* text,
    166                              const gchar* stock_id, gint response_id);
    167 
    168 GtkWidget* BuildDialogButton(GtkWidget* dialog, int ids_id,
    169                              const gchar* stock_id);
    170 
    171 GtkWidget* CreateEntryImageHBox(GtkWidget* entry, GtkWidget* image);
    172 
    173 // Sets all the foreground color states of |label| to |color|.
    174 void SetLabelColor(GtkWidget* label, const GdkColor* color);
    175 
    176 // Adds the given widget to an alignment identing it by |kGroupIndent|.
    177 GtkWidget* IndentWidget(GtkWidget* content);
    178 
    179 // Reverses a point in RTL mode. Used in making vectors of GdkPoints for window
    180 // shapes.
    181 GdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr);
    182 
    183 // Creates a tooltip string to be passed to gtk_widget_set_tooltip_markup from
    184 // the title and URL.
    185 std::string BuildTooltipTitleFor(base::string16 title, const GURL& url);
    186 
    187 // Draws a GTK text entry with the style parameters of GtkEntry
    188 // |offscreen_entry| onto |widget_to_draw_on| in the rectangle |rec|. Drawing
    189 // is only done in the clip rectangle |dirty_rec|.
    190 void DrawTextEntryBackground(GtkWidget* offscreen_entry,
    191                              GtkWidget* widget_to_draw_on,
    192                              GdkRectangle* dirty_rec,
    193                              GdkRectangle* rec);
    194 
    195 // Set up the text to be displayed by |layout|.
    196 void SetLayoutText(PangoLayout* layout, const base::string16& text);
    197 
    198 // Draws the background of the toolbar area subject to the expose rectangle
    199 // |event| and starting image tiling from |tabstrip_origin|.
    200 void DrawThemedToolbarBackground(GtkWidget* widget,
    201                                  cairo_t* cr,
    202                                  GdkEventExpose* event,
    203                                  const gfx::Point& tabstrip_origin,
    204                                  GtkThemeService* provider);
    205 
    206 // Draw an entire pixbuf without dithering.
    207 void DrawFullImage(cairo_t* cr,
    208                    GtkWidget* widget,
    209                    const gfx::Image& image,
    210                    gint dest_x,
    211                    gint dest_y);
    212 
    213 // Returns the two colors averaged together.
    214 GdkColor AverageColors(GdkColor color_one, GdkColor color_two);
    215 
    216 // Show the image for the given menu item, even if the user's default is to not
    217 // show images. Only to be used for favicons or other menus where the image is
    218 // crucial to its functionality.
    219 void SetAlwaysShowImage(GtkWidget* image_menu_item);
    220 
    221 // Get a rectangle corresponding to a widget's allocation relative to its
    222 // toplevel window's origin.
    223 gfx::Rect GetWidgetRectRelativeToToplevel(GtkWidget* widget);
    224 
    225 // Don't allow the widget to paint anything, and instead propagate the expose
    226 // to its children. This is similar to calling
    227 //
    228 //   gtk_widget_set_app_paintable(container, TRUE);
    229 //
    230 // except that it will always work, and it should be called after any custom
    231 // expose events are connected.
    232 void SuppressDefaultPainting(GtkWidget* container);
    233 
    234 // Safely grabs all input (with X grabs and an application grab), returning true
    235 // for success.
    236 bool GrabAllInput(GtkWidget* widget);
    237 
    238 // Returns a rectangle that represents the widget's bounds. The rectangle it
    239 // returns is the same as gtk_widget_get_allocation, but anchored at (0, 0).
    240 gfx::Rect WidgetBounds(GtkWidget* widget);
    241 
    242 // Update the timestamp for the given window. This is usually the time of the
    243 // last user event, but on rare occasions we wish to update it despite not
    244 // receiving a user event.
    245 void SetWMLastUserActionTime(GtkWindow* window);
    246 
    247 // The current system time, using the format expected by the X server, but not
    248 // retrieved from the X server. NOTE: You should almost never need to use this
    249 // function, instead using the timestamp from the latest GDK event.
    250 guint32 XTimeNow();
    251 
    252 // Uses the autocomplete controller for |profile| to convert the contents of the
    253 // PRIMARY selection to a parsed URL. Returns true and sets |url| on success,
    254 // otherwise returns false.
    255 bool URLFromPrimarySelection(Profile* profile, GURL* url);
    256 
    257 // Set the colormap of the given window to rgba to allow transparency.
    258 bool AddWindowAlphaChannel(GtkWidget* window);
    259 
    260 // Get the default colors for a text entry.  Parameters may be NULL.
    261 void GetTextColors(GdkColor* normal_base,
    262                    GdkColor* selected_base,
    263                    GdkColor* normal_text,
    264                    GdkColor* selected_text);
    265 
    266 // Wrappers to show a GtkDialog. On Linux, it merely calls gtk_widget_show_all.
    267 // On ChromeOs, it calls ShowNativeDialog which hosts the its vbox
    268 // in a view based Window.
    269 void ShowDialog(GtkWidget* dialog);
    270 void ShowDialogWithLocalizedSize(GtkWidget* dialog,
    271                                  int width_id,
    272                                  int height_id,
    273                                  bool resizeable);
    274 void ShowDialogWithMinLocalizedWidth(GtkWidget* dialog,
    275                                      int width_id);
    276 
    277 // Wrapper to present a window. On Linux, it just calls gtk_window_present or
    278 // gtk_window_present_with_time for non-zero timestamp.
    279 void PresentWindow(GtkWidget* window, int timestamp);
    280 
    281 // Gets dialog window bounds.
    282 gfx::Rect GetDialogBounds(GtkWidget* dialog);
    283 
    284 // Returns the stock menu item label for the "preferences" item - returns an
    285 // empty string if no stock item found.
    286 base::string16 GetStockPreferencesMenuLabel();
    287 
    288 // Checks whether a widget is actually visible, i.e. whether it and all its
    289 // ancestors up to its toplevel are visible.
    290 bool IsWidgetAncestryVisible(GtkWidget* widget);
    291 
    292 // Sets the given label's size request to |pixel_width|. This will cause the
    293 // label to wrap if it needs to. The reason for this function is that some
    294 // versions of GTK mis-align labels that have a size request and line wrapping,
    295 // and this function hides the complexity of the workaround.
    296 void SetLabelWidth(GtkWidget* label, int pixel_width);
    297 
    298 // Make the |label| shrinkable within a GthChromeShrinkableHBox
    299 // It calculates the real size request of a label and set its ellipsize mode to
    300 // PANGO_ELLIPSIZE_END.
    301 // It must be done when the label is mapped (become visible on the screen),
    302 // to make sure the pango can get correct font information for the calculation.
    303 void InitLabelSizeRequestAndEllipsizeMode(GtkWidget* label);
    304 
    305 // A helper function for gtk_message_dialog_new() to work around a few KDE 3
    306 // window manager bugs. You should always call it after creating a dialog with
    307 // gtk_message_dialog_new.
    308 void ApplyMessageDialogQuirks(GtkWidget* dialog);
    309 
    310 }  // namespace gtk_util
    311 
    312 #endif  // CHROME_BROWSER_UI_GTK_GTK_UTIL_H_
    313