Merge lp:~ricotz/docky/desktopswitcher into lp:docky

Proposed by Rico Tzschichholz
Status: Merged
Merged at revision: 1577
Proposed branch: lp:~ricotz/docky/desktopswitcher
Merge into: lp:docky
Diff against target: 907 lines (+769/-4)
12 files modified
Docky-2.sln (+7/-0)
Docky.Items/Docky.Items/AbstractDockItem.cs (+3/-1)
Docky.Items/Docky.Items/AbstractDockItemProvider.cs (+4/-1)
Docky/Docky/Interface/DockPreferences.cs (+3/-0)
StandardPlugins/Makefile.am (+5/-2)
StandardPlugins/WorkspaceSwitcher/Makefile.am (+30/-0)
StandardPlugins/WorkspaceSwitcher/Resources/WorkspaceSwitcher.addin.xml.in (+25/-0)
StandardPlugins/WorkspaceSwitcher/WorkspaceSwitcher.csproj (+75/-0)
StandardPlugins/WorkspaceSwitcher/src/Desk.cs (+205/-0)
StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherDockItem.cs (+365/-0)
StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherItemProvider.cs (+45/-0)
configure.ac (+2/-0)
To merge this branch: bzr merge lp:~ricotz/docky/desktopswitcher
Reviewer Review Type Date Requested Status
Robert Dyer (community) Needs Fixing
Rico Tzschichholz Approve
Review via email: mp+26822@code.launchpad.net

Description of the change

add WorkspaceSwitcher docklet

To post a comment you must log in.
Revision history for this message
Robert Dyer (psybers) wrote :

Great idea and all, but you can technically have both workspaces and viewports within workspaces and your docklet does not allow that case.

review: Needs Fixing
Revision history for this message
Robert Dyer (psybers) wrote :

1) your docklet should not rotate

2) in OnClicked, the x/y are sent in as percents and you are assuming they are sent as relative co-ords

review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

1) i hope you can explain how to establish this without rotating later

2) you should closer to "Cairo.Rectangle area = DeskAreaOnIcon (1, 1, row, col)" and understand what it does. A Cairo.Rectangle are 4 double values and DeskAreaOnIcon return an Cairo.Rectangle inside the bound of 1x1

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

I think this is ready for merge.

review: Approve
Revision history for this message
Ralf Czaska (longfried) wrote :

Typo in desk.cs line 47?

lp:~ricotz/docky/desktopswitcher updated
1469. By Rico Tzschichholz

fix typo

1470. By Rico Tzschichholz

merge trunk 1575

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

> Typo in desk.cs line 47?

Fixed, didn't noticed this since this property isn't used.

Revision history for this message
Robert Dyer (psybers) wrote :

1) It doesnt 'wrap' when I scroll over it. I realize for some cases this is hard to figure out, and honestly I dont know the answer (for square layouts). But for purely horizontal/vertical layouts it makes perfect sense and needs to be there.

2) what is this 'folder' (??) icon on the active desktop?

3) Should the hover text update itself based on what portion is hovered? IE, hover desk 1 and the hover shows 'desk 1' etc, instead of always showing the current desk - that way, you get a hover for what you are about to click on which makes it easier.... i am not even sure our API allows this, but lets first figure out if it makes sense and go from there :)

review: Needs Fixing
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

> 1) It doesnt 'wrap' when I scroll over it. I realize for some cases this is hard to figure out, and honestly I dont know the answer (for square layouts). But for purely horizontal/vertical layouts it makes perfect sense and needs to be there.

I will implement it this way. If there is a one row/col layout it will
wrap around. On multi row and column layouts scrolling will walk through
line by line and jump from [1,1] to [n,n]

> 2) what is this 'folder' (??) icon on the active desktop?

Just the theme icon for "desktop" to mark it in a proper/colored way to
match the current icon theme.

> 3) Should the hover text update itself based on what portion is hovered? IE, hover desk 1 and the hover shows 'desk 1' etc, instead of always showing the current desk - that way, you get a hover for what you are about to click on which makes it easier.... i am not even sure our API allows this, but lets first figure out if it makes sense and go from there :)

Will need some core changes to do this, so shelve this idea for now.

lp:~ricotz/docky/desktopswitcher updated
1471. By Rico Tzschichholz

add WrappedScrolling

1472. By Rico Tzschichholz

wrapped scrolling through workspaces row/col by row/col

1473. By Rico Tzschichholz

optimizations and fixes

1474. By Rico Tzschichholz

