• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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