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 #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_ACTION_BOX_BUTTON:
     84       return "chrome-action-box-button";
     85 
     86     case VIEW_ID_BROWSER_ACTION_TOOLBAR:
     87       return "chrome-toolbar-browser-actions-container";
     88 
     89     case VIEW_ID_OMNIBOX:
     90       return "chrome-omnibox";
     91 
     92     case VIEW_ID_APP_MENU:
     93       return "chrome-app-menu";
     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     case VIEW_ID_ZOOM_BUTTON:
    111       return "chrome-zoom-button";
    112 
    113     case VIEW_ID_MANAGE_PASSWORDS_ICON_BUTTON:
    114       return "chrome-manage-passwords-icon-button";
    115 
    116     case VIEW_ID_SCRIPT_BUBBLE:
    117       return "chrome-script-bubble-button";
    118 
    119     // These are never hit because the tab container uses the delegate to
    120     // set its ID.
    121     case VIEW_ID_TAB_CONTAINER:
    122     default:
    123       NOTREACHED() << "If you added a new VIEW_ID, please provide "
    124                       "a name for the widget.";
    125       return NULL;
    126   }
    127 }
    128 
    129 }  // namespace
    130 
    131 void ViewIDUtil::SetID(GtkWidget* widget, ViewID id) {
    132   const char* name = GetNameFromID(id);
    133   if (name)
    134     gtk_widget_set_name(widget, name);
    135   g_object_set_data(G_OBJECT(widget), kViewIDString,
    136                     reinterpret_cast<void*>(id));
    137 }
    138 
    139 GtkWidget* ViewIDUtil::GetWidget(GtkWidget* root, ViewID id) {
    140   ViewIDSearchStruct search_struct = { id, NULL };
    141   SearchForWidgetWithViewID(root, &search_struct);
    142   return search_struct.widget;
    143 }
    144 
    145 void ViewIDUtil::SetDelegateForWidget(GtkWidget* widget, Delegate* delegate) {
    146   g_object_set_data(G_OBJECT(widget), kViewIDOverrideString, delegate);
    147 }
    148