last cleanups

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Docky-2.sln'
2--- Docky-2.sln 2010-06-08 08:20:21 +0000
3+++ Docky-2.sln 2010-07-21 11:16:11 +0000
4@@ -41,6 +41,8 @@
5 EndProject
6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timer", "StandardPlugins\Timer\Timer.csproj", "{AAD062AA-454A-4263-97E7-B6ED3020D84C}"
7 EndProject
8+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspaceSwitcher", "StandardPlugins\WorkspaceSwitcher\WorkspaceSwitcher.csproj", "{66939AAB-0832-4D2D-8282-3E29AA772B69}"
9+EndProject
10 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Docky.Widgets", "Docky.Widgets\Docky.Widgets.csproj", "{9CF2F475-7848-4333-9A35-93E8224653B3}"
11 EndProject
12 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Docky.DBus", "Docky.DBus\Docky.DBus.csproj", "{487D3B93-FAAF-4734-B337-85810A60ACCF}"
13@@ -75,6 +77,10 @@
14 {58A2F667-86BF-4128-B442-77C6D14C89A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 {58A2F667-86BF-4128-B442-77C6D14C89A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 {58A2F667-86BF-4128-B442-77C6D14C89A4}.Release|Any CPU.Build.0 = Release|Any CPU
17+ {66939AAB-0832-4D2D-8282-3E29AA772B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18+ {66939AAB-0832-4D2D-8282-3E29AA772B69}.Debug|Any CPU.Build.0 = Debug|Any CPU
19+ {66939AAB-0832-4D2D-8282-3E29AA772B69}.Release|Any CPU.ActiveCfg = Release|Any CPU
20+ {66939AAB-0832-4D2D-8282-3E29AA772B69}.Release|Any CPU.Build.0 = Release|Any CPU
21 {704C5716-B36A-42CC-8BE0-CB8A6CB6B97A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 {704C5716-B36A-42CC-8BE0-CB8A6CB6B97A}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 {704C5716-B36A-42CC-8BE0-CB8A6CB6B97A}.Release|Any CPU.ActiveCfg = Release|Any CPU
24@@ -151,6 +157,7 @@
25 {A96B9440-A980-4E61-8B9A-BA64A2A696E6} = {8D4EE2FA-9CF2-4890-B14A-1BA8752404FE}
26 {731A3B89-99C8-44A8-9ADB-9A3AF3A58C9E} = {8D4EE2FA-9CF2-4890-B14A-1BA8752404FE}
27 {AAD062AA-454A-4263-97E7-B6ED3020D84C} = {8D4EE2FA-9CF2-4890-B14A-1BA8752404FE}
28+ {66939AAB-0832-4D2D-8282-3E29AA772B69} = {8D4EE2FA-9CF2-4890-B14A-1BA8752404FE}
29 EndGlobalSection
30 GlobalSection(MonoDevelopProperties) = preSolution
31 version = 2.0
32
33=== modified file 'Docky.Items/Docky.Items/AbstractDockItem.cs'
34--- Docky.Items/Docky.Items/AbstractDockItem.cs 2010-07-21 08:50:49 +0000
35+++ Docky.Items/Docky.Items/AbstractDockItem.cs 2010-07-21 11:16:11 +0000
36@@ -595,7 +595,9 @@
37 if (icon_buffers[j] == null || redraw[j])
38 continue;
39
40- if (icon_buffers[j].Height == size)
41+ if (icon_buffers[j].Height == size
42+ || (Owner != null && Owner.IsOnVerticalDock && icon_buffers[j].Width == size))
43+
44 return icon_buffers[j];
45 }
46
47
48=== modified file 'Docky.Items/Docky.Items/AbstractDockItemProvider.cs'
49--- Docky.Items/Docky.Items/AbstractDockItemProvider.cs 2010-06-17 06:43:24 +0000
50+++ Docky.Items/Docky.Items/AbstractDockItemProvider.cs 2010-07-21 11:16:11 +0000
51@@ -42,6 +42,8 @@
52 get { return !disposing && true; }
53 }
54
55+ public bool IsOnVerticalDock { get; set; }
56+
57 IEnumerable<AbstractDockItem> items;
58 public IEnumerable<AbstractDockItem> Items {
59 get { return items; }
60@@ -66,10 +68,11 @@
61 OnItemsChanged (added, removed);
62 }
63 }
64-
65+
66 protected AbstractDockItemProvider ()
67 {
68 items = Enumerable.Empty<AbstractDockItem> ();
69+ IsOnVerticalDock = false;
70 }
71
72 public bool CanAcceptDrop (string uri)
73
74=== modified file 'Docky/Docky/Interface/DockPreferences.cs'
75--- Docky/Docky/Interface/DockPreferences.cs 2010-06-17 09:52:23 +0000
76+++ Docky/Docky/Interface/DockPreferences.cs 2010-07-21 11:16:11 +0000
77@@ -467,6 +467,7 @@
78 public void AddProvider (AbstractDockItemProvider provider)
79 {
80 item_providers.Add (provider);
81+ provider.IsOnVerticalDock = IsVertical;
82
83 OnItemProvidersChanged (provider.AsSingle (), null);
84 }
85@@ -714,6 +715,8 @@
86
87 void OnPositionChanged ()
88 {
89+ item_providers.ForEach (provider => provider.IsOnVerticalDock = IsVertical);
90+
91 if (PositionChanged != null)
92 PositionChanged (this, EventArgs.Empty);
93 }
94
95=== modified file 'StandardPlugins/Makefile.am'
96--- StandardPlugins/Makefile.am 2010-05-22 04:50:36 +0000
97+++ StandardPlugins/Makefile.am 2010-07-21 11:16:11 +0000
98@@ -12,7 +12,8 @@
99 SessionManager \
100 Timer \
101 Trash \
102- Weather
103+ Weather \
104+ WorkspaceSwitcher
105
106 DIST_SUBDIRS = \
107 BatteryMonitor \
108@@ -28,4 +29,6 @@
109 SessionManager \
110 Timer \
111 Trash \
112- Weather
113+ Weather \
114+ WorkspaceSwitcher
115+
116
117=== added directory 'StandardPlugins/WorkspaceSwitcher'
118=== added file 'StandardPlugins/WorkspaceSwitcher/Makefile.am'
119--- StandardPlugins/WorkspaceSwitcher/Makefile.am 1970-01-01 00:00:00 +0000
120+++ StandardPlugins/WorkspaceSwitcher/Makefile.am 2010-07-21 11:16:11 +0000
121@@ -0,0 +1,30 @@
122+# Simple component buildsystem
123+include $(top_srcdir)/build.rules.docklets.mk
124+
125+ASSEMBLY = WorkspaceSwitcher
126+
127+FILES = \
128+ src/Desk.cs \
129+ src/WorkspaceSwitcherDockItem.cs \
130+ src/WorkspaceSwitcherItemProvider.cs
131+
132+RESOURCES = \
133+ Resources/WorkspaceSwitcher.addin.xml
134+
135+PROJECT_REFERENCES= \
136+ Docky.CairoHelper \
137+ Docky.Items \
138+ Docky.Windowing \
139+ Docky.Services
140+
141+REFERENCES = \
142+ System \
143+ System.Core \
144+ Mono.Posix \
145+ $(MONO_CAIRO_LIBS) \
146+ $(GCONF_SHARP_20_LIBS) \
147+ $(GTK_SHARP_20_LIBS) \
148+ $(GLIB_SHARP_20_LIBS) \
149+ $(GIO_SHARP_LIBS) \
150+ $(LIBRSVG_SHARP_LIBS) \
151+ $(WNCK_SHARP_10_LIBS)
152
153=== added directory 'StandardPlugins/WorkspaceSwitcher/Resources'
154=== added file 'StandardPlugins/WorkspaceSwitcher/Resources/WorkspaceSwitcher.addin.xml.in'
155--- StandardPlugins/WorkspaceSwitcher/Resources/WorkspaceSwitcher.addin.xml.in 1970-01-01 00:00:00 +0000
156+++ StandardPlugins/WorkspaceSwitcher/Resources/WorkspaceSwitcher.addin.xml.in 2010-07-21 11:16:11 +0000
157@@ -0,0 +1,25 @@
158+<Addin
159+ id="WorkspaceSwitcher"
160+ namespace="Docky"
161+ version="1.0"
162+ isroot="false"
163+ defaultEnabled="false"
164+ name="Workspace Switcher"
165+ description="Switch between your Desks"
166+ author="Rico Tzschichholz"
167+ icon="workspace-switcher"
168+>
169+
170+ <Dependencies>
171+ <Addin id="Items" version="1.0" />
172+ </Dependencies>
173+
174+ <Runtime>
175+ <Import assembly="WorkspaceSwitcher.dll"/>
176+ </Runtime>
177+
178+ <Extension path="/Docky/ItemProvider">
179+ <ItemProvider type="WorkspaceSwitcher.WorkspaceSwitcherItemProvider" />
180+ </Extension>
181+
182+</Addin>
183
184=== added file 'StandardPlugins/WorkspaceSwitcher/WorkspaceSwitcher.csproj'
185--- StandardPlugins/WorkspaceSwitcher/WorkspaceSwitcher.csproj 1970-01-01 00:00:00 +0000
186+++ StandardPlugins/WorkspaceSwitcher/WorkspaceSwitcher.csproj 2010-07-21 11:16:11 +0000
187@@ -0,0 +1,75 @@
188+<?xml version="1.0" encoding="utf-8"?>
189+<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
190+ <PropertyGroup>
191+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
192+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
193+ <ProductVersion>9.0.21022</ProductVersion>
194+ <SchemaVersion>2.0</SchemaVersion>
195+ <ProjectGuid>{66939AAB-0832-4D2D-8282-3E29AA772B69}</ProjectGuid>
196+ <OutputType>Exe</OutputType>
197+ <RootNamespace>WorkspaceSwitcher</RootNamespace>
198+ <AssemblyName>WorkspaceSwitcher</AssemblyName>
199+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
200+ <ReleaseVersion>2.0</ReleaseVersion>
201+ </PropertyGroup>
202+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
203+ <DebugSymbols>true</DebugSymbols>
204+ <DebugType>full</DebugType>
205+ <Optimize>false</Optimize>
206+ <OutputPath>bin\Debug</OutputPath>
207+ <DefineConstants>DEBUG</DefineConstants>
208+ <ErrorReport>prompt</ErrorReport>
209+ <WarningLevel>4</WarningLevel>
210+ </PropertyGroup>
211+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
212+ <DebugType>none</DebugType>
213+ <Optimize>false</Optimize>
214+ <OutputPath>bin\Release</OutputPath>
215+ <ErrorReport>prompt</ErrorReport>
216+ <WarningLevel>4</WarningLevel>
217+ </PropertyGroup>
218+ <ItemGroup>
219+ <Compile Include="src\WorkspaceSwitcherDockItem.cs" />
220+ <Compile Include="src\WorkspaceSwitcherItemProvider.cs" />
221+ <Compile Include="src\Desk.cs" />
222+ </ItemGroup>
223+ <ItemGroup>
224+ <None Include="Resources\WorkspaceSwitcher.addin.xml" />
225+ </ItemGroup>
226+ <ItemGroup>
227+ <ProjectReference Include="..\..\Docky.CairoHelper\Docky.CairoHelper.csproj">
228+ <Project>{B23E0EDD-6443-4F99-9EAC-B7CC906F080D}</Project>
229+ <Name>Docky.CairoHelper</Name>
230+ </ProjectReference>
231+ <ProjectReference Include="..\..\Docky.Items\Docky.Items.csproj">
232+ <Project>{AB6E0EDD-6443-4F99-9EAC-DABC906F080D}</Project>
233+ <Name>Docky.Items</Name>
234+ </ProjectReference>
235+ <ProjectReference Include="..\..\Docky.Windowing\Docky.Windowing.csproj">
236+ <Project>{888FCD95-7C79-45C4-A744-9C840DF4B9B0}</Project>
237+ <Name>Docky.Windowing</Name>
238+ </ProjectReference>
239+ <ProjectReference Include="..\..\Docky.Services\Docky.Services.csproj">
240+ <Project>{8A6E0EDD-6443-4F99-9EAC-D9CC906F080D}</Project>
241+ <Name>Docky.Services</Name>
242+ </ProjectReference>
243+ </ItemGroup>
244+ <ItemGroup>
245+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
246+ <Package>gtk-sharp-2.0</Package>
247+ </Reference>
248+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
249+ <Package>glib-sharp-2.0</Package>
250+ </Reference>
251+ <Reference Include="Mono.Cairo, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
252+ <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
253+ <Package>gtk-sharp-2.0</Package>
254+ </Reference>
255+ <Reference Include="System" />
256+ <Reference Include="System.Core" />
257+ <Reference Include="wnck-sharp, Version=2.20.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
258+ <Package>wnck-sharp-1.0</Package>
259+ </Reference>
260+ </ItemGroup>
261+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
262+</Project>
263\ No newline at end of file
264
265=== added directory 'StandardPlugins/WorkspaceSwitcher/src'
266=== added file 'StandardPlugins/WorkspaceSwitcher/src/Desk.cs'
267--- StandardPlugins/WorkspaceSwitcher/src/Desk.cs 1970-01-01 00:00:00 +0000
268+++ StandardPlugins/WorkspaceSwitcher/src/Desk.cs 2010-07-21 11:16:11 +0000
269@@ -0,0 +1,205 @@
270+//
271+// Copyright (C) 2010 Rico Tzschichholz
272+//
273+// This program is free software: you can redistribute it and/or modify
274+// it under the terms of the GNU General Public License as published by
275+// the Free Software Foundation, either version 3 of the License, or
276+// (at your option) any later version.
277+//
278+// This program is distributed in the hope that it will be useful,
279+// but WITHOUT ANY WARRANTY; without even the implied warranty of
280+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
281+// GNU General Public License for more details.
282+//
283+// You should have received a copy of the GNU General Public License
284+// along with this program. If not, see <http://www.gnu.org/licenses/>.
285+//
286+
287+using System;
288+using System.Collections.Generic;
289+using System.Collections.ObjectModel;
290+using System.Linq;
291+
292+using Gdk;
293+using Wnck;
294+
295+namespace WorkspaceSwitcher
296+{
297+ internal class Desk
298+ {
299+ public Wnck.Workspace Parent { get; private set; }
300+ public string Name { get; private set; }
301+ public int Number { get; private set; }
302+ public Gdk.Rectangle Area { get; private set; }
303+
304+ Dictionary<Wnck.MotionDirection, Desk> neighbors;
305+ Dictionary<Wnck.MotionDirection, Desk> wrapneighbors;
306+
307+ public static Wnck.MotionDirection AlternateMovingDirection (Wnck.MotionDirection direction)
308+ {
309+ switch (direction) {
310+ case MotionDirection.Down: return MotionDirection.Right;
311+ case MotionDirection.Up: return MotionDirection.Left;
312+ case MotionDirection.Left: return MotionDirection.Up;
313+ case MotionDirection.Right: default: return MotionDirection.Down;
314+ }
315+ }
316+
317+ public static Wnck.MotionDirection OppositeDirection (Wnck.MotionDirection direction)
318+ {
319+ switch (direction) {
320+ case MotionDirection.Down: return MotionDirection.Up;
321+ case MotionDirection.Up: return MotionDirection.Down;
322+ case MotionDirection.Left: return MotionDirection.Right;
323+ case MotionDirection.Right: default: return MotionDirection.Left;
324+ }
325+ }
326+
327+ public bool IsVirtual {
328+ get {
329+ return Parent.IsVirtual;
330+ }
331+ }
332+
333+ public bool IsActive {
334+ get {
335+ if (!Parent.IsVirtual)
336+ return Wnck.Screen.Default.ActiveWorkspace == Parent;
337+ else
338+ return Wnck.Screen.Default.ActiveWorkspace.ViewportX == Area.X && Wnck.Screen.Default.ActiveWorkspace.ViewportY == Area.Y;
339+ }
340+ }
341+
342+ Desk GetUpperLeftDesk ()
343+ {
344+ Desk upperleft, next;
345+ upperleft = this;
346+ while ((next = upperleft.GetNeighbor (Wnck.MotionDirection.Up)) != null)
347+ upperleft = next;
348+ while ((next = upperleft.GetNeighbor (Wnck.MotionDirection.Left)) != null)
349+ upperleft = next;
350+ return upperleft;
351+ }
352+
353+ Gdk.Point GetDeskGridSize ()
354+ {
355+ int cols = 1;
356+ int rows = 1;
357+ Desk bottomright, next;
358+ next = GetUpperLeftDesk ();
359+ while ((bottomright = next.GetNeighbor (Wnck.MotionDirection.Down)) != null) {
360+ next = bottomright;
361+ rows++;
362+ }
363+ while ((bottomright = next.GetNeighbor (Wnck.MotionDirection.Right)) != null) {
364+ next = bottomright;
365+ cols++;
366+ }
367+ return new Gdk.Point (cols, rows);
368+ }
369+
370+ public Desk [,] GetDeskGridLayout ()
371+ {
372+ Desk next, desk = GetUpperLeftDesk ();
373+ Gdk.Point gridsize = GetDeskGridSize ();
374+ Desk [,] grid = new Desk [gridsize.X, gridsize.Y];
375+ grid [0, 0] = desk;
376+ int x = 0;
377+ for (int y = 0; y < gridsize.Y; y++) {
378+ x = 0;
379+ while ((next = desk.GetNeighbor (Wnck.MotionDirection.Right)) != null) {
380+ desk = next;
381+ x++;
382+ if (gridsize.X - 1 < x)
383+ break;
384+ grid [x, y] = desk;
385+ }
386+ if (gridsize.Y - 1 > y) {
387+ desk = grid [0, y].GetNeighbor (Wnck.MotionDirection.Down);
388+ grid [0, y+1] = desk;
389+ }
390+ }
391+ return grid;
392+ }
393+
394+ public void Activate ()
395+ {
396+ if (Parent.Screen.ActiveWorkspace != Parent)
397+ Parent.Activate (Gtk.Global.CurrentEventTime);
398+ if (Parent.IsVirtual)
399+ Parent.Screen.MoveViewport (Area.X, Area.Y);
400+ }
401+
402+ public void SetNeighbor (Wnck.MotionDirection direction, Desk newneighbor)
403+ {
404+ Desk oldneighbor = GetNeighbor (direction);
405+ if (oldneighbor != null && oldneighbor != newneighbor) {
406+ neighbors.Remove (direction);
407+ if (oldneighbor.GetNeighbor (OppositeDirection (direction)) == this)
408+ oldneighbor.SetNeighbor (OppositeDirection (direction), null);
409+ }
410+ if (oldneighbor != newneighbor && newneighbor != null) {
411+ neighbors.Add (direction, newneighbor);
412+
413+ if (GetNeighbor (OppositeDirection (direction)) == null) {
414+ Desk oldwrapneighbor = newneighbor.GetWrapNeighbor (OppositeDirection (direction));
415+ if (oldwrapneighbor != null) {
416+ SetWrapNeighbor (OppositeDirection (direction), oldwrapneighbor);
417+ } else {
418+ SetWrapNeighbor (OppositeDirection (direction), newneighbor);
419+ }
420+ }
421+
422+ newneighbor.SetNeighbor (OppositeDirection (direction), this);
423+ }
424+ }
425+
426+ public void SetWrapNeighbor (Wnck.MotionDirection direction, Desk newwrapneighbor)
427+ {
428+ Desk oldwrapneighbor = GetWrapNeighbor (direction);
429+ if (oldwrapneighbor != null && oldwrapneighbor != newwrapneighbor) {
430+ wrapneighbors.Remove (direction);
431+ if (oldwrapneighbor.GetWrapNeighbor (OppositeDirection (direction)) == this)
432+ oldwrapneighbor.SetWrapNeighbor (OppositeDirection (direction), null);
433+ }
434+ if (oldwrapneighbor != newwrapneighbor && newwrapneighbor != null) {
435+ wrapneighbors.Add (direction, newwrapneighbor);
436+ newwrapneighbor.SetWrapNeighbor (OppositeDirection (direction), this);
437+ }
438+ }
439+
440+ public Desk GetNeighbor (Wnck.MotionDirection direction)
441+ {
442+ Desk desk;
443+ neighbors.TryGetValue (direction, out desk);
444+ return desk;
445+ }
446+
447+ public Desk GetWrapNeighbor (Wnck.MotionDirection direction)
448+ {
449+ Desk desk;
450+ wrapneighbors.TryGetValue (direction, out desk);
451+ return desk;
452+ }
453+
454+ public Desk (string name, int number, Gdk.Rectangle area, Workspace parent)
455+ {
456+ Parent = parent;
457+ Area = area;
458+ Name = name;
459+ Number = number;
460+ neighbors = new Dictionary<MotionDirection, Desk> ();
461+ wrapneighbors = new Dictionary<MotionDirection, Desk> ();
462+ }
463+
464+ public Desk (Workspace parent) : this (parent.Name, parent.Number, new Gdk.Rectangle (0, 0, parent.Width, parent.Height), parent)
465+ {
466+ }
467+
468+ public void Dispose ()
469+ {
470+ neighbors.Clear ();
471+ wrapneighbors.Clear ();
472+ }
473+ }
474+}
475
476=== added file 'StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherDockItem.cs'
477--- StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherDockItem.cs 1970-01-01 00:00:00 +0000
478+++ StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherDockItem.cs 2010-07-21 11:16:11 +0000
479@@ -0,0 +1,365 @@
480+//
481+// Copyright (C) 2010 Rico Tzschichholz
482+//
483+// This program is free software: you can redistribute it and/or modify
484+// it under the terms of the GNU General Public License as published by
485+// the Free Software Foundation, either version 3 of the License, or
486+// (at your option) any later version.
487+//
488+// This program is distributed in the hope that it will be useful,
489+// but WITHOUT ANY WARRANTY; without even the implied warranty of
490+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
491+// GNU General Public License for more details.
492+//
493+// You should have received a copy of the GNU General Public License
494+// along with this program. If not, see <http://www.gnu.org/licenses/>.
495+//
496+
497+using System;
498+using System.Collections.Generic;
499+using System.Collections.ObjectModel;
500+using System.Linq;
501+using System.Text;
502+
503+using Mono.Unix;
504+
505+using Cairo;
506+using GLib;
507+using Gdk;
508+using Gtk;
509+using Wnck;
510+
511+using Docky.CairoHelper;
512+using Docky.Items;
513+using Docky.Menus;
514+using Docky.Services;
515+
516+namespace WorkspaceSwitcher
517+{
518+ public class WorkspaceSwitcherDockItem : IconDockItem
519+ {
520+ static IPreferences prefs = DockServices.Preferences.Get<WorkspaceSwitcherDockItem> ();
521+
522+ bool? wrapped_scrolling;
523+ bool WrappedScrolling {
524+ get {
525+ if (!wrapped_scrolling.HasValue)
526+ wrapped_scrolling = prefs.Get<bool> ("WrappedScrolling", false);
527+ return wrapped_scrolling.Value;
528+ }
529+ }
530+
531+ public event EventHandler DesksChanged;
532+
533+ List<Desk> Desks = new List<Desk> ();
534+ Desk[,] DeskGrid = null;
535+
536+ bool AreMultipleDesksAvailable {
537+ get {
538+ return Desks.Count () > 1;
539+ }
540+ }
541+
542+ public override bool Square {
543+ get { return false; }
544+ }
545+
546+ public WorkspaceSwitcherDockItem ()
547+ {
548+ HoverText = Catalog.GetString ("Switch Desks");
549+ Icon = "workspace-switcher";
550+
551+ UpdateDesks ();
552+ UpdateItem ();
553+
554+ Wnck.Screen.Default.ActiveWorkspaceChanged += HandleWnckScreenDefaultActiveWorkspaceChanged;;
555+ Wnck.Screen.Default.ViewportsChanged += HandleWnckScreenDefaultViewportsChanged;
556+ Wnck.Screen.Default.WorkspaceCreated += HandleWnckScreenDefaultWorkspaceCreated;
557+ Wnck.Screen.Default.WorkspaceDestroyed += HandleWnckScreenDefaultWorkspaceDestroyed;
558+ }
559+
560+ public override string UniqueID ()
561+ {
562+ return "WorkspaceSwitcher";
563+ }
564+
565+ protected override ClickAnimation OnClicked (uint button, Gdk.ModifierType mod, double xPercent, double yPercent)
566+ {
567+ if (!AreMultipleDesksAvailable || DeskGrid == null)
568+ return ClickAnimation.None;
569+
570+ if (button == 1 && DeskGrid != null && DeskGrid.GetLength (0) > 0 && DeskGrid.GetLength (1) > 0) {
571+ int col = (int) (xPercent * DeskGrid.GetLength (0));
572+ int row = (int) (yPercent * DeskGrid.GetLength (1));
573+ if (DeskGrid [col,row] != null)
574+ DeskGrid [col,row].Activate ();
575+ }
576+
577+ return ClickAnimation.None;
578+ }
579+
580+ protected override void OnScrolled (Gdk.ScrollDirection direction, Gdk.ModifierType mod)
581+ {
582+ if (!AreMultipleDesksAvailable || DeskGrid == null)
583+ return;
584+
585+ switch (direction) {
586+ case ScrollDirection.Down:
587+ if (((mod & ModifierType.ShiftMask) == ModifierType.ShiftMask) || DeskGrid.GetLength (1) == 1)
588+ SwitchDesk (Wnck.MotionDirection.Right);
589+ else
590+ SwitchDesk (Wnck.MotionDirection.Down);
591+ break;
592+ case ScrollDirection.Right:
593+ SwitchDesk (Wnck.MotionDirection.Right);
594+ break;
595+ case ScrollDirection.Up:
596+ if (((mod & ModifierType.ShiftMask) == ModifierType.ShiftMask) || DeskGrid.GetLength (1) == 1)
597+ SwitchDesk (Wnck.MotionDirection.Left);
598+ else
599+ SwitchDesk (Wnck.MotionDirection.Up);
600+ break;
601+ case ScrollDirection.Left:
602+ SwitchDesk (Wnck.MotionDirection.Left);
603+ break;
604+ }
605+ }
606+
607+ protected override MenuList OnGetMenuItems ()
608+ {
609+ MenuList list = new MenuList ();
610+
611+ Desks.ForEach (d => {
612+ Desk desk = d;
613+ list[MenuListContainer.Actions].Add (new Docky.Menus.MenuItem (desk.Name, (desk.IsActive ? "desktop" : ""), (o, a) => desk.Activate ()));
614+ });
615+
616+ return list;
617+ }
618+
619+ bool SwitchDesk (Wnck.MotionDirection direction)
620+ {
621+ Desk activedesk = Desks.Find (desk => desk.IsActive);
622+ Desk nextdesk = activedesk.GetNeighbor (direction);
623+ if (WrappedScrolling) {
624+ // Walk through the columns/rows and jump between [1,1] and [n,m]
625+ Desk tmp = activedesk.GetWrapNeighbor (direction);
626+ if (tmp != null && (nextdesk = tmp.GetNeighbor (Desk.AlternateMovingDirection (direction))) == null)
627+ if ((nextdesk = tmp.GetWrapNeighbor (Desk.AlternateMovingDirection (direction))) == null)
628+ nextdesk = tmp;
629+ }
630+ if (nextdesk != null) {
631+ nextdesk.Activate ();
632+ return true;
633+ }
634+ return false;
635+ }
636+
637+ #region Update Switcher
638+ void UpdateDesks ()
639+ {
640+ lock (Desks)
641+ {
642+ DeskGrid = null;
643+ Desks.ForEach (desk => desk.Dispose());
644+ Desks.Clear ();
645+
646+ string DeskNameFormatString;
647+
648+ if (Wnck.Screen.Default.WorkspaceCount > 1)
649+ DeskNameFormatString = Catalog.GetString ("Desk") + " {0}";
650+ else
651+ DeskNameFormatString = Catalog.GetString ("Virtual Desk") + " {0}";
652+
653+ foreach (Wnck.Workspace workspace in Wnck.Screen.Default.Workspaces) {
654+ if (workspace.IsVirtual) {
655+ int deskWidth = workspace.Screen.Width;
656+ int deskHeight = workspace.Screen.Height;
657+ int rows = workspace.Height / deskHeight;
658+ int columns = workspace.Width / deskWidth;
659+
660+ for (int row = 0; row < rows; row++) {
661+ for (int col = 0; col < columns; col++) {
662+ int desknumber = (int) (columns * row + col + 1);
663+ Gdk.Rectangle area = new Gdk.Rectangle (col * deskWidth, row * deskHeight, deskWidth, deskHeight);
664+
665+ Desk desk = new Desk (string.Format (DeskNameFormatString, desknumber), desknumber, area, workspace);
666+ desk.SetNeighbor (Wnck.MotionDirection.Down, Desks.Find (d => d.Area.X == area.X && (d.Area.Y - deskHeight == area.Y)));
667+ desk.SetNeighbor (Wnck.MotionDirection.Up, Desks.Find (d => d.Area.X == area.X && (d.Area.Y + deskHeight == area.Y)));
668+ desk.SetNeighbor (Wnck.MotionDirection.Right, Desks.Find (d => (d.Area.X - deskWidth == area.X) && d.Area.Y == area.Y));
669+ desk.SetNeighbor (Wnck.MotionDirection.Left, Desks.Find (d => (d.Area.X + deskWidth == area.X) && d.Area.Y == area.Y));
670+ Desks.Add (desk);
671+ }
672+ }
673+ } else {
674+ Desk desk = new Desk (workspace);
675+ desk.SetNeighbor (Wnck.MotionDirection.Down, Desks.Find (d => d.Parent == workspace.GetNeighbor (Wnck.MotionDirection.Down)));
676+ desk.SetNeighbor (Wnck.MotionDirection.Up, Desks.Find (d => d.Parent == workspace.GetNeighbor (Wnck.MotionDirection.Up)));
677+ desk.SetNeighbor (Wnck.MotionDirection.Right, Desks.Find (d => d.Parent == workspace.GetNeighbor (Wnck.MotionDirection.Right)));
678+ desk.SetNeighbor (Wnck.MotionDirection.Left, Desks.Find (d => d.Parent == workspace.GetNeighbor (Wnck.MotionDirection.Left)));
679+ Desks.Add (desk);
680+ }
681+ }
682+
683+ Desk activedesk = Desks.Find (d => d.IsActive);
684+ if (activedesk != null)
685+ DeskGrid = activedesk.GetDeskGridLayout ();
686+ }
687+
688+ if (DesksChanged != null)
689+ DesksChanged (new object (), EventArgs.Empty);
690+ }
691+
692+ void UpdateItem ()
693+ {
694+ Desk activedesk = Desks.Find (desk => desk.IsActive);
695+ if (activedesk != null)
696+ HoverText = activedesk.Name;
697+ else
698+ HoverText = Catalog.GetString ("Switch Desks");
699+ }
700+
701+ #endregion
702+
703+ void HandleWnckScreenDefaultWorkspaceCreated (object o, WorkspaceCreatedArgs args)
704+ {
705+ UpdateDesks ();
706+ UpdateItem ();
707+
708+ QueueRedraw ();
709+ }
710+
711+ void HandleWnckScreenDefaultWorkspaceDestroyed (object o, WorkspaceDestroyedArgs args)
712+ {
713+ UpdateDesks ();
714+ UpdateItem ();
715+
716+ QueueRedraw ();
717+ }
718+
719+ void HandleWnckScreenDefaultActiveWorkspaceChanged (object o, ActiveWorkspaceChangedArgs args)
720+ {
721+ Desk activedesk = Desks.Find (desk => desk.IsActive);
722+ if (activedesk != null && activedesk.Parent != args.PreviousWorkspace)
723+ DeskGrid = activedesk.GetDeskGridLayout ();
724+ UpdateItem ();
725+
726+ QueueRedraw ();
727+ }
728+
729+ void HandleWnckScreenDefaultViewportsChanged (object sender, EventArgs e)
730+ {
731+ UpdateDesks ();
732+ UpdateItem ();
733+
734+ QueueRedraw ();
735+ }
736+
737+ #region Drawing
738+ protected override DockySurface CreateIconBuffer (DockySurface model, int size)
739+ {
740+ if (DeskGrid == null)
741+ return new DockySurface (size, size, model);
742+
743+ int height = size, width = size;
744+
745+ if (Owner != null && Owner.IsOnVerticalDock)
746+ height = Math.Min ((int) (IconSize * 2.5), Math.Max (size, (int) (size * DeskGrid.GetLength (1) * 0.5)));
747+ else
748+ width = Math.Min ((int) (IconSize * 2.5), Math.Max (size, (int) (size * DeskGrid.GetLength (0) * 0.5)));
749+
750+ return new DockySurface (width, height, model);
751+ }
752+
753+ protected override void PaintIconSurface (DockySurface surface)
754+ {
755+ if (DeskGrid == null)
756+ return;
757+
758+ int cols = DeskGrid.GetLength (0);
759+ int rows = DeskGrid.GetLength (1);
760+
761+ Gdk.Color gdkColor = Style.Backgrounds [(int) Gtk.StateType.Selected];
762+ Cairo.Color selection_color = new Cairo.Color ((double) gdkColor.Red / ushort.MaxValue,
763+ (double) gdkColor.Green / ushort.MaxValue,
764+ (double) gdkColor.Blue / ushort.MaxValue,
765+ 0.5);
766+ Context cr = surface.Context;
767+
768+ cr.AlphaPaint ();
769+
770+ LinearGradient lg = new LinearGradient (0, 0, 0, surface.Height);
771+ lg.AddColorStop (0, new Cairo.Color (.35, .35, .35, .6));
772+ lg.AddColorStop (1, new Cairo.Color (.05, .05, .05, .7));
773+
774+ for (int x = 0; x < cols; x++) {
775+ for (int y = 0; y < rows; y++) {
776+ Cairo.Rectangle area = DeskAreaOnIcon (surface.Width, surface.Height, x, y);
777+ cr.Rectangle (area.X, area.Y, area.Width, area.Height);
778+ cr.Pattern = lg;
779+ cr.FillPreserve ();
780+ if (DeskGrid[x,y].IsActive) {
781+ cr.Color = selection_color;
782+ cr.Fill ();
783+ if (area.Width >= 16 && area.Height >= 16) {
784+ using (Gdk.Pixbuf pbuf = DockServices.Drawing.LoadIcon ("desktop", (int) area.Width, (int) area.Height)) {
785+ Gdk.CairoHelper.SetSourcePixbuf (cr, pbuf, (int) area.X + (area.Width - pbuf.Width) / 2, (int) area.Y + (area.Height - pbuf.Height) / 2);
786+ cr.Paint ();
787+ }
788+ }
789+ }
790+ cr.NewPath ();
791+ }
792+ }
793+
794+ lg.Destroy ();
795+
796+ for (int x = 0; x < cols; x++) {
797+ for (int y = 0; y < rows; y++) {
798+ Cairo.Rectangle area = DeskAreaOnIcon (surface.Width, surface.Height, x, y);
799+ cr.Rectangle (area.X, area.Y, area.Width, area.Height);
800+ }
801+ }
802+
803+ lg = new LinearGradient (0, 0, 0, surface.Height);
804+ lg.AddColorStop (0, new Cairo.Color (.95, .95, .95, .7));
805+ lg.AddColorStop (1, new Cairo.Color (.5, .5, .5, .7));
806+ cr.Pattern = lg;
807+ cr.StrokePreserve ();
808+ lg.Destroy ();
809+ }
810+
811+ Cairo.Rectangle DeskAreaOnIcon (int width, int height, int column, int row)
812+ {
813+ double BorderPercent = 0.05;
814+ double Border = height * BorderPercent;
815+ double boxWidth, boxHeight;
816+ Cairo.Rectangle area;
817+
818+ boxWidth = (width - 2 * Border) / DeskGrid.GetLength (0);
819+ boxHeight = (height - 2 * Border) / DeskGrid.GetLength (1);
820+ area = new Cairo.Rectangle (boxWidth * column + Border, boxHeight * row + Border, boxWidth, boxHeight);
821+
822+ return area;
823+ }
824+ #endregion
825+
826+ #region IDisposable implementation
827+ public override void Dispose ()
828+ {
829+ Wnck.Screen.Default.ActiveWorkspaceChanged -= HandleWnckScreenDefaultActiveWorkspaceChanged;
830+ Wnck.Screen.Default.ViewportsChanged -= HandleWnckScreenDefaultViewportsChanged;
831+ Wnck.Screen.Default.WorkspaceCreated -= HandleWnckScreenDefaultWorkspaceCreated;
832+ Wnck.Screen.Default.WorkspaceDestroyed -= HandleWnckScreenDefaultWorkspaceDestroyed;
833+
834+ DeskGrid = null;
835+ Desks.ForEach (desk => desk.Dispose ());
836+ Desks.Clear ();
837+
838+ base.Dispose ();
839+ }
840+
841+ #endregion
842+
843+ }
844+}
845
846=== added file 'StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherItemProvider.cs'
847--- StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherItemProvider.cs 1970-01-01 00:00:00 +0000
848+++ StandardPlugins/WorkspaceSwitcher/src/WorkspaceSwitcherItemProvider.cs 2010-07-21 11:16:11 +0000
849@@ -0,0 +1,45 @@
850+//
851+// Copyright (C) 2010 Rico Tzschichholz
852+//
853+// This program is free software: you can redistribute it and/or modify
854+// it under the terms of the GNU General Public License as published by
855+// the Free Software Foundation, either version 3 of the License, or
856+// (at your option) any later version.
857+//
858+// This program is distributed in the hope that it will be useful,
859+// but WITHOUT ANY WARRANTY; without even the implied warranty of
860+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
861+// GNU General Public License for more details.
862+//
863+// You should have received a copy of the GNU General Public License
864+// along with this program. If not, see <http://www.gnu.org/licenses/>.
865+//
866+
867+using System;
868+using System.Collections.Generic;
869+
870+using Docky.Items;
871+
872+namespace WorkspaceSwitcher
873+{
874+ public class WorkspaceSwitcherItemProvider : AbstractDockItemProvider
875+ {
876+ #region IDockItemProvider implementation
877+
878+ public override string Name {
879+ get {
880+ return "WorkspaceSwitcher";
881+ }
882+ }
883+
884+ #endregion
885+
886+ WorkspaceSwitcherDockItem workspaceswitcher;
887+
888+ public WorkspaceSwitcherItemProvider ()
889+ {
890+ workspaceswitcher = new WorkspaceSwitcherDockItem ();
891+ Items = workspaceswitcher.AsSingle<AbstractDockItem> ();
892+ }
893+ }
894+}
895
896=== modified file 'configure.ac'
897--- configure.ac 2010-07-01 09:18:04 +0000
898+++ configure.ac 2010-07-21 11:16:11 +0000
899@@ -205,6 +205,8 @@
900 StandardPlugins/Trash/Resources/Trash.addin.xml
901 StandardPlugins/Weather/Makefile
902 StandardPlugins/Weather/Resources/Weather.addin.xml
903+StandardPlugins/WorkspaceSwitcher/Makefile
904+StandardPlugins/WorkspaceSwitcher/Resources/WorkspaceSwitcher.addin.xml
905 Makefile
906 data/Makefile
907 data/icons/Makefile

Subscribers

People subscribed via source and target branches

to status/vote changes: