Logo Search packages:      
Sourcecode: monodevelop version File versions  Download package

DockToolbarPanel.cs

//
// DockToolbarPanel.cs
//
// Author:
//   Lluis Sanchez Gual
//
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using Gtk;
using Gdk;
using System.Collections;

namespace MonoDevelop.Components.DockToolbars
{
      internal class DockToolbarPanel: FixedPanel
      {
            DockToolbarFrame parentFrame;
            ArrayList bars = new ArrayList ();
            Orientation orientation;
            
            ArrowWindow placeholderArrow1;
            ArrowWindow placeholderArrow2;
            PlaceholderWindow placeholder;
            bool currentPlaceholderHorz;
            
            int dropOffset;
            int dropRow = -1;
            bool dropNewRow;
            bool enableAnimations = true;
            
            public DockToolbarPanel (DockToolbarFrame parentFrame, Placement placement)
            {
      //          ResizeMode = ResizeMode.Immediate;
                  Placement = placement;
                  switch (placement) {
                        case Placement.Top:
                              this.orientation = Orientation.Horizontal;
                              break;
                        case Placement.Bottom:
                              this.orientation = Orientation.Horizontal;
                              break;
                        case Placement.Left:
                              this.orientation = Orientation.Vertical;
                              break;
                        case Placement.Right:
                              this.orientation = Orientation.Vertical;
                              break;
                  }
                  
                  this.parentFrame = parentFrame;
            }
            
            public Orientation Orientation {
                  get { return orientation; }
            }
            
            public void AddDockToolbar (DockToolbar bar)
            {
                  bool ea = EnableAnimation (false);

                  Put (bar, 0, 0);
                  bar.Orientation = orientation;
                  
                  if (bars.Count > 0 && IsRealized) {
                        DockToolbar last = (DockToolbar) bars [bars.Count - 1];
                        int width = bar.DefaultSize;
                        int lastx = last.DockOffset + last.DefaultSize;
                        
                        if (lastx + width <= PanelWidth)
                              MoveBar (bar, lastx, last.DockRow, false);
                        else
                              MoveBar (bar, 0, last.DockRow + 1, false);
                        bar.AnchorOffset = bar.DockOffset;
                        InternalAdd (bar);
                        SortBars ();
                  } else {
                        MoveBar (bar, 0, 0);
                        bar.AnchorOffset = bar.DockOffset;
                        InternalAdd (bar);
                  }

                  EnableAnimation (ea);
            }
            
            public void AddDockToolbar (DockToolbar bar, int offset, int row)
            {
                  bool ea = EnableAnimation (false);
                  InternalAdd (bar);
                  Put (bar, 0, 0);
                  bar.Orientation = orientation;
                  MoveBar (bar, offset, row, false);
                  bar.AnchorOffset = offset;
                  SortBars ();
                  PackBars ();
                  EnableAnimation (ea);
            }
            
            void InternalAdd (DockToolbar bar)
            {
                  bars.Add (bar);
                  bar.DefaultSizeChanged += new EventHandler (OnBarSizeChanged);
            }
            
            public void RemoveBar (DockToolbar bar)
            {
                  if (IsSingleBarRow (bar))
                        RemoveRow (bar.DockRow);
            
                  Remove (bar);
                  bars.Remove (bar);
                  bar.DefaultSizeChanged -= new EventHandler (OnBarSizeChanged);
                  
                  UpdateRowHeight (bar.DockRow);
                  PackBars ();
            }
            
            protected override void OnRealized ()
            {
                  base.OnRealized ();
                  bool ea = EnableAnimation (false);
                  ResetBarPositions ();
                  EnableAnimation (ea);
            }

            public void ResetBarPositions ()
            {
                  int x=0, row=0;
                  int width = PanelWidth;
                  
                  foreach (DockToolbar b in bars) {
                        int barw = GetChildWidth (b);
                        if (x + barw < width)
                              MoveBar (b, x, row);
                        else {
                              row++;
                              x = 0;
                              MoveBar (b, 0, row);
                        }
                        x += barw;
                  }
                  SortBars ();

            }
            
            void SetPlaceholder (DockToolbar bar, int offset, int row)
            {
                  if (dropRow != row && dropRow != -1)
                        RestoreShiftedBars (dropRow);

                  ShowPlaceholder (bar, false, offset, GetRowTop (row), GetChildWidth (bar), GetRowSize (row));

                  dropOffset = offset;
                  dropRow = row;
                  dropNewRow = false;
            }
            
