1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) James Liggett 2009 <jrliggett@cox.net>
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"
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
33 * Optionally, you can also associate an #AnjutaCommandBar with an AnjutaDock to
34 * provide contextually appropriate sets of commands depending on the currently
38 struct _AnjutaDockPriv
41 GHashTable
*dock_items
;
42 GtkWidget
*command_bar
;
44 AnjutaDockPane
* command_pane
;
47 G_DEFINE_TYPE (AnjutaDock
, anjuta_dock
, GDL_TYPE_DOCK
);
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;
60 anjuta_dock_finalize (GObject
*object
)
64 self
= ANJUTA_DOCK (object
);
66 g_hash_table_destroy (self
->priv
->panes
);
67 g_hash_table_destroy (self
->priv
->dock_items
);
70 G_OBJECT_CLASS (anjuta_dock_parent_class
)->finalize (object
);
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
),
80 anjuta_command_bar_show_action_group (command_bar
, pane_name
);
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
),
93 anjuta_dock_dispose (GObject
*object
)
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
);
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
;
129 * Creates a new AnjutaDock.
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
144 * @stock_icon: Stock icon to display in this pane's grip
145 * @placement: A #GdlDockPlacement value indicating where the pane should be
147 * @entries: (allow-none) (array length=num_entries): #AnjutaCommandBar entries
148 * for this pane. Can be %NULL
149 * @num_entries: The number of entries pointed to by entries, or 0.
150 * @user_data: User data to pass to the entry callback
152 * Adds a pane, with optional #AnjutaCommandBar entries, to an AnjutaDock. This
153 * method adds a pane with no grip that cannot be closed, floating or iconified.
155 * Returns: %TRUE if the pane was added, or %FALSE if a pane with the same name
156 * already exists in the dock
159 anjuta_dock_add_pane (AnjutaDock
*self
, const gchar
*pane_name
,
160 const gchar
*pane_label
, const gchar
*stock_icon
,
161 AnjutaDockPane
*pane
, GdlDockPlacement placement
,
162 AnjutaCommandBarEntry
*entries
, int num_entries
,
168 behavior
|= GDL_DOCK_ITEM_BEH_NO_GRIP
;
169 behavior
|= GDL_DOCK_ITEM_BEH_CANT_CLOSE
;
170 behavior
|= GDL_DOCK_ITEM_BEH_CANT_ICONIFY
;
171 behavior
|= GDL_DOCK_ITEM_BEH_NEVER_FLOATING
;
173 return anjuta_dock_add_pane_full (self
, pane_name
, pane_label
, stock_icon
,
174 pane
, placement
, entries
, num_entries
,
175 user_data
, behavior
);
179 * anjuta_dock_add_pane_full:
180 * @self: An AnjutaDock
181 * @pane_name: A unique name for this pane
182 * @pane_label: Label to display in this pane's grip
183 * @stock_icon: Stock icon to display in this pane's grip
184 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
186 * @placement: A #GdlDockPlacement value indicating where the pane should be
188 * @entries: (allow-none) (array length=num_entries): #AnjutaCommandBar entries
189 * for this pane. Can be %NULL
190 * @num_entries: The number of entries pointed to by entries, or 0.
191 * @user_data: User data to pass to the entry callback
192 * @behavior: Any combination of #GdlDockItemBehavior flags
194 * Does the same thing as anjuta_dock_add_pane, but allows GDL dock behavior
195 * flags to be specified.
197 * Returns: %TRUE if the pane was added, or %FALSE if a pane with the same name
198 * already exists in the dock
201 anjuta_dock_add_pane_full (AnjutaDock
*self
, const gchar
*pane_name
,
202 const gchar
*pane_label
, const gchar
*stock_icon
,
203 AnjutaDockPane
*pane
,
204 GdlDockPlacement placement
,
205 AnjutaCommandBarEntry
*entries
, int num_entries
,
207 GdlDockItemBehavior behavior
)
209 GtkWidget
*dock_item
;
212 dock_item
= gdl_dock_item_new (pane_name
, pane_label
, behavior
);
213 child
= anjuta_dock_pane_get_widget (pane
);
214 g_object_set_data (G_OBJECT (child
), "dock-item", dock_item
);
216 /* Make sure there isn't another dock with the same name */
217 if (!g_hash_table_lookup_extended (self
->priv
->panes
, pane_name
, NULL
,
220 /* Take ownership of the pane object */
221 g_hash_table_insert (self
->priv
->panes
, (gchar
*) pane_name
, pane
);
223 gtk_container_add (GTK_CONTAINER (dock_item
), child
);
224 gdl_dock_add_item (GDL_DOCK (self
), GDL_DOCK_ITEM (dock_item
), placement
);
226 g_object_set_data (G_OBJECT (dock_item
), "pane-name", (gchar
*) pane_name
);
228 /* Don't add anything to the action bar if there are no entries */
229 if (self
->priv
->command_bar
&& entries
)
231 anjuta_command_bar_add_action_group (ANJUTA_COMMAND_BAR (self
->priv
->command_bar
),
232 pane_name
, entries
, num_entries
,
235 g_signal_connect (G_OBJECT (dock_item
), "selected",
236 G_CALLBACK (on_pane_selected
),
237 self
->priv
->command_bar
);
239 g_hash_table_insert (self
->priv
->dock_items
, (gchar
*) pane_name
,
242 /* Show the new pane's commands in the command bar */
243 anjuta_command_bar_show_action_group (ANJUTA_COMMAND_BAR (self
->priv
->command_bar
),
254 * anjuta_dock_replace_command_pane:
255 * @self: An AnjutaDock
256 * @pane_name: A unique name for this pane
257 * @pane_label: Label to display in this pane's grip
258 * @pane: The #AnjutaDockPane to add to the dock. The dock takes ownership of
260 * @stock_icon: Stock icon to display in this pane's grip
261 * @placement: A #GdlDockPlacement value indicating where the pane should be
263 * @entries: (allow-none) (array length=num_entries): #AnjutaCommandBar entries
264 * for this pane. Can be %NULL
265 * @num_entries: The number of entries pointed to by entries, or 0.
266 * @user_data: User data to pass to the entry callback
268 * Adds a pane, with optional #AnjutaCommandBar entries, to an AnjutaDock. This
269 * method adds a pane with no grip that cannot be closed, floating or iconified.
270 * If there was an old command pane, that pane is removed in favour of the new pane.
273 anjuta_dock_replace_command_pane (AnjutaDock
*self
,
274 const gchar
*pane_name
,
275 const gchar
*pane_label
, const gchar
*stock_icon
,
276 AnjutaDockPane
*pane
, GdlDockPlacement placement
,
277 AnjutaCommandBarEntry
*entries
, int num_entries
,
280 if (anjuta_dock_add_pane (self
, pane_name
, pane_label
, stock_icon
,
281 pane
, placement
, entries
, num_entries
, user_data
))
283 if (self
->priv
->command_pane
)
285 anjuta_dock_remove_pane (self
, self
->priv
->command_pane
);
288 self
->priv
->command_pane
= pane
;
293 * anjuta_dock_remove_pane:
294 * @self An AnjutaDock
295 * @pane: Name of the pane to remove
297 * Removes a pane from a dock
300 anjuta_dock_remove_pane (AnjutaDock
*self
, AnjutaDockPane
*pane
)
303 GtkContainer
*dock_item
;
305 child
= anjuta_dock_pane_get_widget (pane
);
307 if (self
->priv
->command_pane
== pane
)
309 self
->priv
->command_pane
= NULL
;
314 /* Remove the child from its dock item and destroy it */
315 dock_item
= g_object_get_data (G_OBJECT (child
), "dock-item");
316 g_hash_table_remove (self
->priv
->panes
,
317 g_object_get_data (G_OBJECT (dock_item
),
319 gtk_container_remove (dock_item
, child
);
321 gdl_dock_item_unbind (GDL_DOCK_ITEM (dock_item
));
326 * anjuta_dock_show_pane:
327 * @self: An AnjutaDock
328 * @pane: Name of the pane to show
330 * Makes the given pane visible
333 anjuta_dock_show_pane (AnjutaDock
*self
, AnjutaDockPane
*pane
)
336 GdlDockItem
*dock_item
;
338 child
= anjuta_dock_pane_get_widget (pane
);
342 dock_item
= g_object_get_data (G_OBJECT (child
), "dock-item");
343 gdl_dock_item_show_item (dock_item
);
348 * anjuta_dock_hide_pane:
349 * @self: An AnjutaDock
350 * @pane: Name of the pane to hide
352 * Makes the given pane invisible
355 anjuta_dock_hide_pane (AnjutaDock
*self
, AnjutaDockPane
*pane
)
358 GdlDockItem
*dock_item
;
360 child
= anjuta_dock_pane_get_widget (pane
);
364 dock_item
= g_object_get_data (G_OBJECT (child
), "dock-item");
365 gdl_dock_item_hide_item (dock_item
);
370 * anjuta_dock_present_pane:
371 * @self: An AnjutaDock
372 * @pane: Pane to present
374 * Presents the pane to the user by making it the currently active pane in its
378 anjuta_dock_present_pane (AnjutaDock
*self
, AnjutaDockPane
*pane
)
381 GdlDockObject
*dock_item
;
383 child
= anjuta_dock_pane_get_widget (pane
);
387 dock_item
= g_object_get_data (G_OBJECT (child
), "dock-item");
388 gdl_dock_object_present (dock_item
, NULL
);
393 * anjuta_dock_set_command_bar:
394 * @self: An AnjutaDock
395 * @command_bar: An #AnjutaCommandBar to associate with this dock
397 * Associates an #AnjutaCommandBar with this dock. Command bars can be used to
398 * provide different sets of commands based on the currently visible pane.
401 anjuta_dock_set_command_bar (AnjutaDock
*self
, AnjutaCommandBar
*command_bar
)
403 if (self
->priv
->command_bar
)
404 g_object_unref (self
->priv
->command_bar
);
406 self
->priv
->command_bar
= g_object_ref (command_bar
);
410 * anjuta_dock_get_command_bar:
411 * @self: An AnjutaDock
413 * Returns: (transfer none) (allow-none): the #AnjutaCommandBar associated with
414 * this dock or %NULL.
417 anjuta_dock_get_command_bar (AnjutaDock
*self
)
419 return ANJUTA_COMMAND_BAR (self
->priv
->command_bar
);