libanjuta: Fix some warnings and made AnjutaPluginDescription a boxed type
[anjuta.git] / libanjuta / anjuta-dock.c
blobfabcfd42034eb241177da98c6dc197f37be634c9
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;
44 AnjutaDockPane* command_pane;
47 G_DEFINE_TYPE (AnjutaDock, anjuta_dock, GDL_TYPE_DOCK);
49 static void
50 anjuta_dock_init (AnjutaDock *self)
52 self->priv = g_new0 (AnjutaDockPriv, 1);
53 self->priv->panes = g_hash_table_new_full (g_str_hash, g_str_equal,
54 NULL, g_object_unref);
55 self->priv->dock_items = g_hash_table_new (g_str_hash, g_str_equal);
56 self->priv->command_pane = 0;
59 static void
60 anjuta_dock_finalize (GObject *object)
62 AnjutaDock *self;
64 self = ANJUTA_DOCK (object);
66 g_hash_table_destroy (self->priv->panes);
67 g_hash_table_destroy (self->priv->dock_items);
68 g_free (self->priv);
70 G_OBJECT_CLASS (anjuta_dock_parent_class)->finalize (object);
73 static void
74 on_pane_selected (GdlDockItem *item, AnjutaCommandBar *command_bar)
76 const gchar *pane_name;
78 pane_name = (const gchar *) g_object_get_data (G_OBJECT (item),
79 "pane-name");
80 anjuta_command_bar_show_action_group (command_bar, pane_name);
84 static void
85 disconnect_select_signals (gpointer key, GdlDockItem *value,
86 AnjutaCommandBar *command_bar)
88 g_signal_handlers_disconnect_by_func (value, G_CALLBACK (on_pane_selected),
89 command_bar);
92 static void
93 anjuta_dock_dispose (GObject *object)
95 AnjutaDock *self;
97 self = ANJUTA_DOCK (object);
99 if (self->priv->command_bar)
101 /* Disconnect pane selection signals before dropping the command bar
102 * reference. It is possible that we may be holding the last reference
103 * of the bar, creating the possibility that the parent implementation
104 * of dispose might do something that would call the signal handler that
105 * would reference the already destroyed command bar. */
106 g_hash_table_foreach (self->priv->dock_items,
107 (GHFunc) disconnect_select_signals,
108 self->priv->command_bar);
110 g_object_unref (self->priv->command_bar);
111 self->priv->command_bar = NULL;
114 G_OBJECT_CLASS (anjuta_dock_parent_class)->dispose (object);
117 static void
118 anjuta_dock_class_init (AnjutaDockClass *klass)
120 GObjectClass* object_class = G_OBJECT_CLASS (klass);
122 object_class->finalize = anjuta_dock_finalize;
123 object_class->dispose = anjuta_dock_dispose;
127 * anjuta_dock_new:
129 * Creates a new AnjutaDock.
131 GtkWidget *
132 anjuta_dock_new (void)
134 return g_object_new (ANJUTA_TYPE_DOCK, NULL);
138 * anjuta_dock_add_pane:
139 * @self: An AnjutaDock
140 * @pane_name: A unique name for this pane
141 * @pane_label: Label to display in this pane's grip
142 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
143 * the pane object.
144 * @stock_icon: Stock icon to display in this pane's grip
145 * @placement: A #GdlDockPlacement value indicating where the pane should be
146 * placed
147 * @entries: #AnjutaCommandBar entries for this pane. Can be %NULL
148 * @num_entries: The number of entries pointed to by entries, or 0.
149 * @user_data: User data to pass to the entry callback
151 * Adds a pane, with optional #AnjutaCommandBar entries, to an AnjutaDock. This
152 * method adds a pane with no grip that cannot be closed, floating or iconified.
154 * Returns: %TRUE if the pane was added, or %FALSE if a pane with the same name
155 * already exists in the dock
157 gboolean
158 anjuta_dock_add_pane (AnjutaDock *self, const gchar *pane_name,
159 const gchar *pane_label, const gchar *stock_icon,
160 AnjutaDockPane *pane, GdlDockPlacement placement,
161 AnjutaCommandBarEntry *entries, int num_entries,
162 gpointer user_data)
164 int behavior;
166 behavior = 0;
167 behavior |= GDL_DOCK_ITEM_BEH_NO_GRIP;
168 behavior |= GDL_DOCK_ITEM_BEH_CANT_CLOSE;
169 behavior |= GDL_DOCK_ITEM_BEH_CANT_ICONIFY;
170 behavior |= GDL_DOCK_ITEM_BEH_NEVER_FLOATING;
172 return anjuta_dock_add_pane_full (self, pane_name, pane_label, stock_icon,
173 pane, placement, entries, num_entries,
174 user_data, behavior);
178 * anjuta_dock_add_pane_full:
179 * @self: An AnjutaDock
180 * @pane_name: A unique name for this pane
181 * @pane_label: Label to display in this pane's grip
182 * @stock_icon: Stock icon to display in this pane's grip
183 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
184 * the pane object.
185 * @placement: A #GdlDockPlacement value indicating where the pane should be
186 * placed
187 * @entries: #AnjutaCommandBar entries for this pane. Can be %NULL
188 * @num_entries: The number of entries pointed to by entries, or 0.
189 * @user_data: User data to pass to the entry callback
190 * @behavior: Any combination of #GdlDockItemBehavior flags
192 * Does the same thing as anjuta_dock_add_pane, but allows GDL dock behavior
193 * flags to be specified.
195 * Returns: %TRUE if the pane was added, or %FALSE if a pane with the same name
196 * already exists in the dock
198 gboolean
199 anjuta_dock_add_pane_full (AnjutaDock *self, const gchar *pane_name,
200 const gchar *pane_label, const gchar *stock_icon,
201 AnjutaDockPane *pane,
202 GdlDockPlacement placement,
203 AnjutaCommandBarEntry *entries, int num_entries,
204 gpointer user_data,
205 GdlDockItemBehavior behavior)
207 GtkWidget *dock_item;
208 GtkWidget *child;
210 dock_item = gdl_dock_item_new (pane_name, pane_label, behavior);
211 child = anjuta_dock_pane_get_widget (pane);
212 g_object_set_data (G_OBJECT (child), "dock-item", dock_item);
214 /* Make sure there isn't another dock with the same name */
215 if (!g_hash_table_lookup_extended (self->priv->panes, pane_name, NULL,
216 NULL))
218 /* Take ownership of the pane object */
219 g_hash_table_insert (self->priv->panes, (gchar *) pane_name, pane);
221 gtk_container_add (GTK_CONTAINER (dock_item), child);
222 gdl_dock_add_item (GDL_DOCK (self), GDL_DOCK_ITEM (dock_item), placement);
224 g_object_set_data (G_OBJECT (dock_item), "pane-name", (gchar *) pane_name);
226 /* Don't add anything to the action bar if there are no entries */
227 if (self->priv->command_bar && entries)
229 anjuta_command_bar_add_action_group (ANJUTA_COMMAND_BAR (self->priv->command_bar),
230 pane_name, entries, num_entries,
231 user_data);
233 g_signal_connect (G_OBJECT (dock_item), "selected",
234 G_CALLBACK (on_pane_selected),
235 self->priv->command_bar);
237 g_hash_table_insert (self->priv->dock_items, (gchar *) pane_name,
238 dock_item);
240 /* Show the new pane's commands in the command bar */
241 anjuta_command_bar_show_action_group (ANJUTA_COMMAND_BAR (self->priv->command_bar),
242 pane_name);
245 return TRUE;
248 return FALSE;
252 * anjuta_dock_replace_command_pane:
253 * @self: An AnjutaDock
254 * @pane_name: A unique name for this pane
255 * @pane_label: Label to display in this pane's grip
256 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
257 * the pane object.
258 * @stock_icon: Stock icon to display in this pane's grip
259 * @placement: A #GdlDockPlacement value indicating where the pane should be
260 * placed
261 * @entries: #AnjutaCommandBar entries for this pane. Can be %NULL
262 * @num_entries: The number of entries pointed to by entries, or 0.
263 * @user_data: User data to pass to the entry callback
265 * Adds a pane, with optional #AnjutaCommandBar entries, to an AnjutaDock. This
266 * method adds a pane with no grip that cannot be closed, floating or iconified.
267 * If there was an old command pane, that pane is removed in favour of the new pane.
269 void
270 anjuta_dock_replace_command_pane (AnjutaDock *self,
271 const gchar *pane_name,
272 const gchar *pane_label, const gchar *stock_icon,
273 AnjutaDockPane *pane, GdlDockPlacement placement,
274 AnjutaCommandBarEntry *entries, int num_entries,
275 gpointer user_data)
277 if (anjuta_dock_add_pane (self, pane_name, pane_label, stock_icon,
278 pane, placement, entries, num_entries, user_data))
280 if (self->priv->command_pane)
282 anjuta_dock_remove_pane (self, self->priv->command_pane);
285 self->priv->command_pane = pane;
290 * anjuta_dock_remove_pane:
291 * @self An AnjutaDock
292 * @pane: Name of the pane to remove
294 * Removes a pane from a dock
296 void
297 anjuta_dock_remove_pane (AnjutaDock *self, AnjutaDockPane *pane)
299 GtkWidget *child;
300 GtkContainer *dock_item;
302 child = anjuta_dock_pane_get_widget (pane);
304 if (self->priv->command_pane == pane)
306 self->priv->command_pane = NULL;
309 if (child)
311 /* Remove the child from its dock item and destroy it */
312 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
313 g_hash_table_remove (self->priv->panes,
314 g_object_get_data (G_OBJECT (dock_item),
315 "pane-name"));
316 gtk_container_remove (dock_item, child);
318 gdl_dock_item_unbind (GDL_DOCK_ITEM (dock_item));
323 * anjuta_dock_show_pane:
324 * @self: An AnjutaDock
325 * @pane_name: Name of the pane to show
327 * Makes the given pane visible
329 void
330 anjuta_dock_show_pane (AnjutaDock *self, AnjutaDockPane *pane)
332 GtkWidget *child;
333 GdlDockItem *dock_item;
335 child = anjuta_dock_pane_get_widget (pane);
337 if (child)
339 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
340 gdl_dock_item_show_item (dock_item);
345 * anjuta_dock_hide_pane:
346 * @self: An AnjutaDock
347 * @pane: Name of the pane to hide
349 * Makes the given pane invisible
351 void
352 anjuta_dock_hide_pane (AnjutaDock *self, AnjutaDockPane *pane)
354 GtkWidget *child;
355 GdlDockItem *dock_item;
357 child = anjuta_dock_pane_get_widget (pane);
359 if (child)
361 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
362 gdl_dock_item_hide_item (dock_item);
367 * anjuta_dock_show_pane:
368 * @self: An AnjutaDock
369 * @pane: Pane to present
371 * Presents the pane to the user by making it the currently active pane in its
372 * switcher
374 void
375 anjuta_dock_present_pane (AnjutaDock *self, AnjutaDockPane *pane)
377 GtkWidget *child;
378 GdlDockObject *dock_item;
380 child = anjuta_dock_pane_get_widget (pane);
382 if (child)
384 dock_item = g_object_get_data (G_OBJECT (child), "dock-item");
385 gdl_dock_object_present (dock_item, NULL);
390 * anjuta_dock_set_command_bar:
391 * @self: An AnjutaDock
392 * @command_bar: An #AnjutaCommandBar to associate with this dock
394 * Associates an #AnjutaCommandBar with this dock. Command bars can be used to
395 * provide different sets of commands based on the currently visible pane.
397 void
398 anjuta_dock_set_command_bar (AnjutaDock *self, AnjutaCommandBar *command_bar)
400 if (self->priv->command_bar)
401 g_object_unref (self->priv->command_bar);
403 self->priv->command_bar = g_object_ref (command_bar);
407 * anjuta_dock_get_command_bar:
408 * @self: An AnjutaDock
410 * Returns: the #AnjutaCommandBar associated with this dock or %NULL.
412 AnjutaCommandBar *
413 anjuta_dock_get_command_bar (AnjutaDock *self)
415 return ANJUTA_COMMAND_BAR (self->priv->command_bar);