            void SetNewRowPlaceholder (DockToolbar bar, int offset, int toprow)
            {
                  if (dropRow != -1)
                        RestoreShiftedBars (dropRow);
                  
                  int y = GetRowTop (toprow) - parentFrame.DockMargin;
                  int h = parentFrame.DockMargin * 2;
                  ShowPlaceholder (bar, true, offset, y, GetChildWidth (bar), h);
                  
                  dropOffset = offset;
                  dropRow = toprow;
                  dropNewRow = true;
            }
            
            void ShowPlaceholder (DockToolbar bar, bool horz, int x, int y, int w, int h)
            {
                  if (orientation != Orientation.Horizontal)
                        horz = !horz;
                  
                  PanelToWindow (x, y, w, h, out x, out y, out w, out h);
                  
                  bool created = false;
                  
                  if (placeholder == null || horz != currentPlaceholderHorz) {
                        HidePlaceholder ();
                        placeholder = new PlaceholderWindow (parentFrame);
                        placeholderArrow1 = new ArrowWindow (parentFrame, horz ? ArrowWindow.Direction.Right : ArrowWindow.Direction.Down);
                        placeholderArrow2 = new ArrowWindow (parentFrame, horz ? ArrowWindow.Direction.Left : ArrowWindow.Direction.Up);
                        currentPlaceholderHorz = horz;
                        created = true;
                  }
                  
                  int sx, sy;
                  this.GdkWindow.GetOrigin (out sx, out sy);
                  sx += x;
                  sy += y;
                  
                  int mg = -4;
                  placeholder.Move (sx - mg, sy - mg);
                  placeholder.Resize (w + mg*2, h + mg * 2);
                  
                  if (horz) {
                        placeholderArrow1.Move (sx - placeholderArrow1.Width, sy + (h/2) - placeholderArrow1.Height/2);
                        placeholderArrow2.Move (sx + w, sy + (h/2) - placeholderArrow1.Height/2);
                  } else {
                        int px = sx + w/2 - placeholderArrow1.Width/2;
                        if (px < 0) px = 0;
                        placeholderArrow1.Move (px, sy - placeholderArrow1.Height);
                        placeholderArrow2.Move (px, sy + h);
                  }
                  
                  if (created) {
                        placeholder.Show ();
                        placeholder.Present ();
                        if (bar.FloatingDock != null)
                              bar.FloatingDock.Present ();
                        placeholderArrow1.Present ();
                        placeholderArrow2.Present ();
                  }
            }
            
            void HidePlaceholder ()
            {
                  if (placeholder == null) return;
                  placeholder.Destroy ();
                  placeholder = null;
                  placeholderArrow1.Destroy ();
                  placeholderArrow1 = null;
                  placeholderArrow2.Destroy ();
                  placeholderArrow2 = null;

                  if (dropRow != -1 && !dropNewRow) {
                        RestoreShiftedBars (dropRow);
                        dropRow = -1;
                  }
            }
            
            bool IsPlaceHolderVisible {
                  get { return placeholder != null; }
            }
            
            public void StartDragBar (DockToolbar bar)
            {
            }
            
            public void DropDragBar (DockToolbar bar)
            {
                  if (!IsPlaceHolderVisible) return;
                  
                  foreach (DockToolbar b in bars) {
                        if (b.DockRow == dropRow && b.DockShiftOffset != -1) {
                              b.DockShiftOffset = -1;
                              b.AnchorOffset = b.DockRow;
                        }
                  }
                  
                  if (dropRow != -1) {
                        if (dropNewRow)
                              InsertRow (bar, dropOffset, dropRow);
                        else {
                              MoveBar (bar, dropOffset, dropRow);
                              UpdateRowHeight (dropRow);
                        }
                        SortBars ();
                        dropRow = -1;
                  }
            }
            
            public void EndDragBar (DockToolbar bar)
            {
                  if (IsPlaceHolderVisible) {
                        HidePlaceholder ();
                  }
            }
            
            void RestoreShiftedBars (int row)
            {
                  foreach (DockToolbar b in bars) {
                        if (b.DockRow == row && b.DockShiftOffset != -1) {
                              MoveBar (b, b.DockShiftOffset, b.DockRow, false);
                              b.DockShiftOffset = -1;
                        }
                  }
            }
            
