summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/view_id_util.cc
blob: fe6501fd71bad4edfa6dc3132d679eab220f2be4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/view_id_util.h"

#include <stdint.h>

#include <gtk/gtk.h>

namespace {

const char kViewIDString[] = "__VIEW_ID__";
const char kViewIDOverrideString[] = "__VIEW_ID_OVERRIDE__";

struct ViewIDSearchStruct {
  ViewID id;  // Input: the ID we are searching for.
  GtkWidget* widget;  // Output: the found widget, or NULL.
};

// Recursively search for the given view ID among the children of |widget|.
void SearchForWidgetWithViewID(GtkWidget* widget, gpointer data) {
  ViewIDSearchStruct* search_struct =
      reinterpret_cast<ViewIDSearchStruct*>(data);

  // The widget has already been found; abort the search.
  if (search_struct->widget)
    return;

  // Check if the widget defines its own ID function.
  ViewIDUtil::Delegate* delegate = reinterpret_cast<ViewIDUtil::Delegate*>(
      g_object_get_data(G_OBJECT(widget), kViewIDOverrideString));
  if (delegate) {
    search_struct->widget = delegate->GetWidgetForViewID(search_struct->id);
    // If there was success, return.
    if (search_struct->widget)
      return;
  }

  // Otherwise check the g_object data.
  int widget_id =
      reinterpret_cast<intptr_t>(g_object_get_data(G_OBJECT(widget),
                                 kViewIDString));
  if (search_struct->id == widget_id) {
    // Success; set |widget| and return.
    search_struct->widget = widget;
    return;
  }

  // Recurse.
  if (GTK_IS_CONTAINER(widget)) {
    gtk_container_foreach(GTK_CONTAINER(widget),
                          SearchForWidgetWithViewID, data);
  }
}

}  // namespace

void ViewIDUtil::SetID(GtkWidget* widget, ViewID id) {
  g_object_set_data(G_OBJECT(widget), kViewIDString,
                    reinterpret_cast<void*>(id));
}

GtkWidget* ViewIDUtil::GetWidget(GtkWidget* root, ViewID id) {
  ViewIDSearchStruct search_struct = { id, NULL };
  SearchForWidgetWithViewID(root, &search_struct);
  return search_struct.widget;
}

void ViewIDUtil::SetDelegateForWidget(GtkWidget* widget, Delegate* delegate) {
  g_object_set_data(G_OBJECT(widget), kViewIDOverrideString, delegate);
}