Ejemplo n.º 1
0
			public DrawValue MoveIn (DockPosition position, double amount)
			{
				DrawValue result = new DrawValue {
					Center = Center,
					StaticCenter = StaticCenter,
					HoverArea = HoverArea,
					Zoom = Zoom
				};
				
				switch (position) {
				case DockPosition.Top:
					result.Center.Y += amount;
					result.StaticCenter.Y += amount;
					break;
				case DockPosition.Left:
					result.Center.X += amount;
					result.StaticCenter.X += amount;
					break;
				case DockPosition.Right:
					result.Center.X -= amount;
					result.StaticCenter.X -= amount;
					break;
				case DockPosition.Bottom:
					result.Center.Y -= amount;
					result.StaticCenter.Y -= amount;
					break;
				}
				
				return result;
			}
Ejemplo n.º 2
0
		Gdk.Rectangle DrawRegionForItemValue (AbstractDockItem item, DrawValue val, bool hoverRegion)
		{
			int width = IconSize, height = IconSize;
			
			if (!item.Square) {
				DockySurface surface = item.IconSurface (main_buffer, IconSize, IconSize, VisibleDockHeight);
				
				width = surface.Width;
				height = surface.Height;
				
				if (item.RotateWithDock && Preferences.IsVertical) {
					int tmp = width;
					width = height;
					height = tmp;
				}
			}
			
			if (hoverRegion)
				if (Preferences.IsVertical)
					return new Gdk.Rectangle ((int) (val.Center.X - (width * val.Zoom / 2)),
						(int) (val.StaticCenter.Y - height / 2),
						(int) (width * val.Zoom),
						height);
				else
					return new Gdk.Rectangle ((int) (val.StaticCenter.X - width / 2),
						(int) (val.Center.Y - (height * val.Zoom / 2)),
						width,
						(int) (height * val.Zoom));
			
			return new Gdk.Rectangle ((int) (val.Center.X - (width * val.Zoom / 2)),
				(int) (val.Center.Y - (height * val.Zoom / 2)),
				(int) (width * val.Zoom),
				(int) (height * val.Zoom));
		}