            public void Reposition (DockToolbar bar, int xcursor, int ycursor, int difx, int dify)
            {
                  if (!bar.CanDockTo (this))
                        return;

                  bar.Orientation = orientation;
                  
                  int x, y;
                  WindowToPanel (xcursor + difx, ycursor + dify, bar.Allocation.Width, bar.Allocation.Height, out x, out y);
                  WindowToPanel (xcursor, ycursor, 0, 0, out xcursor, out ycursor);
                  
                  RepositionInternal (bar, x, y, xcursor, ycursor);
            }
            
            void RepositionInternal (DockToolbar bar, int x, int y, int xcursor, int ycursor)
            {
                  int width = GetChildWidth (bar);
                  
                  ycursor = y + bar.DefaultHeight / 2;
                  
                  if (bars.Count == 0 && bar.Floating) {
                        SetNewRowPlaceholder (bar, x, 0);
                        return;
                  }
                  
                  int dx = (x + width) - PanelWidth;
                  if (dx > parentFrame.DockMargin && !bar.Floating) {
                        HidePlaceholder ();
                        FloatBar (bar, x, y);
                        return;
                  }
                  else if (dx > 0)
                        x -= dx;
                  else if (x < -parentFrame.DockMargin && !bar.Floating) {
                        HidePlaceholder ();
                        FloatBar (bar, x, y);
                        return;
                  }
                  else if (x < 0)
                        x = 0;

                  int nx = x;
                  int row = -1;
                  
                  // Get the old bar y position
                   
                  int panelBottom = GetPanelBottom ();
                        
                  if (ycursor < - parentFrame.DockMargin || ycursor > panelBottom + parentFrame.DockMargin) {
                        HidePlaceholder ();
                        FloatBar (bar, x, y);
                        return;
                  }
                  
                  int rtop = 0;
                  int prevtop = 0;
                  row = 0;
                  while (ycursor >= rtop) {
                        prevtop = rtop;
                        row++;
                        if (rtop >= panelBottom) break;
                        rtop += GetRowSize (row - 1);
                  }
                  
                  row--;
                  int ry = ycursor - prevtop;
                  
                  if (ry <= parentFrame.DockMargin && ry >= 0) {
                        SetNewRowPlaceholder (bar, x, row);
                        FloatBar (bar, x, y);
                        return;
                  } else if (ry >= (GetRowSize(row) - parentFrame.DockMargin) || (ry < 0 && -ry < parentFrame.DockMargin)) {
                        SetNewRowPlaceholder (bar, x, row + 1);
                        FloatBar (bar, x, y);
                        return;
                  }
                  
                  // Can't create a new row. Try to fit the bar in the current row
                  // Find the first bar in the row:
                  
                  int ns = -1;
                  for (int n=0; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar)bars[n];
                        
                        // Ignore the bar being moved
                        if (b == bar) continue;
                        
                        if (b.DockRow == row) {
                              ns = n;
                              break;
                        }
                  }
                  
                  if (ns == -1) {
                        // There are no other bars, no problem then
                        if (bar.Floating) {
                              SetPlaceholder (bar, nx, row);
                              return;
                        }

                        if ((nx == bar.DockOffset && row == bar.DockRow) || (row != bar.DockRow)) {
                              SetPlaceholder (bar, nx, row);
                              FloatBar (bar, x, y);
                              return;
                        }
                        
                        HidePlaceholder ();
                        MoveBar (bar, nx, row);
                        return;
                  }
                  
                  // Compute the available space, and find the bars at the
                  // left and the right of the bar being moved
                  
                  int gapsTotal = 0;
                  int lastx = 0;
                  int leftIndex=-1, rightIndex = -1;
                  int gapsLeft = 0, gapsRight = 0;
                  
                  for (int n=ns; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar)bars[n];
                        
                        // Ignore the bar being moved
                        if (b == bar) continue;

                        if (b.DockRow != row) break;
                        int bx = b.DockOffset;
                        
                        if (bx > x && (rightIndex == -1))
                              rightIndex = n;
                        else if (bx <= x)
                              leftIndex = n;
                        
                        if (bx < x)
                              gapsLeft += bx - lastx;
                        else {
                              if (lastx < x) {
                                    gapsLeft += x - lastx;
                                    gapsRight += bx - x;
                              } else
                                    gapsRight += bx - lastx;
                        }
                        
                        gapsTotal += bx - lastx;
                        lastx = GetChildRightOffset (b); 
                  }

                  if (lastx < x) {
                        gapsLeft += x - lastx;
                        gapsRight += PanelWidth - x;
                  } else {
                        gapsRight += PanelWidth - lastx;
                  }
                  
                  gapsTotal += PanelWidth - lastx;
                  
