python-loader: Fix build with python3 (bgo#633786)
[anjuta.git] / libanjuta / anjuta-dock.c
blobc3bf5d0100e9953aed2ed0008f617702d9aea700
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * git-shell-test
4 * Copyright (C) James Liggett 2009 <jrliggett@cox.net>
5 *
6 * git-shell-test is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * git-shell-test is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "anjuta-dock.h"
22 /**
23 * SECTION: AnjutaDock
24 * @short_description: Docking system for context-driven user interfaces.
25 * @see_also: #AnjutaCommandBar
26 * @include; libanjuta/anjuta-dock.h
28 * AnjutaDock provides an alternative to the traditional menu and toolbar based
29 * methodologies used by most GNOME programs. Instead, it focuses on tasks, or
30 * related sets of tasks. Each pane in the dock corresponds to a different set
31 * of related tasks.
33 * Optionally, you can also associate an #AnjutaCommandBar with an AnjutaDock to
34 * provide contextually appropriate sets of commands depending on the currently
35 * visible pane
38 struct _AnjutaDockPriv
40 GHashTable *panes;
41 GHashTable *dock_items;
42 GtkWidget *command_bar;
45 G_DEFINE_TYPE (AnjutaDock, anjuta_dock, GDL_TYPE_DOCK);
47 static void
48 anjuta_dock_init (AnjutaDock *self)
50 self->priv = g_new0 (AnjutaDockPriv, 1);
51 self->priv->panes = g_hash_table_new_full (g_str_hash, g_str_equal,
52 NULL, g_object_unref);
53 self->priv->dock_items = g_hash_table_new (g_str_hash, g_str_equal);
56 static void
57 anjuta_dock_finalize (GObject *object)
59 AnjutaDock *self;
61 self = ANJUTA_DOCK (object);
63 g_hash_table_destroy (self->priv->panes);
64 g_hash_table_destroy (self->priv->dock_items);
65 g_free (self->priv);
67 G_OBJECT_CLASS (anjuta_dock_parent_class)->finalize (object);
70 static void
71 on_pane_selected (GdlDockItem *item, AnjutaCommandBar *command_bar)
73 const gchar *pane_name;
75 pane_name = (const gchar *) g_object_get_data (G_OBJECT (item),
76 "pane-name");
77 anjuta_command_bar_show_action_group (command_bar, pane_name);
81 static void
82 disconnect_select_signals (gpointer key, GdlDockItem *value,
83 AnjutaCommandBar *command_bar)
85 g_signal_handlers_disconnect_by_func (value, G_CALLBACK (on_pane_selected),
86 command_bar);
89 static void
90 anjuta_dock_dispose (GObject *object)
92 AnjutaDock *self;
94 self = ANJUTA_DOCK (object);
96 if (self->priv->command_bar)
98 /* Disconnect pane selection signals before dropping the command bar
99 * reference. It is possible that we may be holding the last reference
100 * of the bar, creating the possibility that the parent implementation
101 * of dispose might do something that would call the signal handler that
102 * would reference the already destroyed command bar. */
103 g_hash_table_foreach (self->priv->dock_items,
104 (GHFunc) disconnect_select_signals,
105 self->priv->command_bar);
107 g_object_unref (self->priv->command_bar);
108 self->priv->command_bar = NULL;
111 G_OBJECT_CLASS (anjuta_dock_parent_class)->dispose (object);
114 static void
115 anjuta_dock_class_init (AnjutaDockClass *klass)
117 GObjectClass* object_class = G_OBJECT_CLASS (klass);
119 object_class->finalize = anjuta_dock_finalize;
120 object_class->dispose = anjuta_dock_dispose;
124 * anjuta_dock_new:
126 * Creates a new AnjutaDock.
128 GtkWidget *
129 anjuta_dock_new (void)
131 return g_object_new (ANJUTA_TYPE_DOCK, NULL);
135 * anjuta_dock_add_pane:
136 * @self: An AnjutaDock
137 * @pane_name: A unique name for this pane
138 * @pane_label: Label to display in this pane's grip
139 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
140 * the pane object.
141 * @stock_id: Stock icon to display in this pane's grip
142 * @placement: A #GdlDockPlacement value indicating where the pane should be
143 * placed
144 * @entries: #AnjutaCommandBar entries for this pane. Can be %NULL
145 * @num_entries: The number of entries pointed to by entries, or 0.
146 * @user_data: User data to pass to the entry callback
148 * Adds a pane, with optional #AnjutaCommandBar entries, to an AnjutaDock. This
149 * method adds a pane with no grip that cannot be closed, floating or iconified.
151 void
152 anjuta_dock_add_pane (AnjutaDock *self, const gchar *pane_name,
153 const gchar *pane_label, const gchar *stock_icon,
154 AnjutaDockPane *pane, GdlDockPlacement placement,
155 AnjutaCommandBarEntry *entries, int num_entries,
156 gpointer user_data)
158 int behavior;
160 behavior = 0;
161 behavior |= GDL_DOCK_ITEM_BEH_NO_GRIP;
162 behavior |= GDL_DOCK_ITEM_BEH_CANT_CLOSE;
163 behavior |= GDL_DOCK_ITEM_BEH_CANT_ICONIFY;
164 behavior |= GDL_DOCK_ITEM_BEH_NEVER_FLOATING;
166 anjuta_dock_add_pane_full (self, pane_name, pane_label, stock_icon,
167 pane, placement, entries, num_entries,
168 user_data, behavior);
172 * anjuta_dock_add_pane_full:
173 * @self: An AnjutaDock
174 * @pane_name: A unique name for this pane
175 * @pane_label: Label to display in this pane's grip
176 * @stock_id: Stock icon to display in this pane's grip
177 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
178 * the pane object.
179 * @placement: A #GdlDockPlacement value indicating where the pane should be
180 * placed
181 * @entries: #AnjutaCommandBar entries for this pane. Can be %NULL
182 * @num_entries: The number of entries pointed to by entries, or 0.
183 * @user_data: User data to pass to the entry callback
184 * @behavior: Any combination of #GdlDockItemBehavior flags
186 * Does the same thing as anjuta_dock_add_pane, but allows GDL dock behavior
187 * flags to be specified.
189 void
190 anjuta_dock_add_pane_full (AnjutaDock *self, const gchar *pane_name,
191 const gchar *pane_label, const gchar *stock_icon,
192 AnjutaDockPane *pane,
193 GdlDockPlacement placement,
194 AnjutaCommandBarEntry *entries, int num_entries,
195 gpointer user_data,
196 GdlDockItemBehavior behavior)
198 GtkWidget *dock_item;
199 GtkWidget *child;
201 dock_item = gdl_dock_item_new (pane_name, pane_label, behavior);
202 child = anjuta_dock_pane_get_widget (pane);
203 g_object_set_data (G_OBJECT (child), "dock-item", dock_item);
205 /* Make sure there isn't another dock with the same name */
206 if (!g_hash_table_lookup_extended (self->priv->panes, pane_name, NULL,
207 NULL))
209 /* Take ownership of the pane object */
210 g_hash_table_insert (self->priv->panes, (gchar *) pane_name, pane);
212 gtk_container_add (GTK_CONTAINER (dock_item), child);
213 gdl_dock_add_item (GDL_DOCK (self), GDL_DOCK_ITEM (dock_item), placement);
215 g_object_set_data (G_OBJECT (dock_item), "pane-name", (gchar *) pane_name);
217 /* Don't add anything to the action bar if there are no entries */
218 if (self->priv->command_bar && entries)
220 anjuta_command_bar_add_action_group (ANJUTA_COMMAND_BAR (self->priv->command_bar),
221 pane_name, entries, num_entries,
222 user_data);
224 g_signal_connect (G_OBJECT (dock_item), "selected",
225 G_CALLBACK (on_pane_selected),
226 self->priv->command_bar);
228 g_hash_table_insert (self->priv->dock_items, (gchar *) pane_name,
229 dock_item);
231 /* Show the new pane's commands in the command bar */
232 anjuta_command_bar_show_action_group (ANJUTA_COMMAND_BAR (self->priv->command_bar),
233 pane_name);
239 * anjuta_dock_remove_pane:
240 * @self An AnjutaDock
241 * @pane_name: Name of the pane to remove
243 * Removes a pane from a dock
245 void
246 anjuta_dock_remove_pane (AnjutaDock *self, AnjutaDockPane *pane)
248 GtkWidget *child;
249 GtkContainer *dock_item;
251 child = anjuta_dock_pane_get_widget (pane);
253 if (child)
255 /* Remove the child from its dock item and destroy it */
256 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
257 g_hash_table_remove (self->priv->panes,
258 g_object_get_data (G_OBJECT (dock_item),
259 "pane-name"));
260 gtk_container_remove (dock_item, child);
262 gdl_dock_item_unbind (GDL_DOCK_ITEM (dock_item));
267 * anjuta_dock_show_pane:
268 * @self: An AnjutaDock
269 * @pane_name: Name of the pane to show
271 * Makes the given pane visible
273 void
274 anjuta_dock_show_pane (AnjutaDock *self, AnjutaDockPane *pane)
276 GtkWidget *child;
277 GdlDockItem *dock_item;
279 child = anjuta_dock_pane_get_widget (pane);
281 if (child)
283 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
284 gdl_dock_item_show_item (dock_item);
289 * anjuta_dock_hide_pane:
290 * @self: An AnjutaDock
291 * @pane_name: Name of the pane to hide
293 * Makes the given pane invisible
295 void
296 anjuta_dock_hide_pane (AnjutaDock *self, AnjutaDockPane *pane)
298 GtkWidget *child;
299 GdlDockItem *dock_item;
301 child = anjuta_dock_pane_get_widget (pane);
303 if (child)
305 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
306 gdl_dock_item_hide_item (dock_item);
311 * anjuta_dock_set_command_bar:
312 * @self: An AnjutaDock
313 * @command_bar: An #AnjutaCommandBar to associate with this dock
315 * Associates an #AnjutaCommandBar with this dock. Command bars can be used to
316 * provide different sets of commands based on the currently visible pane.
318 void
319 anjuta_dock_set_command_bar (AnjutaDock *self, AnjutaCommandBar *command_bar)
321 if (self->priv->command_bar)
322 g_object_unref (self->priv->command_bar);
324 self->priv->command_bar = g_object_ref (command_bar);