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|. 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 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 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 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 137 void ViewIDUtil::SetDelegateForWidget(GtkWidget* widget, Delegate* delegate) { 138 g_object_set_data(G_OBJECT(widget), kViewIDOverrideString, delegate); 139 } 140