                  // Is there room for the bar? 
                  if (gapsTotal < width) {
                        HidePlaceholder ();
                        FloatBar (bar, x, y);
                        return;
                  }
                  
                  // Shift the bars at the left and the right
                  
                  int oversizeLeft = 0;
                  int oversizeRight = 0;
                  
                  if (leftIndex != -1) {
                        int r = GetChildRightOffset ((DockToolbar) bars [leftIndex]);
                        oversizeLeft = r - nx;
                  }
                  
                  if (rightIndex != -1) {
                        int r = ((DockToolbar) bars [rightIndex]).DockOffset;
                        oversizeRight = (nx + width) - r;
                  }
                  
                  if (oversizeLeft > gapsLeft)
                        oversizeRight += (oversizeLeft - gapsLeft);
                  else if (oversizeRight > gapsRight)
                        oversizeLeft += (oversizeRight - gapsRight);
                  
                  if (leftIndex != -1 && oversizeLeft > 0) {
                        ShiftBar (leftIndex, -oversizeLeft);
                        nx = GetChildRightOffset ((DockToolbar) bars [leftIndex]);
                  }
                  
                  if (rightIndex != -1 && oversizeRight > 0) {
                        ShiftBar (rightIndex, oversizeRight);
                        nx = ((DockToolbar) bars [rightIndex]).DockOffset - width;
                  }
                  
                  
                  if (bar.Floating) {
                        SetPlaceholder (bar, nx, row);
                        return;
                  }

                  if ((nx == bar.DockOffset && row == bar.DockRow) || (row != bar.DockRow)) {
                        if (bar.Floating) {
                              SetPlaceholder (bar, nx, row);
                              FloatBar (bar, x, y);
                        }
                        return;
                  }
                  
