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 #include "chrome/browser/ui/gtk/view_id_util.h"
6
7 #include <stdint.h>
8 #include <string>
9
10 #include <gtk/gtk.h>
11
12 #include "base/logging.h"
13
14 namespace {
15
16 const char kViewIDString[] = "__VIEW_ID__";
17 const char kViewIDOverrideString[] = "__VIEW_ID_OVERRIDE__";
18
19 struct ViewIDSearchStruct {
20 ViewID id; // Input: the ID we are searching for.
21 GtkWidget* widget; // Output: the found widget, or NULL.
22 };
23
24 // Recursively search for the given view ID among the children of |widget|.
SearchForWidgetWithViewID(GtkWidget * widget,gpointer data)25 void SearchForWidgetWithViewID(GtkWidget* widget, gpointer data) {
26 ViewIDSearchStruct* search_struct =
27 reinterpret_cast<ViewIDSearchStruct*>(data);
28
29 // The widget has already been found; abort the search.
30 if (search_struct->widget)
31 return;
32
33 // Check if the widget defines its own ID function.
34 ViewIDUtil::Delegate* delegate = reinterpret_cast<ViewIDUtil::Delegate*>(
35 g_object_get_data(G_OBJECT(widget), kViewIDOverrideString));
36 if (delegate) {
37 search_struct->widget = delegate->GetWidgetForViewID(search_struct->id);
38 // If there was success, return.
39 if (search_struct->widget)
40 return;
41 }
42
43 // Otherwise check the g_object data.
44 int widget_id =
45 reinterpret_cast<intptr_t>(g_object_get_data(G_OBJECT(widget),
46 kViewIDString));
47 if (search_struct->id == widget_id) {
48 // Success; set |widget| and return.
49 search_struct->widget = widget;
50 return;
51 }
52
53 // Recurse.
54 if (GTK_IS_CONTAINER(widget)) {
55 gtk_container_foreach(GTK_CONTAINER(widget),
56 SearchForWidgetWithViewID, data);
57 }
58 }
59
GetNameFromID(ViewID id)60 const char* GetNameFromID(ViewID id) {
61 switch (id) {
62 case VIEW_ID_TAB_STRIP:
63 return "chrome-tab-strip";
64
65 case VIEW_ID_TOOLBAR:
66 return "chrome-toolbar";
67
68 case VIEW_ID_BACK_BUTTON:
69 return "chrome-toolbar-back-button";
70
71 case VIEW_ID_FORWARD_BUTTON:
72 return "chrome-toolbar-forward-button";
73
74 case VIEW_ID_RELOAD_BUTTON:
75 return "chrome-toolbar-reload-button";
76
77 case VIEW_ID_HOME_BUTTON:
78 return "chrome-toolbar-home-button";
79
80 case VIEW_ID_STAR_BUTTON:
81 return "chrome-toolbar-star-button";
82
83 case VIEW_ID_LOCATION_BAR:
84 return "chrome-location-bar";
85
86 case VIEW_ID_BROWSER_ACTION_TOOLBAR:
87 return "chrome-toolbar-browser-actions-container";
88
89 case VIEW_ID_APP_MENU:
90 return "chrome-app-menu";
91
92 case VIEW_ID_AUTOCOMPLETE:
93 return "chrome-autocomplete-edit";
94
95 case VIEW_ID_BOOKMARK_BAR:
96 return "chrome-bookmark-bar";
97
98 case VIEW_ID_OTHER_BOOKMARKS:
99 return "chrome-bookmark-bar-other-bookmarks";
100
101 case VIEW_ID_FIND_IN_PAGE_TEXT_FIELD:
102 return "chrome-find-in-page-entry";
103
104 case VIEW_ID_FIND_IN_PAGE:
105 return "chrome-find-in-page";
106
107 case VIEW_ID_DEV_TOOLS_DOCKED:
108 return "chrome-dev-tools-docked";
109
110 // These are never hit because the tab container uses the delegate to
111 // set its ID.
112 case VIEW_ID_TAB_CONTAINER:
113 case VIEW_ID_TAB_CONTAINER_FOCUS_VIEW:
114 default:
115 NOTREACHED() << "If you added a new VIEW_ID, please provide "
116 "a name for the widget.";
117 return NULL;
118 }
119 }
120
121 } // namespace
122
SetID(GtkWidget * widget,ViewID id)123 void ViewIDUtil::SetID(GtkWidget* widget, ViewID id) {
124 const char* name = GetNameFromID(id);
125 if (name)
126 gtk_widget_set_name(widget, name);
127 g_object_set_data(G_OBJECT(widget), kViewIDString,
128 reinterpret_cast<void*>(id));
129 }
130
GetWidget(GtkWidget * root,ViewID id)131 GtkWidget* ViewIDUtil::GetWidget(GtkWidget* root, ViewID id) {
132 ViewIDSearchStruct search_struct = { id, NULL };
133 SearchForWidgetWithViewID(root, &search_struct);
134 return search_struct.widget;
135 }
136
SetDelegateForWidget(GtkWidget * widget,Delegate * delegate)137 void ViewIDUtil::SetDelegateForWidget(GtkWidget* widget, Delegate* delegate) {
138 g_object_set_data(G_OBJECT(widget), kViewIDOverrideString, delegate);
139 }
140