7
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
using System.Collections;
34
using System.Xml.Serialization;
35
using System.Collections.Generic;
37
namespace MonoDevelop.Components.DockToolbars
39
public class DockToolbarFrame: EventBox
41
DockToolbarPanel[] panels;
42
DockToolbarPanel targetPanel;
46
int xDragDif, yDragDif;
47
List<DockToolbar> bars = new List<DockToolbar> ();
49
Dictionary<string,DockToolbarStatus[]> layouts = new Dictionary<string,DockToolbarStatus[]> ();
50
string currentLayout = "";
52
Cursor handCursor = new Cursor (CursorType.Fleur);
54
public DockToolbarFrame ()
59
DockToolbarPanel topPanel = new DockToolbarPanel (this, Placement.Top);
60
DockToolbarPanel bottomPanel = new DockToolbarPanel (this, Placement.Bottom);
61
DockToolbarPanel leftPanel = new DockToolbarPanel (this, Placement.Left);
62
DockToolbarPanel rightPanel = new DockToolbarPanel (this, Placement.Right);
64
panels = new DockToolbarPanel [4];
65
panels [(int)Placement.Top] = topPanel;
66
panels [(int)Placement.Bottom] = bottomPanel;
67
panels [(int)Placement.Left] = leftPanel;
68
panels [(int)Placement.Right] = rightPanel;
70
vbox.PackStart (topPanel, false, false, 0);
72
HBox hbox = new HBox ();
73
contentBox = new VBox ();
75
hbox.PackStart (leftPanel, false, false, 0);
76
hbox.PackStart (contentBox, true, true, 0);
77
hbox.PackStart (rightPanel, false, false, 0);
79
vbox.PackStart (hbox, true, true, 0);
80
vbox.PackStart (bottomPanel, false, false, 0);
82
this.Events = EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.PointerMotionMask;
86
public void AddContent (Widget w)
88
contentBox.PackStart (w, true, true, 0);
91
public void RemoveContent (Widget w)
93
contentBox.Remove (w);
96
public string CurrentLayout {
97
get { return currentLayout; }
99
if (value != currentLayout) {
100
SaveCurrentLayout ();
101
RestoreLayout (value);
106
public DockToolbarFrameStatus GetStatus ()
108
SaveCurrentLayout ();
109
DockToolbarFrameStatus col = new DockToolbarFrameStatus ();
110
col.Version = DockToolbarFrameStatus.CurrentVersion;
112
foreach (var layout in layouts) {
113
col.Status.Add (new DockToolbarFrameLayout () {
121
public void SetStatus (DockToolbarFrameStatus status)
124
if (status != null && status.Status != null) {
125
foreach (DockToolbarFrameLayout c in status.Status) {
126
if (status.Version < 2) {
127
// Convert from old to new toolbar id
128
foreach (DockToolbarStatus ts in c.Bars)
129
ts.BarId = ConvertToolbarId (ts.BarId);
131
layouts [c.Id] = c.Bars;
137
public void SaveStatus (XmlWriter writer)
139
XmlSerializer ser = new XmlSerializer (typeof(DockToolbarFrameStatus));
140
ser.Serialize (writer, GetStatus ());
143
public void LoadStatus (XmlReader reader)
146
XmlSerializer ser = new XmlSerializer (typeof(DockToolbarFrameStatus));
147
DockToolbarFrameStatus col = (DockToolbarFrameStatus) ser.Deserialize (reader);
151
string ConvertToolbarId (string id)
153
// Old MD versions include the display name of the toolbar in the id.
154
// New MD versions use a different id composition.
155
// This method translates the id from the old to the new format (when possible)
157
int i = id.LastIndexOf ('/');
161
string baseId = id.Substring (0, i + 1);
163
foreach (DockToolbar t in bars) {
166
if (baseId + t.Title == id)
172
public IDockToolbar AddBar (DockToolbar bar)
174
return AddBar (bar, Placement.Top, true);
177
public IDockToolbar AddBar (DockToolbar bar, Placement defaultPanel, bool defaultVisible)
179
bar.SetParentFrame (this);
182
DockToolbarPosition pos = new DockedPosition (defaultPanel);
183
DockToolbarStatus s = new DockToolbarStatus (bar.Id, defaultVisible, pos);
184
bar.DefaultStatus = s;
190
public void RemoveToolbar(DockToolbar bar)
192
IDockToolbar db = (IDockToolbar)bar;
198
public void ClearToolbars ()
200
foreach (DockToolbar bar in bars) {
201
IDockToolbar db = (IDockToolbar) bar;
208
public IDockToolbar GetBar (string id)
210
foreach (DockToolbar bar in bars)
211
if (bar.Id == id) return bar;
215
public ICollection<DockToolbar> Toolbars {
219
public void ResetToolbarPositions ()
221
foreach (DockToolbarPanel panel in panels)
222
panel.ResetBarPositions (false);
225
void SaveCurrentLayout ()
227
DockToolbarStatus[] status = SaveStatus ();
228
layouts [currentLayout] = status;
231
void RestoreLayout (string layout)
233
DockToolbarStatus[] status;
234
layouts.TryGetValue (layout, out status);
235
RestoreStatus (status);
236
currentLayout = layout;
239
internal void DeleteLayout (string layout)
241
if (layouts.ContainsKey (layout))
242
layouts.Remove (layout);
245
DockToolbarStatus[] SaveStatus ()
247
DockToolbarStatus[] status = new DockToolbarStatus [bars.Count];
248
for (int n=0; n<bars.Count; n++) {
249
DockToolbar bar = (DockToolbar) bars [n];
250
status [n] = bar.Status;
255
void RestoreStatus (DockToolbarStatus[] status)
257
foreach (IDockToolbar b in bars)
260
if (status == null) {
261
foreach (DockToolbar bar in bars)
262
bar.Status = bar.DefaultStatus;
264
foreach (DockToolbarStatus s in status) {
265
DockToolbar bar = (DockToolbar) GetBar (s.BarId);
272
internal int DockMargin {
276
internal void DockToolbar (DockToolbar bar, Placement placement, int offset, int row)
278
DockToolbarPanel p = GetPanel (placement);
280
p.AddDockToolbar (bar, offset, row);
282
p.AddDockToolbar (bar);
285
internal void FloatBar (DockToolbar bar, Orientation orientation, int x, int y)
287
FloatingDock fdock = new FloatingDock (this);
291
bar.Orientation = orientation;
294
internal Gtk.Window TopWindow {
297
while (w != null && !(w is Gtk.Window))
299
return (Gtk.Window) w;
303
DockToolbarPanel GetPanel (Placement o)
305
return panels [(int)o];
308
protected override bool OnMotionNotifyEvent (EventMotion e)
310
if (dragBar != null) {
312
this.GdkWindow.GetOrigin (out sx, out sy);
313
int rx = (int)e.XRoot - sx;
314
int ry = (int)e.YRoot - sy;
316
if (dragBar.Floating) {
317
bool foundPanel = false;
318
dragBar.FloatingDock.Move ((int)e.XRoot + xDragDif, (int)e.YRoot + yDragDif);
319
Rectangle barRect = new Rectangle (rx + xDragDif, ry + yDragDif, dragBar.Allocation.Width, dragBar.DefaultHeight);
320
foreach (DockToolbarPanel p in panels) {
321
if (p.Allocation.IntersectsWith (barRect)) {
322
if (targetPanel != null && targetPanel != p)
323
targetPanel.EndDragBar (dragBar);
324
p.Reposition (dragBar, rx, ry, xDragDif, yDragDif);
330
if (!foundPanel && targetPanel != null)
331
targetPanel.EndDragBar (dragBar);
333
DockToolbarPanel panel = (DockToolbarPanel) dragBar.Parent;
334
panel.Reposition (dragBar, rx, ry, xDragDif, yDragDif);
337
return base.OnMotionNotifyEvent (e);
340
internal void StartDragBar (DockToolbar bar, int x, int y, uint time)
345
Pointer.Grab (this.GdkWindow, false, EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.PointerMotionMask, null, handCursor, time);
347
DockToolbarPanel panel = (DockToolbarPanel) dragBar.Parent;
348
panel.StartDragBar (bar);
352
internal void EndDragBar (DockToolbar bar, uint time)
354
Pointer.Ungrab (time);
355
if (targetPanel != null) {
356
targetPanel.DropDragBar (bar);
357
targetPanel.EndDragBar (bar);
362
protected override bool OnButtonReleaseEvent (EventButton e)
365
EndDragBar (dragBar, e.Time);
367
return base.OnButtonReleaseEvent (e);
370
protected override bool OnButtonPressEvent (Gdk.EventButton e)
374
this.GdkWindow.GetOrigin (out sx, out sy);
375
int rx = (int)e.XRoot - sx;
376
int ry = (int)e.YRoot - sy;
378
foreach (DockToolbarPanel p in panels) {
379
if (p.Allocation.Contains (rx, ry))
380
OnPanelClick (e, p.Placement);
383
return base.OnButtonPressEvent (e);
386
protected virtual void OnPanelClick (Gdk.EventButton e, Placement placement)
390
protected override void OnDestroyed ()
392
if (handCursor != null) {
393
handCursor.Dispose ();