1
// ItemPositionProvider.cs
3
// Copyright (C) 2009 GNOME Do
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
20
using System.Collections.Generic;
25
using Docky.Utilities;
27
namespace Docky.Interface
31
public class ItemPositionProvider : IDisposable
33
const int HorizontalBuffer = 7;
35
DockItemProvider item_provider;
38
List<BaseDockItem> DockItems {
39
get { return item_provider.DockItems; }
43
/// The width of the visible dock
45
public int DockWidth {
47
int val = 2 * HorizontalBuffer;
48
foreach (BaseDockItem di in DockItems)
49
val += 2 * DockPreferences.IconBorderWidth + di.Width;
54
public int VerticalBuffer {
59
get { return DockPreferences.IconSize; }
63
get { return clip_area.Width; }
67
get { return clip_area.Height; }
71
get { return DockPreferences.ZoomSize; }
74
public Rectangle MinimumDockArea {
76
int x_offset = (Width - DockWidth) / 2;
77
return new Gdk.Rectangle (x_offset, Height - IconSize - 2 * VerticalBuffer, DockWidth, IconSize + 2 * VerticalBuffer);
81
public ItemPositionProvider(DockItemProvider itemProvider, Gdk.Rectangle clipArea)
83
item_provider = itemProvider;
87
public Rectangle DockArea (double zoomByEntryTime, Gdk.Point cursor)
90
double start_zoom, end_zoom;
91
IconZoomedPosition (0, zoomByEntryTime, cursor, out start_x, out start_zoom);
92
IconZoomedPosition (DockItems.Count - 1, zoomByEntryTime, cursor, out end_x, out end_zoom);
94
double x = start_x - start_zoom * (IconSize / 2) - (start_zoom * HorizontalBuffer) - DockPreferences.IconBorderWidth;
95
double end = end_x + end_zoom * (IconSize / 2) + (end_zoom * HorizontalBuffer) + DockPreferences.IconBorderWidth;
97
return new Gdk.Rectangle ((int) x, Height - IconSize - 2 * VerticalBuffer, (int) (end - x), IconSize + 2 * VerticalBuffer);
100
public int IconUnzoomedPosition (int icon)
102
// the first icons center is at dock X + border + IconBorder + half its width
103
// it is subtle, but it *is* a mistake to add the half width until the end. adding
104
// premature will add the wrong width. It hurts the brain.
105
if (!DockItems.Any ())
107
int startX = MinimumDockArea.X + HorizontalBuffer + DockPreferences.IconBorderWidth;
108
for (int i = 0; i < icon; i++)
109
startX += DockItems [i].Width + 2 * DockPreferences.IconBorderWidth;
111
return startX + DockItems [icon].Width / 2;
114
public void IconZoomedPosition (int icon, double zoomByEntryTime, Gdk.Point cursor, out int position, out double zoom)
116
// get our actual center
117
int center = IconUnzoomedPosition (icon);
119
// ZoomPercent is a number greater than 1. It should never be less than one.
120
// ZoomIn is a range of 0 to 1. we need a number that is 1 when ZoomIn is 0,
121
// and ZoomPercent when ZoomIn is 1. Then we treat this as
122
// if it were the ZoomPercent for the rest of the calculation
123
double zoomInPercent = 1 + (DockPreferences.ZoomPercent - 1) * zoomByEntryTime;
125
// offset from the center of the true position, ranged between 0 and half of the zoom range
126
int offset = Math.Min (Math.Abs (cursor.X - center), ZoomSize / 2);
128
if (ZoomSize / 2.0 == 0) {
131
// zoom is calculated as 1 through target_zoom (default 2).
132
// The larger your offset, the smaller your zoom
133
zoom = 0 - Math.Pow (offset / (ZoomSize / 2.0), 2) + 2;
134
zoom = 1 + (zoom - 1) * (zoomInPercent - 1);
136
offset = (int) (offset * (zoomInPercent - 1) - (zoomInPercent - zoom) * (IconSize * .9));
139
if (cursor.X > center) {
147
public int IndexAtPosition (int position)
149
int startX = MinimumDockArea.X + HorizontalBuffer;
151
for (int i = 0; i < DockItems.Count; i++) {
152
width = DockItems [i].Width + 2 * DockPreferences.IconBorderWidth;
153
if (position >= startX && position <= startX + width)
160
#region IDisposable implementation
162
public void Dispose ()
164
item_provider = null;