                  HidePlaceholder ();
                  MoveBar (bar, nx, row);
            }
            
            void FloatBar (DockToolbar bar, int x, int y)
            {
                  if (bar.Floating) return;
                  
                  int wx,wy,w,h;
                  PanelToWindow (x, y, GetChildWidth (bar), bar.DefaultHeight, out x, out y, out w, out h);
                        
                  this.GdkWindow.GetOrigin (out wx, out wy);
                  RemoveBar (bar);
                  parentFrame.FloatBar (bar, orientation, wx + x, wy + y);
            }
            
            void ShiftBar (int index, int size)
            {
                  DockToolbar bar = (DockToolbar) bars [index];
                  if (bar.DockShiftOffset == -1)
                        bar.DockShiftOffset = bar.DockOffset;
                  
                  if (size > 0) {
                        int rp = GetChildRightOffset (bar);
                        int gap = PanelWidth - rp;
                        if (index + 1 < bars.Count) {
                              DockToolbar obar = (DockToolbar) bars [index + 1];
                              if (bar.DockRow == obar.DockRow) {
                                    gap = obar.DockOffset - rp;
                                    if (gap < size) {
                                          ShiftBar (index + 1, size - gap);
                                          gap = obar.DockOffset - rp;
                                    }
                              }
                        }
                        if (gap > size)
                              gap = size;
                        if (gap > 0)
                              MoveBar (bar, bar.DockOffset + gap, bar.DockRow, false);
                  } else {
                        size = -size;
                        int lp = bar.DockOffset;
                        int gap = lp;
                        if (index > 0) {
                              DockToolbar obar = (DockToolbar) bars [index - 1];
                              if (bar.DockRow == obar.DockRow) {
                                    gap = lp - GetChildRightOffset (obar);
                                    if (gap < size) {
                                          ShiftBar (index - 1, gap - size);
                                          gap = lp - GetChildRightOffset (obar);
                                    }
                              }
                        }
                        
                        if (gap > size)
                              gap = size;
                        if (gap > 0)
                              MoveBar (bar, bar.DockOffset - gap, bar.DockRow, false);
                  }
            }
            
            void MoveBar (DockToolbar bar, int x, int row)
            {
                  MoveBar (bar, x, row, true);
            }
            
            void MoveBar (DockToolbar bar, int x, int row, bool setAnchorOffset)
            {
                  int rt = GetRowTop (row);

                  bar.DockRow = row;
                  bar.DockOffset = x;
                  
                  if (bar.Floating) {
                        FloatingDock win = bar.FloatingDock;
                        win.Detach ();
                        win.Destroy ();
                        
                        InternalAdd (bar);
                        Put (bar, x, rt);
                        SortBars ();
                        ResetAnchorOffsets (row);
                        
                  } else {
                        if (setAnchorOffset)
                              ResetAnchorOffsets (row);

                        InternalMove (bar, x, rt, true);
                  }
            }
            
            void ResetAnchorOffsets (int row)
            {
                  for (int n=0; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar) bars [n];
                        if (b.DockRow < row) continue;
                        if (b.DockRow > row) return;
                        b.AnchorOffset = b.DockOffset;
                  }
            }
            
            void UpdateRowHeight (int row)
            {
                  int nr = row + 1;
                  bool ea = EnableAnimation (false);
                  for (int n=0; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar) bars [n];
                        if (b.DockRow < nr) continue;
                        MoveBar (b, b.DockOffset, b.DockRow);
                  }
                  EnableAnimation (ea);
            }
            
            void OnBarSizeChanged (object s, EventArgs e)
            {
                  UpdateRowSizes (((DockToolbar)s).DockRow);
            }
            
            void UpdateRowSizes (int row)
            {
                  int lastx = 0;
                  for (int n=0; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar) bars [n];
                        if (b.DockRow < row) continue;
                        if (b.DockRow > row) break;
                        if (b.AnchorOffset < lastx)
                              b.AnchorOffset = lastx;
                        lastx = b.AnchorOffset + b.DefaultSize;
                  }
                  PackBars ();
            }
            
            protected override void OnSizeAllocated (Rectangle rect)
            {
                  Rectangle oldRect = Allocation;
                  base.OnSizeAllocated (rect);
                  
                  if (!rect.Equals (oldRect))
                        PackBars ();
            }
            
            void PackBars ()
            {
                  bool ea = EnableAnimation (false);
                  int n=0;
                  while (n < bars.Count)
                        n = PackRow (n);
                  EnableAnimation (ea);
            }
            
            int PackRow (int sn)
            {
                  int n = sn;
                  int row = ((DockToolbar)bars[n]).DockRow;
                  int lastx = 0;
                  int gaps = 0;

                  while (n < bars.Count) {
                        DockToolbar bar = (DockToolbar) bars [n];
                        if (bar.DockRow != row) break;
                        
                        if (bar.AnchorOffset > lastx)
                              gaps += bar.AnchorOffset - lastx;
                        
                        lastx = bar.AnchorOffset + bar.DefaultSize;
                        n++;
                  }

                  if (lastx <= PanelWidth) {
                        for (int i=sn; i<n; i++) {
                              DockToolbar b = (DockToolbar) bars[i];
                              if (b.AnchorOffset != b.DockOffset)
                                    MoveBar (b, b.AnchorOffset, b.DockRow, false);
                              if (b.Size != b.DefaultSize) {
                                    b.ShowArrow = false;
                                    b.Size = b.DefaultSize;
                              }
                        }
                        return n;
                  }
                  
                  int barsSize = lastx - gaps;
                  double barShrink = 1;
                  double gapShrink = 0;
                  
                  if (barsSize > PanelWidth)
                        barShrink = (double)PanelWidth / (double)barsSize;
                  else
                        gapShrink = ((double)(PanelWidth - barsSize)) / (double)gaps;
                  
                  lastx = 0;
                  int newlastx = 0;
                  for (int i=sn; i < n; i++) {
                        DockToolbar bar = (DockToolbar) bars [i];
                        int gap = bar.AnchorOffset - lastx;
                        lastx = bar.AnchorOffset + bar.DefaultSize;
                        
                        int nx = (int)(newlastx + ((double)gap * gapShrink));
                        if (nx != bar.DockOffset)
                              MoveBar (bar, nx, bar.DockRow, false);
                        
                        int nw = (int)((double)bar.DefaultSize * barShrink);
                        if (nw != bar.Size) {
                              bar.ShowArrow = nw != bar.DefaultSize;
                              bar.Size = nw;
                        }
                        newlastx = bar.DockOffset + nw;
                  }
                  
                  return n;
            }
            
            int GetPanelBottom ()
            {
                  if (bars.Count > 0) {
                        DockToolbar bar = (DockToolbar) bars [bars.Count - 1];
                        return GetRowTop (bar.DockRow + 1);
                  }
                  else
                        return 0;
            } 
            
            bool IsSingleBarRow (DockToolbar bar)
            {
                  int row = bar.DockRow;
                  foreach (DockToolbar b in bars) {
                        if (bar != b && b.DockRow == row)
                              return false;
                  }
                  return true;
            }
            
            void InsertRow (DockToolbar ibar, int offset, int row)
            {
                  MoveBar (ibar, offset, row);
                  foreach (DockToolbar bar in bars) {
                        if (ibar != bar && bar.DockRow >= row)
                              bar.DockRow++;
                  }
                  SortBars ();
                  UpdateRowHeight (row);
            }
            
            void RemoveRow (int row)
            {
                  foreach (DockToolbar bar in bars) {
                        if (bar.DockRow >= row)
                              MoveBar (bar, bar.DockOffset, bar.DockRow - 1, false);
                  }
            }
            
            int GetChildRightOffset (DockToolbar bar)
            {
                  return bar.DockOffset + bar.Size;
            }
            
            int GetRowSize (int row)
            {
                  int max = 0;
                  for (int n=0; n<bars.Count; n++) {
                        DockToolbar b = (DockToolbar) bars [n];
                        if (b.DockRow < row) continue;
                        if (b.DockRow > row) return max;
                        if (b.DefaultHeight > max)
                              max = b.DefaultHeight;
                  }
                  return max;
            }
            
            int GetRowTop (int row)
            {
                  int t = 0;
                  for (int n=0; n < row; n++)
                        t += GetRowSize (n);
                  return t;
            }
            
            void SortBars ()
            {
                  bars.Sort (DocBarComparer.Instance);
            }
            
            void InternalMove (DockToolbar bar, int x, int y, bool animate)
            {
                  if (bar.Animation != null) {
                        bar.Animation.Cancel ();
                        bar.Animation = null;
                  }
                  
                  if (animate && enableAnimations) {
                        bar.Animation = new MoveAnimation (this, bar, x, y);
                        bar.Animation.Start ();
                  }
                  else
                        Move (bar, x, y);
            }
            
            bool EnableAnimation (bool enable)
            {
                  bool r = enableAnimations;
                  enableAnimations = enable;
                  return r;
            }
      }


      internal class DocBarComparer: IComparer
      {
            internal static DocBarComparer Instance = new DocBarComparer (); 
            
            public int Compare (object a, object b)
            {
                  DockToolbar b1 = (DockToolbar) a;
                  DockToolbar b2 = (DockToolbar) b;

                  if (b1.DockRow < b2.DockRow) return -1;
                  else if (b1.DockRow > b2.DockRow) return 1;
                  else if (b1.DockOffset < b2.DockOffset) return -1;
                  else if (b1.DockOffset > b2.DockOffset) return 1;
                  else return 0;
            } 
      }

      internal abstract class AnimationManager
      {
            static ArrayList anims = new ArrayList ();
            static int s = 0;
            
            public static void Animate (Animation a)
            {
                  if (anims.Count == 0)
                        GLib.Timeout.Add (10, new GLib.TimeoutHandler (Animate));
                  anims.Add (a);
            }
            
            public static void CancelAnimation (Animation a)
            {
                  anims.Remove (a);
            }
            
            public static bool Animate ()
            {
                  s++;
                  ArrayList toDelete = new ArrayList ();
                  foreach (Animation a in anims)
                        if (!a.Run ())
                              toDelete.Add (a);
                  
                  foreach (object ob in toDelete)
                        anims.Remove (ob);

                  return anims.Count != 0;
            }
      }

      internal abstract class Animation
      {
            protected Widget widget;
            
            public Animation (Widget w)
            {
                  widget = w;
            }
            
            public void Start ()
            {
                  AnimationManager.Animate (this);
            }
            
            public void Cancel ()
            {
                  AnimationManager.CancelAnimation (this);
            }
            
            internal protected abstract bool Run ();
      }

      internal class MoveAnimation: Animation
      {
            FixedPanel panel;
            float destx, desty;
            float curx, cury;
            
            public MoveAnimation (FixedPanel f, Widget w, int destx, int desty): base (w)
            {
                  panel = f;
                  int x, y;
                  f.GetPosition (w, out x, out y);
                  curx = (float)x;
                  cury = (float)y;
                  this.destx = (float) destx;
                  this.desty = (float) desty;
            }
            
            internal protected override bool Run ()
            {
                  float dx = destx - curx;
                  float dy = desty - cury;
                  
                  dx = dx / 4;
                  dy = dy / 4;
                  
                  curx += dx;
                  cury += dy;
                  
                  panel.Move (widget, (int)curx, (int)cury);
                  
                  if(Math.Abs (dx) < 0.1 && Math.Abs (dy) < 0.1) {
                        panel.Move (widget, (int)destx, (int)desty);
                        return false;
                  } else
                        return true;
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index