Ejemplo n.º 3
0
		/// <summary>
		/// Updates drawing regions for the supplied surface
		/// </summary>
		/// <param name="surface">
		/// The <see cref="DockySurface"/> surface off which the coordinates will be based
		/// </param>
		void UpdateDrawRegionsForSurface (DockySurface surface)
		{
			// first we do the math as if this is a top dock, to do this we need to set
			// up some "pretend" variables. we pretend we are a top dock because 0,0 is
			// at the top.
			int width = surface.Width;
			int height = surface.Height;
			double zoom;
			
			Gdk.Point cursor = LocalCursor;
			Gdk.Point localCursor = cursor;
			
			// "relocate" our cursor to be on the top
			switch (Position) {
			case DockPosition.Right:
				cursor.X = (Width - 1) - cursor.X;
				break;
			case DockPosition.Bottom:
				cursor.Y = (Height - 1) - cursor.Y;
				break;
			default:
				break;
			}
			
			if (Preferences.IsVertical) {
				int tmpY = cursor.Y;
				cursor.Y = cursor.X;
				cursor.X = tmpY;
				
				// our width and height switch around if we have a veritcal dock
				width = surface.Height;
				height = surface.Width;
			}
			
			// this offset is used to split the icons into left/right aligned for panel mode
			double panelanim = PanelModeToggleProgress;
			int panel_item_offset;
			
			if (Preferences.IsVertical)
				panel_item_offset = (monitor_geo.Height - DockWidth) / 2;
			else
				panel_item_offset = (monitor_geo.Width - DockWidth) / 2;
			
			if (panelanim >= 1) {
				if (!Preferences.PanelMode)
					panel_item_offset = 0;
			} else {
				if (Preferences.PanelMode)
					panel_item_offset = (int) (panel_item_offset * panelanim);
				else
					panel_item_offset -= (int) (panel_item_offset * panelanim);
			}
			
			// the line along the dock width about which the center of unzoomed icons sit
			int midline = DockHeight / 2;
			
			// the left most edge of the first dock item
			int startX = ((width - DockWidth) / 2) + DockWidthBuffer - panel_item_offset;
			
			Gdk.Point center = new Gdk.Point (startX, midline);
			
			// right align docklets
			bool rightAlign = (Items [0].Owner != Preferences.DefaultProvider && Items [0] != DockyItem);
			if (rightAlign)
				center.X += 2 * panel_item_offset;
			
			int index = 0;
			foreach (AbstractDockItem adi in Items) {
				// anything after the first separator is a docklet, and right aligned
				if (!rightAlign && adi is SeparatorItem) {
					rightAlign = true;
					center.X += 2 * panel_item_offset;
				}
				
				// used to handle remove animations
				if (remove_index != 0 && remove_index < index && remove_index > index - 1) {
					double removePercent = 1 - Math.Min (1, (DateTime.UtcNow - remove_time).TotalMilliseconds / BaseAnimationTime.TotalMilliseconds);
					if (removePercent == 0)
						remove_index = 0;
					else
						center.X += (int) ((remove_size + ItemWidthBuffer) * removePercent);
				}
				
				DrawValue val = new DrawValue ();
				int iconSize = IconSize;
				
				// div by 2 may result in rounding errors? Will this render OK? Shorts WidthBuffer by 1?
				double halfSize = iconSize / 2.0;
				
				if (!adi.Square) {
					DockySurface icon = adi.IconSurface (surface, iconSize, iconSize, VisibleDockHeight);
					halfSize = ((adi.RotateWithDock || !Preferences.IsVertical) ? icon.Width : icon.Height) / 2.0;
				}
				
				// animate adding new icon
				halfSize *= Math.Min (1, (DateTime.UtcNow - adi.AddTime).TotalMilliseconds / BaseAnimationTime.TotalMilliseconds);
				
				// center now represents our midpoint
				center.X += (int) Math.Floor (halfSize);
				val.StaticCenter = new PointD (center.X, center.Y);
				
				// get us some handy doubles with fancy names
				double cursorPosition = cursor.X;
				double centerPosition = center.X;
				
				// ZoomPercent is a number greater than 1.  It should never be less than one.
				
				// zoomInPercent is a range of 1 to ZoomPercent.
				// We need a number that is 1 when ZoomIn is 0, and ZoomPercent when ZoomIn is 1.
				// Then we treat this as if it were the ZoomPercent for the rest of the calculation.
				double zoomInPercent = 1 + (ZoomPercent - 1) * ZoomIn;
				
				double zoomSize = ZoomEnabled ? ZoomedIconSize : 2.0 * IconSize;
				
				// offset from the center of the true position, ranged between 0 and the zoom size
				double offset = Math.Min (Math.Abs (cursorPosition - centerPosition), zoomSize);
				
				double offsetPercent;
				if (ExternalDragActive && DragTracker.ProviderAcceptsDrop ()) {
					// Provide space for dropping between items
					offset += offset * zoomSize / IconSize;
					offsetPercent = Math.Min (1, offset / (zoomSize + ZoomedIconSize));
				} else {
					offsetPercent = offset / zoomSize;
				}
				
				if (offsetPercent > .99)
					offsetPercent = 1;
				
				// pull in our offset to make things less spaced out
				// explaination since this is a bit tricky...
				// we have three terms, basically offset = f(x) * h(x) * g(x)
				// f(x) == offset identity
				// h(x) == a number from 0 to DockPreference.ZoomPercent - 1.  This is used to get the smooth "zoom in" effect.
				//         additionally serves to "curve" the offset based on the max zoom
				// g(x) == a term used to move the ends of the zoom inward.  Precalculated that the edges should be 66% of the current
				//         value. The center is 100%. (1 - offsetPercent) == 0,1 distance from center
				// The .66 value comes from the area under the curve.  Dont ask me to explain it too much because it's too clever for me.
				
				// for external drags with no zoom, we pretend there is actually a zoom of 200%
				if (ExternalDragActive && ZoomPercent == 1 && DragTracker.ProviderAcceptsDrop ())
					offset *= ZoomIn / 2.0;
				else
					offset *= zoomInPercent - 1;
				offset *= 1 - offsetPercent / 3;
				
				if (cursorPosition > centerPosition)
					centerPosition -= offset;
				else
					centerPosition += offset;
				
				if (!adi.Zoom) {
					val.Zoom = 1;
					val.Center = new Cairo.PointD ((int) centerPosition, center.Y);
				} else {
					// zoom is calculated as 1 through target_zoom (default 2).  
					// The larger your offset, the smaller your zoom
					
					// First we get the point on our curve that defines our current zoom
					// offset is always going to fall on a point on the curve >= 0
					zoom = 1 - Math.Pow (offsetPercent, 2);
					
					// scale this to match our zoomInPercent
					zoom = 1 + zoom * (zoomInPercent - 1);
					
					double zoomedCenterHeight = DockHeightBuffer + (iconSize * zoom / 2.0);
					
					if (zoom == 1)
						centerPosition = Math.Round (centerPosition);
					
					val.Center = new Cairo.PointD (centerPosition, zoomedCenterHeight);
					val.Zoom = zoom;
				}
				
				// now we undo our transforms to the point
				if (Preferences.IsVertical) {
					double tmpY = val.Center.Y;
					val.Center.Y = val.Center.X;
					val.Center.X = tmpY;
					
					tmpY = val.StaticCenter.Y;
					val.StaticCenter.Y = val.StaticCenter.X;
					val.StaticCenter.X = tmpY;
				}
				
				switch (Position) {
				case DockPosition.Right:
					val.Center.X = (height - 1) - val.Center.X;
					val.StaticCenter.X = (height - 1) - val.StaticCenter.X;
					break;
				case DockPosition.Bottom:
					val.Center.Y = (height - 1) - val.Center.Y;
					val.StaticCenter.Y = (height - 1) - val.StaticCenter.Y;
					break;
				default:
					break;
				}
				
				Gdk.Rectangle hoverArea = DrawRegionForItemValue (adi, val, true);
				
				if (Preferences.IsVertical) {
					hoverArea.Inflate ((int) (ZoomedDockHeight * .3), ItemWidthBuffer / 2);
					hoverArea.Width += DockHeightBuffer;
				} else {
					hoverArea.Inflate (ItemWidthBuffer / 2, (int) (ZoomedDockHeight * .3));
					hoverArea.Height += DockHeightBuffer;
				}
				
				switch (Position) {
				case DockPosition.Right:
					hoverArea.X -= DockHeightBuffer;
					break;
				case DockPosition.Bottom:
					hoverArea.Y -= DockHeightBuffer;
					break;
				default:
					break;
				}
				
				val.HoverArea = hoverArea;
				DrawValues[adi] = val;

				// keep the hovereditem in mind, but don't change it while rendering
				if (hoverArea.Contains (localCursor) && !AutohideManager.Hidden && !(adi is SeparatorItem))
					next_hoveredItem = adi;
				
				if (update_screen_regions) {
					if (Menu.Visible || ConfigurationMode || Painter != null) {
						adi.SetScreenRegion (Screen, new Gdk.Rectangle (0, 0, 0, 0));
					} else {
						Gdk.Rectangle region = hoverArea;
						region.X += window_position.X;
						region.Y += window_position.Y;
						adi.SetScreenRegion (Screen, region);
					}
				}
				
				// move past midpoint to end of icon
				center.X += (int) Math.Ceiling (halfSize) + ItemWidthBuffer;
				
				index++;
			}
			
			update_screen_regions = false;
		}
Ejemplo n.º 4
0
		Gdk.Rectangle DrawRegionForItemValue (AbstractDockItem item, DrawValue val)
		{
			return DrawRegionForItemValue (item, val, false);
		}