Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 1343 | ||||
Proposed branch: | lp:~ricotz/plank/zoom | ||||
Merge into: | lp:plank | ||||
Diff against target: |
2458 lines (+1232/-386) 13 files modified
data/ui/preferences.ui (+45/-0) docs/Makefile.am (+1/-0) lib/DockController.vala (+0/-2) lib/DockPreferences.vala (+21/-0) lib/DockRenderer.vala (+271/-185) lib/DragManager.vala (+2/-1) lib/Drawing/DockSurface.vala (+21/-0) lib/Drawing/SurfaceCache.vala (+322/-0) lib/Items/DockItem.vala (+59/-40) lib/Makefile.am (+1/-0) lib/PositionManager.vala (+451/-154) lib/Widgets/DockWindow.vala (+5/-4) lib/Widgets/PreferencesWindow.vala (+33/-0) |
||||
To merge this branch: | bzr merge lp:~ricotz/plank/zoom | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Docky Core | Pending | ||
Review via email: mp+262897@code.launchpad.net |
Commit message
Description of the change
Add support to enable a zoom-animation while hovering the dock.
Still needs some cleaning and a more intelligent caching.
Caching icons significantly increases the memory consumption which is suppose to only take effect with enabled zoom.
Might still perform badly on your machine!
(drawing this bloody "libreoffice-
- 1328. By Rico Tzschichholz
-
animatedrenderer: Always initialize frame if a redraw is scheduled
- 1329. By Rico Tzschichholz
-
po: Update translations
- 1330. By Rico Tzschichholz
-
dockrenderer: Guard duration-
calculations which are used for animations - 1331. By Rico Tzschichholz
-
Update symbols
- 1332. By Rico Tzschichholz
-
color: Avoid double setting of out-vars in hsv_to_rgb
- 1333. By Rico Tzschichholz
-
color: Clarify documention of set_min/max_* methods
- 1334. By Rico Tzschichholz
-
hidemanager: Add dodge-active hide-mode
- 1335. By Rico Tzschichholz
-
prefswindow: Use Gtk.Stack if available
- 1337. By Rico Tzschichholz
-
prefswindow: Allow closing the window using "Escape"
- 1338. By Rico Tzschichholz
-
po: Update translations
- 1339. By Rico Tzschichholz
-
ui: Tweak minimum gtk+ version for conditional 3.4 support
- 1340. By Rico Tzschichholz
-
build: Make sure to enable maintainer-mode by default
- 1341. By Rico Tzschichholz
-
Add icon-zoom preferences and expose gui-settings
- 1342. By Rico Tzschichholz
-
Add optional zoom animation when hovering dock-items
- 1343. By Rico Tzschichholz
-
Add ability to cache multiple sizes of drawn items
Preview Diff
1 | === modified file 'data/ui/preferences.ui' | |||
2 | --- data/ui/preferences.ui 2015-07-12 17:08:16 +0000 | |||
3 | +++ data/ui/preferences.ui 2015-07-16 08:37:41 +0000 | |||
4 | @@ -42,6 +42,13 @@ | |||
5 | 42 | <property name="upper">2500</property> | 42 | <property name="upper">2500</property> |
6 | 43 | <property name="step_increment">50</property> | 43 | <property name="step_increment">50</property> |
7 | 44 | </object> | 44 | </object> |
8 | 45 | <object class="GtkAdjustment" id="adj_zoom_percent"> | ||
9 | 46 | <property name="lower">100</property> | ||
10 | 47 | <property name="upper">200</property> | ||
11 | 48 | <property name="value">150</property> | ||
12 | 49 | <property name="step_increment">5</property> | ||
13 | 50 | <property name="page_increment">10</property> | ||
14 | 51 | </object> | ||
15 | 45 | <object class="GtkStack" id="dock_preferences"> | 52 | <object class="GtkStack" id="dock_preferences"> |
16 | 46 | <property name="visible">True</property> | 53 | <property name="visible">True</property> |
17 | 47 | <property name="can_focus">False</property> | 54 | <property name="can_focus">False</property> |
18 | @@ -266,6 +273,44 @@ | |||
19 | 266 | <property name="width">2</property> | 273 | <property name="width">2</property> |
20 | 267 | </packing> | 274 | </packing> |
21 | 268 | </child> | 275 | </child> |
22 | 276 | <child> | ||
23 | 277 | <object class="GtkScale" id="s_zoom_percent"> | ||
24 | 278 | <property name="visible">True</property> | ||
25 | 279 | <property name="can_focus">True</property> | ||
26 | 280 | <property name="adjustment">adj_zoom_percent</property> | ||
27 | 281 | <property name="digits">0</property> | ||
28 | 282 | <property name="value_pos">right</property> | ||
29 | 283 | </object> | ||
30 | 284 | <packing> | ||
31 | 285 | <property name="left_attach">3</property> | ||
32 | 286 | <property name="top_attach">6</property> | ||
33 | 287 | </packing> | ||
34 | 288 | </child> | ||
35 | 289 | <child> | ||
36 | 290 | <object class="GtkSwitch" id="sw_zoom_enabled"> | ||
37 | 291 | <property name="visible">True</property> | ||
38 | 292 | <property name="can_focus">True</property> | ||
39 | 293 | <property name="halign">start</property> | ||
40 | 294 | <property name="valign">center</property> | ||
41 | 295 | </object> | ||
42 | 296 | <packing> | ||
43 | 297 | <property name="left_attach">2</property> | ||
44 | 298 | <property name="top_attach">6</property> | ||
45 | 299 | </packing> | ||
46 | 300 | </child> | ||
47 | 301 | <child> | ||
48 | 302 | <object class="GtkLabel" id="l_iconzoom"> | ||
49 | 303 | <property name="visible">True</property> | ||
50 | 304 | <property name="can_focus">False</property> | ||
51 | 305 | <property name="halign">end</property> | ||
52 | 306 | <property name="label" translatable="yes">Icon Zoom:</property> | ||
53 | 307 | <property name="justify">right</property> | ||
54 | 308 | </object> | ||
55 | 309 | <packing> | ||
56 | 310 | <property name="left_attach">1</property> | ||
57 | 311 | <property name="top_attach">6</property> | ||
58 | 312 | </packing> | ||
59 | 313 | </child> | ||
60 | 269 | </object> | 314 | </object> |
61 | 270 | <packing> | 315 | <packing> |
62 | 271 | <property name="name">grid_appearance</property> | 316 | <property name="name">grid_appearance</property> |
63 | 272 | 317 | ||
64 | === modified file 'docs/Makefile.am' | |||
65 | --- docs/Makefile.am 2015-06-04 20:24:37 +0000 | |||
66 | +++ docs/Makefile.am 2015-07-16 08:37:41 +0000 | |||
67 | @@ -33,6 +33,7 @@ | |||
68 | 33 | $(top_srcdir)/lib/Drawing/DockSurface.vala \ | 33 | $(top_srcdir)/lib/Drawing/DockSurface.vala \ |
69 | 34 | $(top_srcdir)/lib/Drawing/DockTheme.vala \ | 34 | $(top_srcdir)/lib/Drawing/DockTheme.vala \ |
70 | 35 | $(top_srcdir)/lib/Drawing/Easing.vala \ | 35 | $(top_srcdir)/lib/Drawing/Easing.vala \ |
71 | 36 | $(top_srcdir)/lib/Drawing/SurfaceCache.vala \ | ||
72 | 36 | $(top_srcdir)/lib/Drawing/Theme.vala \ | 37 | $(top_srcdir)/lib/Drawing/Theme.vala \ |
73 | 37 | $(top_srcdir)/lib/Factories/AbstractMain.vala \ | 38 | $(top_srcdir)/lib/Factories/AbstractMain.vala \ |
74 | 38 | $(top_srcdir)/lib/Factories/Factory.vala \ | 39 | $(top_srcdir)/lib/Factories/Factory.vala \ |
75 | 39 | 40 | ||
76 | === modified file 'lib/DockController.vala' | |||
77 | --- lib/DockController.vala 2015-06-11 05:36:16 +0000 | |||
78 | +++ lib/DockController.vala 2015-07-16 08:37:41 +0000 | |||
79 | @@ -348,7 +348,6 @@ | |||
80 | 348 | && added.size != removed.size) { | 348 | && added.size != removed.size) { |
81 | 349 | position_manager.update (renderer.theme); | 349 | position_manager.update (renderer.theme); |
82 | 350 | } else { | 350 | } else { |
83 | 351 | position_manager.reset_item_caches (); | ||
84 | 352 | position_manager.update_regions (); | 351 | position_manager.update_regions (); |
85 | 353 | } | 352 | } |
86 | 354 | window.update_icon_regions (); | 353 | window.update_icon_regions (); |
87 | @@ -362,7 +361,6 @@ | |||
88 | 362 | update_visible_elements (); | 361 | update_visible_elements (); |
89 | 363 | 362 | ||
90 | 364 | foreach (unowned DockElement item in moved_items) { | 363 | foreach (unowned DockElement item in moved_items) { |
91 | 365 | position_manager.reset_item_cache (item); | ||
92 | 366 | unowned ApplicationDockItem? app_item = (item as ApplicationDockItem); | 364 | unowned ApplicationDockItem? app_item = (item as ApplicationDockItem); |
93 | 367 | if (app_item != null) | 365 | if (app_item != null) |
94 | 368 | window.update_icon_region (app_item); | 366 | window.update_icon_region (app_item); |
95 | 369 | 367 | ||
96 | === modified file 'lib/DockPreferences.vala' | |||
97 | --- lib/DockPreferences.vala 2015-05-07 12:46:58 +0000 | |||
98 | +++ lib/DockPreferences.vala 2015-07-16 08:37:41 +0000 | |||
99 | @@ -29,6 +29,9 @@ | |||
100 | 29 | public const int MIN_ICON_SIZE = 24; | 29 | public const int MIN_ICON_SIZE = 24; |
101 | 30 | public const int MAX_ICON_SIZE = 128; | 30 | public const int MAX_ICON_SIZE = 128; |
102 | 31 | 31 | ||
103 | 32 | public const int MIN_ICON_ZOOM = 100; | ||
104 | 33 | public const int MAX_ICON_ZOOM = 200; | ||
105 | 34 | |||
106 | 32 | [Description(nick = "current-workspace-only", blurb = "Whether to show only windows of the current workspace.")] | 35 | [Description(nick = "current-workspace-only", blurb = "Whether to show only windows of the current workspace.")] |
107 | 33 | public bool CurrentWorkspaceOnly { get; set; } | 36 | public bool CurrentWorkspaceOnly { get; set; } |
108 | 34 | 37 | ||
109 | @@ -80,6 +83,12 @@ | |||
110 | 80 | [Description(nick = "show-dock-item", blurb = "Whether to show the item for the dock itself.")] | 83 | [Description(nick = "show-dock-item", blurb = "Whether to show the item for the dock itself.")] |
111 | 81 | public bool ShowDockItem { get; set; } | 84 | public bool ShowDockItem { get; set; } |
112 | 82 | 85 | ||
113 | 86 | [Description(nick = "zoom-enabled", blurb = "Whether the dock will zoom when hovered.")] | ||
114 | 87 | public bool ZoomEnabled { get; set; } | ||
115 | 88 | |||
116 | 89 | [Description(nick = "zoom-percent", blurb = "The dock's icon-zoom (in percent).")] | ||
117 | 90 | public uint ZoomPercent { get; set; } | ||
118 | 91 | |||
119 | 83 | /** | 92 | /** |
120 | 84 | * {@inheritDoc} | 93 | * {@inheritDoc} |
121 | 85 | */ | 94 | */ |
122 | @@ -132,6 +141,8 @@ | |||
123 | 132 | PinnedOnly = false; | 141 | PinnedOnly = false; |
124 | 133 | AutoPinning = true; | 142 | AutoPinning = true; |
125 | 134 | ShowDockItem = true; | 143 | ShowDockItem = true; |
126 | 144 | ZoomEnabled = false; | ||
127 | 145 | ZoomPercent = 150; | ||
128 | 135 | } | 146 | } |
129 | 136 | 147 | ||
130 | 137 | /** | 148 | /** |
131 | @@ -235,6 +246,16 @@ | |||
132 | 235 | 246 | ||
133 | 236 | case "ShowDockItem": | 247 | case "ShowDockItem": |
134 | 237 | break; | 248 | break; |
135 | 249 | |||
136 | 250 | case "ZoomEnabled": | ||
137 | 251 | break; | ||
138 | 252 | |||
139 | 253 | case "ZoomPercent": | ||
140 | 254 | if (ZoomPercent < MIN_ICON_ZOOM) | ||
141 | 255 | ZoomPercent = MIN_ICON_ZOOM; | ||
142 | 256 | else if (ZoomPercent > MAX_ICON_ZOOM) | ||
143 | 257 | ZoomPercent = MAX_ICON_ZOOM; | ||
144 | 258 | break; | ||
145 | 238 | } | 259 | } |
146 | 239 | } | 260 | } |
147 | 240 | } | 261 | } |
148 | 241 | 262 | ||
149 | === modified file 'lib/DockRenderer.vala' | |||
150 | --- lib/DockRenderer.vala 2015-07-03 20:25:11 +0000 | |||
151 | +++ lib/DockRenderer.vala 2015-07-16 08:37:41 +0000 | |||
152 | @@ -44,6 +44,18 @@ | |||
153 | 44 | */ | 44 | */ |
154 | 45 | [CCode (notify = false)] | 45 | [CCode (notify = false)] |
155 | 46 | double opacity { get; private set; } | 46 | double opacity { get; private set; } |
156 | 47 | |||
157 | 48 | /** | ||
158 | 49 | * The current progress [0.0..1.0] of the zoom-in-animation of the dock. | ||
159 | 50 | */ | ||
160 | 51 | [CCode (notify = false)] | ||
161 | 52 | public double zoom_in_progress { get; private set; } | ||
162 | 53 | |||
163 | 54 | /** | ||
164 | 55 | * The current local cursor-position on the dock if hovered. | ||
165 | 56 | */ | ||
166 | 57 | [CCode (notify = false)] | ||
167 | 58 | public Gdk.Point local_cursor { get; private set; } | ||
168 | 47 | 59 | ||
169 | 48 | DockSurface? main_buffer = null; | 60 | DockSurface? main_buffer = null; |
170 | 49 | DockSurface? fade_buffer = null; | 61 | DockSurface? fade_buffer = null; |
171 | @@ -57,16 +69,19 @@ | |||
172 | 57 | DockSurface? urgent_glow_buffer = null; | 69 | DockSurface? urgent_glow_buffer = null; |
173 | 58 | 70 | ||
174 | 59 | int64 last_hide = 0; | 71 | int64 last_hide = 0; |
175 | 72 | int64 last_hovered_changed = 0; | ||
176 | 60 | 73 | ||
177 | 61 | bool screen_is_composited = false; | 74 | bool screen_is_composited = false; |
178 | 62 | uint reset_position_manager_timer = 0; | 75 | uint reset_position_manager_timer = 0; |
179 | 63 | int window_scale_factor = 1; | 76 | int window_scale_factor = 1; |
180 | 64 | bool is_first_frame = true; | 77 | bool is_first_frame = true; |
181 | 78 | bool zoom_changed = false; | ||
182 | 65 | 79 | ||
183 | 66 | ulong gtk_theme_name_changed_id = 0; | 80 | ulong gtk_theme_name_changed_id = 0; |
184 | 67 | 81 | ||
185 | 68 | double dynamic_animation_offset = 0.0; | 82 | double dynamic_animation_offset = 0.0; |
186 | 69 | 83 | ||
187 | 84 | Gee.ArrayList<unowned DockItem> current_items; | ||
188 | 70 | Gee.HashSet<DockItem> transient_items; | 85 | Gee.HashSet<DockItem> transient_items; |
189 | 71 | #if BENCHMARK | 86 | #if BENCHMARK |
190 | 72 | Gee.ArrayList<string> benchmark; | 87 | Gee.ArrayList<string> benchmark; |
191 | @@ -86,6 +101,7 @@ | |||
192 | 86 | construct | 101 | construct |
193 | 87 | { | 102 | { |
194 | 88 | transient_items = new Gee.HashSet<DockItem> (); | 103 | transient_items = new Gee.HashSet<DockItem> (); |
195 | 104 | current_items = new Gee.ArrayList<unowned DockItem> (); | ||
196 | 89 | #if BENCHMARK | 105 | #if BENCHMARK |
197 | 90 | benchmark = new Gee.ArrayList<string> (); | 106 | benchmark = new Gee.ArrayList<string> (); |
198 | 91 | #endif | 107 | #endif |
199 | @@ -104,6 +120,7 @@ | |||
200 | 104 | 120 | ||
201 | 105 | controller.window.notify["HoveredItem"].connect (animated_draw); | 121 | controller.window.notify["HoveredItem"].connect (animated_draw); |
202 | 106 | controller.hide_manager.notify["Hidden"].connect (hidden_changed); | 122 | controller.hide_manager.notify["Hidden"].connect (hidden_changed); |
203 | 123 | controller.hide_manager.notify["Hovered"].connect (hovered_changed); | ||
204 | 107 | } | 124 | } |
205 | 108 | 125 | ||
206 | 109 | ~DockRenderer () | 126 | ~DockRenderer () |
207 | @@ -112,6 +129,7 @@ | |||
208 | 112 | theme.notify.disconnect (theme_changed); | 129 | theme.notify.disconnect (theme_changed); |
209 | 113 | 130 | ||
210 | 114 | controller.hide_manager.notify["Hidden"].disconnect (hidden_changed); | 131 | controller.hide_manager.notify["Hidden"].disconnect (hidden_changed); |
211 | 132 | controller.hide_manager.notify["Hovered"].disconnect (hovered_changed); | ||
212 | 115 | controller.window.notify["HoveredItem"].disconnect (animated_draw); | 133 | controller.window.notify["HoveredItem"].disconnect (animated_draw); |
213 | 116 | } | 134 | } |
214 | 117 | 135 | ||
215 | @@ -221,7 +239,9 @@ | |||
216 | 221 | { | 239 | { |
217 | 222 | return_if_fail (theme != null); | 240 | return_if_fail (theme != null); |
218 | 223 | 241 | ||
220 | 224 | screen_is_composited = controller.position_manager.screen_is_composited; | 242 | unowned PositionManager position_manager = controller.position_manager; |
221 | 243 | |||
222 | 244 | screen_is_composited = position_manager.screen_is_composited; | ||
223 | 225 | dynamic_animation_offset = 0.0; | 245 | dynamic_animation_offset = 0.0; |
224 | 226 | 246 | ||
225 | 227 | var fade_opacity = theme.FadeOpacity; | 247 | var fade_opacity = theme.FadeOpacity; |
226 | @@ -237,14 +257,78 @@ | |||
227 | 237 | } else { | 257 | } else { |
228 | 238 | hide_progress = (controller.hide_manager.Hidden ? 1.0 : 0.0); | 258 | hide_progress = (controller.hide_manager.Hidden ? 1.0 : 0.0); |
229 | 239 | } | 259 | } |
230 | 260 | |||
231 | 261 | var zoom_duration = 150 * 1000; | ||
232 | 262 | var zoom_time = int64.max (0LL, frame_time - last_hovered_changed); | ||
233 | 263 | double zoom_progress; | ||
234 | 264 | if (zoom_time < zoom_duration) | ||
235 | 265 | zoom_progress = Drawing.easing_for_mode (AnimationMode.LINEAR, zoom_time, zoom_duration); | ||
236 | 266 | else | ||
237 | 267 | zoom_progress = 1.0; | ||
238 | 268 | if (!controller.hide_manager.Hovered) | ||
239 | 269 | zoom_progress = 1.0 - zoom_progress; | ||
240 | 270 | zoom_progress *= 1.0 - hide_progress; | ||
241 | 271 | zoom_in_progress = zoom_progress; | ||
242 | 240 | } else { | 272 | } else { |
243 | 241 | hide_progress = 0.0; | 273 | hide_progress = 0.0; |
244 | 274 | zoom_in_progress = 0.0; | ||
245 | 242 | } | 275 | } |
246 | 243 | 276 | ||
247 | 244 | if (fade_opacity < 1.0) | 277 | if (fade_opacity < 1.0) |
248 | 245 | opacity = 1.0 - (1.0 - fade_opacity) * hide_progress; | 278 | opacity = 1.0 - (1.0 - fade_opacity) * hide_progress; |
249 | 246 | else | 279 | else |
250 | 247 | opacity = 1.0; | 280 | opacity = 1.0; |
251 | 281 | |||
252 | 282 | // Update *ordered* list of items | ||
253 | 283 | current_items.clear (); | ||
254 | 284 | current_items.add_all (controller.VisibleItems); | ||
255 | 285 | |||
256 | 286 | if (screen_is_composited) { | ||
257 | 287 | var add_time = 0LL; | ||
258 | 288 | var remove_time = 0LL; | ||
259 | 289 | var move_time = 0LL; | ||
260 | 290 | var move_duration = theme.ItemMoveTime * 1000; | ||
261 | 291 | |||
262 | 292 | var transient_items_it = transient_items.iterator (); | ||
263 | 293 | while (transient_items_it.next ()) { | ||
264 | 294 | var item = transient_items_it.get (); | ||
265 | 295 | add_time = item.AddTime; | ||
266 | 296 | remove_time = item.RemoveTime; | ||
267 | 297 | |||
268 | 298 | if (add_time > remove_time) { | ||
269 | 299 | move_time = frame_time - add_time; | ||
270 | 300 | if (move_time < move_duration) { | ||
271 | 301 | if (!current_items.contains (item)) | ||
272 | 302 | current_items.add (item); | ||
273 | 303 | } else { | ||
274 | 304 | transient_items_it.remove (); | ||
275 | 305 | } | ||
276 | 306 | } else if (remove_time > 0) { | ||
277 | 307 | move_time = frame_time - remove_time; | ||
278 | 308 | if (move_time < move_duration) { | ||
279 | 309 | if (!current_items.contains (item)) | ||
280 | 310 | current_items.add (item); | ||
281 | 311 | } else { | ||
282 | 312 | transient_items_it.remove (); | ||
283 | 313 | } | ||
284 | 314 | } | ||
285 | 315 | } | ||
286 | 316 | } else { | ||
287 | 317 | transient_items.clear (); | ||
288 | 318 | } | ||
289 | 319 | |||
290 | 320 | #if HAVE_GEE_0_8 | ||
291 | 321 | current_items.sort ((CompareDataFunc) compare_dock_item_position); | ||
292 | 322 | #else | ||
293 | 323 | current_items.sort ((CompareFunc) compare_dock_item_position); | ||
294 | 324 | #endif | ||
295 | 325 | |||
296 | 326 | // Calculate positions for given ordered list of items | ||
297 | 327 | position_manager.update_draw_values (current_items, | ||
298 | 328 | (PositionManager.DockItemDrawValueFunc) animate_draw_value_for_item, | ||
299 | 329 | (PositionManager.DrawValuesFunc) post_process_draw_values); | ||
300 | 330 | |||
301 | 331 | background_rect = position_manager.get_background_region (); | ||
302 | 248 | } | 332 | } |
303 | 249 | 333 | ||
304 | 250 | /** | 334 | /** |
305 | @@ -262,7 +346,6 @@ | |||
306 | 262 | unowned PositionManager position_manager = controller.position_manager; | 346 | unowned PositionManager position_manager = controller.position_manager; |
307 | 263 | unowned DockItem dragged_item = controller.drag_manager.DragItem; | 347 | unowned DockItem dragged_item = controller.drag_manager.DragItem; |
308 | 264 | var win_rect = position_manager.get_dock_window_region (); | 348 | var win_rect = position_manager.get_dock_window_region (); |
309 | 265 | var items = controller.VisibleItems; | ||
310 | 266 | 349 | ||
311 | 267 | if (main_buffer == null) { | 350 | if (main_buffer == null) { |
312 | 268 | main_buffer = new DockSurface.with_surface (win_rect.width, win_rect.height, cr.get_target ()); | 351 | main_buffer = new DockSurface.with_surface (win_rect.width, win_rect.height, cr.get_target ()); |
313 | @@ -295,7 +378,7 @@ | |||
314 | 295 | cr.paint (); | 378 | cr.paint (); |
315 | 296 | cr.restore (); | 379 | cr.restore (); |
316 | 297 | 380 | ||
318 | 298 | foreach (var item in items) | 381 | foreach (unowned DockItem item in current_items) |
319 | 299 | draw_urgent_glow (item, cr, frame_time); | 382 | draw_urgent_glow (item, cr, frame_time); |
320 | 300 | 383 | ||
321 | 301 | return; | 384 | return; |
322 | @@ -320,118 +403,11 @@ | |||
323 | 320 | unowned Cairo.Context item_cr = item_buffer.Context; | 403 | unowned Cairo.Context item_cr = item_buffer.Context; |
324 | 321 | unowned Cairo.Context shadow_cr = shadow_buffer.Context; | 404 | unowned Cairo.Context shadow_cr = shadow_buffer.Context; |
325 | 322 | 405 | ||
326 | 323 | // draw transient items onto the dock buffer and calculate the resulting | ||
327 | 324 | // dynamic-animation-offset used to animate the background-resize | ||
328 | 325 | if (screen_is_composited) { | ||
329 | 326 | var add_time = 0LL; | ||
330 | 327 | var remove_time = 0LL; | ||
331 | 328 | var move_time = 0LL; | ||
332 | 329 | var move_duration = theme.ItemMoveTime * 1000; | ||
333 | 330 | |||
334 | 331 | var transient_items_it = transient_items.iterator (); | ||
335 | 332 | while (transient_items_it.next ()) { | ||
336 | 333 | var item = transient_items_it.get (); | ||
337 | 334 | add_time = item.AddTime; | ||
338 | 335 | remove_time = item.RemoveTime; | ||
339 | 336 | |||
340 | 337 | if (add_time > remove_time) { | ||
341 | 338 | move_time = int64.max (0LL, frame_time - add_time); | ||
342 | 339 | if (move_time < move_duration) { | ||
343 | 340 | var move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_QUINT, move_time, move_duration); | ||
344 | 341 | dynamic_animation_offset -= move_animation_progress * (position_manager.IconSize + position_manager.ItemPadding); | ||
345 | 342 | } else { | ||
346 | 343 | transient_items_it.remove (); | ||
347 | 344 | } | ||
348 | 345 | } else if (remove_time > 0) { | ||
349 | 346 | move_time = int64.max (0LL, frame_time - remove_time); | ||
350 | 347 | if (move_time < move_duration) { | ||
351 | 348 | var move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_IN_QUINT, move_time, move_duration); | ||
352 | 349 | dynamic_animation_offset += move_animation_progress * (position_manager.IconSize + position_manager.ItemPadding); | ||
353 | 350 | } else { | ||
354 | 351 | transient_items_it.remove (); | ||
355 | 352 | } | ||
356 | 353 | } else { | ||
357 | 354 | continue; | ||
358 | 355 | } | ||
359 | 356 | #if BENCHMARK | ||
360 | 357 | start2 = new DateTime.now_local (); | ||
361 | 358 | #endif | ||
362 | 359 | // Do not draw the currently dragged item or items which are suppose to be drawn later | ||
363 | 360 | if (move_time < move_duration && item.IsVisible && dragged_item != item && !items.contains (item)) { | ||
364 | 361 | var draw_value = get_animated_draw_value_for_item (item, frame_time); | ||
365 | 362 | draw_item (item_cr, item, ref draw_value, frame_time); | ||
366 | 363 | draw_item_shadow (shadow_cr, item, ref draw_value); | ||
367 | 364 | } | ||
368 | 365 | #if BENCHMARK | ||
369 | 366 | end2 = new DateTime.now_local (); | ||
370 | 367 | benchmark.add ("item render time - %f ms".printf (end2.difference (start2) / 1000.0)); | ||
371 | 368 | #endif | ||
372 | 369 | } | ||
373 | 370 | } else { | ||
374 | 371 | transient_items.clear (); | ||
375 | 372 | } | ||
376 | 373 | |||
377 | 374 | background_rect = position_manager.get_background_region (); | ||
378 | 375 | |||
379 | 376 | // calculate drawing offset | 406 | // calculate drawing offset |
380 | 377 | var x_offset = 0, y_offset = 0; | 407 | var x_offset = 0, y_offset = 0; |
381 | 378 | if (opacity == 1.0) | 408 | if (opacity == 1.0) |
382 | 379 | position_manager.get_dock_draw_position (out x_offset, out y_offset); | 409 | position_manager.get_dock_draw_position (out x_offset, out y_offset); |
383 | 380 | 410 | ||
384 | 381 | // calculate drawing animation-offset | ||
385 | 382 | var x_animation_offset = 0, y_animation_offset = 0; | ||
386 | 383 | switch (controller.prefs.Alignment) { | ||
387 | 384 | default: | ||
388 | 385 | case Gtk.Align.CENTER: | ||
389 | 386 | if (position_manager.is_horizontal_dock ()) | ||
390 | 387 | x_animation_offset -= (int) Math.round (dynamic_animation_offset / 2.0); | ||
391 | 388 | else | ||
392 | 389 | y_animation_offset -= (int) Math.round (dynamic_animation_offset / 2.0); | ||
393 | 390 | background_rect = { background_rect.x + x_offset + x_animation_offset, background_rect.y + y_offset + y_animation_offset, | ||
394 | 391 | background_rect.width -2 * x_animation_offset, background_rect.height -2 * y_animation_offset }; | ||
395 | 392 | break; | ||
396 | 393 | case Gtk.Align.START: | ||
397 | 394 | if (position_manager.is_horizontal_dock ()) | ||
398 | 395 | background_rect = { background_rect.x + x_offset, background_rect.y + y_offset, | ||
399 | 396 | background_rect.width + (int) Math.round (dynamic_animation_offset), background_rect.height }; | ||
400 | 397 | else | ||
401 | 398 | background_rect = { background_rect.x + x_offset, background_rect.y + y_offset, | ||
402 | 399 | background_rect.width, background_rect.height + (int) Math.round (dynamic_animation_offset) }; | ||
403 | 400 | break; | ||
404 | 401 | case Gtk.Align.END: | ||
405 | 402 | if (position_manager.is_horizontal_dock ()) | ||
406 | 403 | x_animation_offset -= (int) Math.round (dynamic_animation_offset); | ||
407 | 404 | else | ||
408 | 405 | y_animation_offset -= (int) Math.round (dynamic_animation_offset); | ||
409 | 406 | background_rect = { background_rect.x + x_offset + x_animation_offset, background_rect.y + y_offset + y_animation_offset, | ||
410 | 407 | background_rect.width - x_animation_offset, background_rect.height - y_animation_offset }; | ||
411 | 408 | break; | ||
412 | 409 | case Gtk.Align.FILL: | ||
413 | 410 | switch (controller.prefs.ItemsAlignment) { | ||
414 | 411 | default: | ||
415 | 412 | case Gtk.Align.FILL: | ||
416 | 413 | case Gtk.Align.CENTER: | ||
417 | 414 | if (position_manager.is_horizontal_dock ()) | ||
418 | 415 | x_animation_offset -= (int) Math.round (dynamic_animation_offset / 2.0); | ||
419 | 416 | else | ||
420 | 417 | y_animation_offset -= (int) Math.round (dynamic_animation_offset / 2.0); | ||
421 | 418 | break; | ||
422 | 419 | case Gtk.Align.START: | ||
423 | 420 | break; | ||
424 | 421 | case Gtk.Align.END: | ||
425 | 422 | if (position_manager.is_horizontal_dock ()) | ||
426 | 423 | x_animation_offset -= (int) Math.round (dynamic_animation_offset); | ||
427 | 424 | else | ||
428 | 425 | y_animation_offset -= (int) Math.round (dynamic_animation_offset); | ||
429 | 426 | break; | ||
430 | 427 | } | ||
431 | 428 | background_rect = { background_rect.x + x_offset, background_rect.y + y_offset, background_rect.width, background_rect.height }; | ||
432 | 429 | break; | ||
433 | 430 | } | ||
434 | 431 | |||
435 | 432 | x_offset += x_animation_offset; | ||
436 | 433 | y_offset += y_animation_offset; | ||
437 | 434 | |||
438 | 435 | // composite dock layers and make sure to draw onto the window's context with one operation | 411 | // composite dock layers and make sure to draw onto the window's context with one operation |
439 | 436 | main_buffer.clear (); | 412 | main_buffer.clear (); |
440 | 437 | unowned Cairo.Context main_cr = main_buffer.Context; | 413 | unowned Cairo.Context main_cr = main_buffer.Context; |
441 | @@ -441,22 +417,22 @@ | |||
442 | 441 | start2 = new DateTime.now_local (); | 417 | start2 = new DateTime.now_local (); |
443 | 442 | #endif | 418 | #endif |
444 | 443 | // draw background-layer | 419 | // draw background-layer |
446 | 444 | draw_dock_background (main_cr, background_rect); | 420 | draw_dock_background (main_cr, background_rect, x_offset, y_offset); |
447 | 445 | #if BENCHMARK | 421 | #if BENCHMARK |
448 | 446 | end2 = new DateTime.now_local (); | 422 | end2 = new DateTime.now_local (); |
449 | 447 | benchmark.add ("background render time - %f ms".printf (end2.difference (start2) / 1000.0)); | 423 | benchmark.add ("background render time - %f ms".printf (end2.difference (start2) / 1000.0)); |
450 | 448 | #endif | 424 | #endif |
451 | 449 | 425 | ||
452 | 450 | // draw each item onto the dock buffer | 426 | // draw each item onto the dock buffer |
454 | 451 | foreach (var item in items) { | 427 | foreach (unowned DockItem item in current_items) { |
455 | 452 | #if BENCHMARK | 428 | #if BENCHMARK |
456 | 453 | start2 = new DateTime.now_local (); | 429 | start2 = new DateTime.now_local (); |
457 | 454 | #endif | 430 | #endif |
458 | 455 | // Do not draw the currently dragged item | 431 | // Do not draw the currently dragged item |
459 | 456 | if (item.IsVisible && dragged_item != item) { | 432 | if (item.IsVisible && dragged_item != item) { |
463 | 457 | var draw_value = get_animated_draw_value_for_item (item, frame_time); | 433 | var draw_value = position_manager.get_draw_value_for_item (item); |
464 | 458 | draw_item (item_cr, item, ref draw_value, frame_time); | 434 | draw_item (item_cr, item, draw_value, frame_time); |
465 | 459 | draw_item_shadow (shadow_cr, item, ref draw_value); | 435 | draw_item_shadow (shadow_cr, item, draw_value); |
466 | 460 | } | 436 | } |
467 | 461 | #if BENCHMARK | 437 | #if BENCHMARK |
468 | 462 | end2 = new DateTime.now_local (); | 438 | end2 = new DateTime.now_local (); |
469 | @@ -489,7 +465,7 @@ | |||
470 | 489 | 465 | ||
471 | 490 | // draw urgent-glow if dock is completely hidden | 466 | // draw urgent-glow if dock is completely hidden |
472 | 491 | if (hide_progress == 1.0) { | 467 | if (hide_progress == 1.0) { |
474 | 492 | foreach (var item in items) | 468 | foreach (unowned DockItem item in current_items) |
475 | 493 | draw_urgent_glow (item, cr, frame_time); | 469 | draw_urgent_glow (item, cr, frame_time); |
476 | 494 | } | 470 | } |
477 | 495 | 471 | ||
478 | @@ -520,7 +496,7 @@ | |||
479 | 520 | } | 496 | } |
480 | 521 | } | 497 | } |
481 | 522 | 498 | ||
483 | 523 | void draw_dock_background (Cairo.Context cr, Gdk.Rectangle background_rect) | 499 | void draw_dock_background (Cairo.Context cr, Gdk.Rectangle background_rect, int x_offset, int y_offset) |
484 | 524 | { | 500 | { |
485 | 525 | unowned PositionManager position_manager = controller.position_manager; | 501 | unowned PositionManager position_manager = controller.position_manager; |
486 | 526 | 502 | ||
487 | @@ -534,21 +510,20 @@ | |||
488 | 534 | background_buffer = theme.create_background (background_rect.width, background_rect.height, | 510 | background_buffer = theme.create_background (background_rect.width, background_rect.height, |
489 | 535 | position_manager.Position, main_buffer); | 511 | position_manager.Position, main_buffer); |
490 | 536 | 512 | ||
492 | 537 | cr.set_source_surface (background_buffer.Internal, background_rect.x, background_rect.y); | 513 | cr.set_source_surface (background_buffer.Internal, background_rect.x + x_offset, background_rect.y + y_offset); |
493 | 538 | cr.paint (); | 514 | cr.paint (); |
494 | 539 | } | 515 | } |
495 | 540 | 516 | ||
497 | 541 | PositionManager.DockItemDrawValue get_animated_draw_value_for_item (DockItem item, int64 frame_time) | 517 | [CCode (instance_pos = -1)] |
498 | 518 | void animate_draw_value_for_item (DockItem item, PositionManager.DockItemDrawValue draw_value) | ||
499 | 542 | { | 519 | { |
500 | 543 | unowned PositionManager position_manager = controller.position_manager; | 520 | unowned PositionManager position_manager = controller.position_manager; |
501 | 544 | unowned DockItem hovered_item = controller.window.HoveredItem; | 521 | unowned DockItem hovered_item = controller.window.HoveredItem; |
502 | 545 | unowned DragManager drag_manager = controller.drag_manager; | 522 | unowned DragManager drag_manager = controller.drag_manager; |
503 | 546 | 523 | ||
505 | 547 | var icon_size = position_manager.IconSize; | 524 | var icon_size = (int) draw_value.icon_size; |
506 | 548 | var position = position_manager.Position; | 525 | var position = position_manager.Position; |
510 | 549 | 526 | var x_offset = 0.0, y_offset = 0.0; | |
508 | 550 | // get item's draw-value | ||
509 | 551 | var draw_value = position_manager.get_draw_value_for_item (item); | ||
511 | 552 | 527 | ||
512 | 553 | // check for and calculate click-animation | 528 | // check for and calculate click-animation |
513 | 554 | var max_click_time = item.ClickedAnimation == Animation.BOUNCE ? theme.LaunchBounceTime : theme.ClickTime; | 529 | var max_click_time = item.ClickedAnimation == Animation.BOUNCE ? theme.LaunchBounceTime : theme.ClickTime; |
514 | @@ -564,8 +539,7 @@ | |||
515 | 564 | case Animation.BOUNCE: | 539 | case Animation.BOUNCE: |
516 | 565 | if (!screen_is_composited) | 540 | if (!screen_is_composited) |
517 | 566 | break; | 541 | break; |
520 | 567 | var change = Math.fabs (Math.sin (2 * Math.PI * click_animation_progress) * position_manager.LaunchBounceHeight * double.min (1.0, 1.3333 * (1.0 - click_animation_progress))); | 542 | y_offset += Math.fabs (Math.sin (2 * Math.PI * click_animation_progress) * position_manager.LaunchBounceHeight * double.min (1.0, 1.3333 * (1.0 - click_animation_progress))); |
519 | 568 | draw_value.move_in (position, change); | ||
521 | 569 | break; | 543 | break; |
522 | 570 | case Animation.DARKEN: | 544 | case Animation.DARKEN: |
523 | 571 | draw_value.darken = double.max (0, Math.sin (Math.PI * click_animation_progress)) * 0.5; | 545 | draw_value.darken = double.max (0, Math.sin (Math.PI * click_animation_progress)) * 0.5; |
524 | @@ -630,8 +604,40 @@ | |||
525 | 630 | var urgent_time = int64.max (0LL, frame_time - item.LastUrgent); | 604 | var urgent_time = int64.max (0LL, frame_time - item.LastUrgent); |
526 | 631 | var bounce_animation_progress = urgent_time / (double) (theme.UrgentBounceTime * 1000); | 605 | var bounce_animation_progress = urgent_time / (double) (theme.UrgentBounceTime * 1000); |
527 | 632 | if (bounce_animation_progress < 1.0) { | 606 | if (bounce_animation_progress < 1.0) { |
530 | 633 | var change = Math.fabs (Math.sin (Math.PI * bounce_animation_progress) * position_manager.UrgentBounceHeight * double.min (1.0, 2.0 * (1.0 - bounce_animation_progress))); | 607 | y_offset += Math.fabs (Math.sin (Math.PI * bounce_animation_progress) * position_manager.UrgentBounceHeight * double.min (1.0, 2.0 * (1.0 - bounce_animation_progress))); |
531 | 634 | draw_value.move_in (position, change); | 608 | } |
532 | 609 | } | ||
533 | 610 | |||
534 | 611 | // animate addition/removal | ||
535 | 612 | unowned DockContainer? container = item.Container; | ||
536 | 613 | var allow_animation = (screen_is_composited && (container == null || container.AddTime < item.AddTime)); | ||
537 | 614 | if (allow_animation && item.AddTime > item.RemoveTime) { | ||
538 | 615 | var move_duration = theme.ItemMoveTime * 1000; | ||
539 | 616 | var move_time = int64.max (0LL, frame_time - item.AddTime); | ||
540 | 617 | if (move_time < move_duration) { | ||
541 | 618 | var move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.LINEAR, move_time, move_duration); | ||
542 | 619 | draw_value.opacity = Drawing.easing_for_mode (AnimationMode.EASE_IN_EXPO, move_time, move_duration); | ||
543 | 620 | y_offset -= move_animation_progress * (icon_size + position_manager.BottomPadding); | ||
544 | 621 | draw_value.show_indicator = false; | ||
545 | 622 | |||
546 | 623 | // calculate the resulting incremental dynamic-animation-offset used to animate the background-resize and icon-offset | ||
547 | 624 | move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_QUINT, move_time, move_duration); | ||
548 | 625 | dynamic_animation_offset -= move_animation_progress * (icon_size + position_manager.ItemPadding); | ||
549 | 626 | x_offset += dynamic_animation_offset; | ||
550 | 627 | } | ||
551 | 628 | } else if (allow_animation && item.RemoveTime > 0) { | ||
552 | 629 | var move_duration = theme.ItemMoveTime * 1000; | ||
553 | 630 | var move_time = int64.max (0LL, frame_time - item.RemoveTime); | ||
554 | 631 | if (move_time < move_duration) { | ||
555 | 632 | var move_animation_progress = Drawing.easing_for_mode (AnimationMode.LINEAR, move_time, move_duration); | ||
556 | 633 | draw_value.opacity = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_EXPO, move_time, move_duration); | ||
557 | 634 | y_offset -= move_animation_progress * (icon_size + position_manager.BottomPadding); | ||
558 | 635 | draw_value.show_indicator = false; | ||
559 | 636 | |||
560 | 637 | // calculate the resulting incremental dynamic-animation-offset used to animate the background-resize and icon-offset | ||
561 | 638 | move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_IN_QUINT, move_time, move_duration); | ||
562 | 639 | dynamic_animation_offset += move_animation_progress * (icon_size + position_manager.ItemPadding); | ||
563 | 640 | x_offset += dynamic_animation_offset - (icon_size + position_manager.ItemPadding); | ||
564 | 635 | } | 641 | } |
565 | 636 | } | 642 | } |
566 | 637 | 643 | ||
567 | @@ -650,37 +656,12 @@ | |||
568 | 650 | move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_CIRC, move_time, move_duration); | 656 | move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_CIRC, move_time, move_duration); |
569 | 651 | } | 657 | } |
570 | 652 | var change = move_animation_progress * (icon_size + position_manager.ItemPadding); | 658 | var change = move_animation_progress * (icon_size + position_manager.ItemPadding); |
572 | 653 | draw_value.move_right (position, (item.Position < item.LastPosition ? change : -change)); | 659 | x_offset += (item.Position < item.LastPosition ? change : -change); |
573 | 654 | } else { | 660 | } else { |
574 | 655 | item.unset_move_state (); | 661 | item.unset_move_state (); |
575 | 656 | } | 662 | } |
576 | 657 | } | 663 | } |
577 | 658 | 664 | ||
578 | 659 | // animate addition/removal | ||
579 | 660 | unowned DockContainer? container = item.Container; | ||
580 | 661 | var allow_animation = (screen_is_composited && (container == null || container.AddTime < item.AddTime)); | ||
581 | 662 | if (allow_animation && item.AddTime > item.RemoveTime) { | ||
582 | 663 | var move_duration = theme.ItemMoveTime * 1000; | ||
583 | 664 | var move_time = int64.max (0LL, frame_time - item.AddTime); | ||
584 | 665 | if (move_time < move_duration) { | ||
585 | 666 | var move_animation_progress = 1.0 - Drawing.easing_for_mode (AnimationMode.LINEAR, move_time, move_duration); | ||
586 | 667 | draw_value.opacity = Drawing.easing_for_mode (AnimationMode.EASE_IN_EXPO, move_time, move_duration); | ||
587 | 668 | var change = move_animation_progress * (icon_size + position_manager.BottomPadding); | ||
588 | 669 | draw_value.move_in (position, -change); | ||
589 | 670 | draw_value.show_indicator = false; | ||
590 | 671 | } | ||
591 | 672 | } else if (allow_animation && item.RemoveTime > 0) { | ||
592 | 673 | var move_duration = theme.ItemMoveTime * 1000; | ||
593 | 674 | var move_time = int64.max (0LL, frame_time - item.RemoveTime); | ||
594 | 675 | if (move_time < move_duration) { | ||
595 | 676 | var move_animation_progress = Drawing.easing_for_mode (AnimationMode.LINEAR, move_time, move_duration); | ||
596 | 677 | draw_value.opacity = 1.0 - Drawing.easing_for_mode (AnimationMode.EASE_OUT_EXPO, move_time, move_duration); | ||
597 | 678 | var change = move_animation_progress * (icon_size + position_manager.BottomPadding); | ||
598 | 679 | draw_value.move_in (position, -change); | ||
599 | 680 | draw_value.show_indicator = false; | ||
600 | 681 | } | ||
601 | 682 | } | ||
602 | 683 | |||
603 | 684 | // animate icon on invalid state | 665 | // animate icon on invalid state |
604 | 685 | if ((item.State & ItemState.INVALID) != 0) { | 666 | if ((item.State & ItemState.INVALID) != 0) { |
605 | 686 | var invalid_duration = 3000 * 1000; | 667 | var invalid_duration = 3000 * 1000; |
606 | @@ -692,13 +673,71 @@ | |||
607 | 692 | } | 673 | } |
608 | 693 | } | 674 | } |
609 | 694 | 675 | ||
617 | 695 | return draw_value; | 676 | if (x_offset != 0.0) |
618 | 696 | } | 677 | draw_value.move_right (position, x_offset); |
619 | 697 | 678 | ||
620 | 698 | void draw_item (Cairo.Context cr, DockItem item, ref PositionManager.DockItemDrawValue draw_value, int64 frame_time) | 679 | if (y_offset != 0.0) |
621 | 699 | { | 680 | draw_value.move_in (position, y_offset); |
622 | 700 | unowned PositionManager position_manager = controller.position_manager; | 681 | } |
623 | 701 | var icon_size = position_manager.IconSize; | 682 | |
624 | 683 | [CCode (instance_pos = -1)] | ||
625 | 684 | void post_process_draw_values (Gee.HashMap<DockElement, PositionManager.DockItemDrawValue?> draw_values) | ||
626 | 685 | { | ||
627 | 686 | if (dynamic_animation_offset == 0.0) | ||
628 | 687 | return; | ||
629 | 688 | |||
630 | 689 | unowned PositionManager position_manager = controller.position_manager; | ||
631 | 690 | var position = position_manager.Position; | ||
632 | 691 | |||
633 | 692 | var x_offset = 0.0; | ||
634 | 693 | |||
635 | 694 | switch (position_manager.Alignment) { | ||
636 | 695 | default: | ||
637 | 696 | case Gtk.Align.CENTER: | ||
638 | 697 | x_offset -= Math.round (dynamic_animation_offset / 2.0); | ||
639 | 698 | break; | ||
640 | 699 | case Gtk.Align.START: | ||
641 | 700 | break; | ||
642 | 701 | case Gtk.Align.END: | ||
643 | 702 | x_offset -= Math.round (dynamic_animation_offset); | ||
644 | 703 | break; | ||
645 | 704 | case Gtk.Align.FILL: | ||
646 | 705 | switch (position_manager.ItemsAlignment) { | ||
647 | 706 | default: | ||
648 | 707 | case Gtk.Align.FILL: | ||
649 | 708 | case Gtk.Align.CENTER: | ||
650 | 709 | x_offset -= Math.round (dynamic_animation_offset / 2.0); | ||
651 | 710 | break; | ||
652 | 711 | case Gtk.Align.START: | ||
653 | 712 | break; | ||
654 | 713 | case Gtk.Align.END: | ||
655 | 714 | x_offset -= Math.round (dynamic_animation_offset); | ||
656 | 715 | break; | ||
657 | 716 | } | ||
658 | 717 | break; | ||
659 | 718 | } | ||
660 | 719 | |||
661 | 720 | if (x_offset == 0.0) | ||
662 | 721 | return; | ||
663 | 722 | |||
664 | 723 | #if HAVE_GEE_0_8 | ||
665 | 724 | draw_values.map_iterator ().foreach ((i, val) => { | ||
666 | 725 | val.move_right (position, x_offset); | ||
667 | 726 | return true; | ||
668 | 727 | }); | ||
669 | 728 | #else | ||
670 | 729 | var draw_values_it = draw_values.map_iterator (); | ||
671 | 730 | while (draw_values_it.next ()) { | ||
672 | 731 | var val = draw_values_it.get_value (); | ||
673 | 732 | val.move_right (position, x_offset); | ||
674 | 733 | } | ||
675 | 734 | #endif | ||
676 | 735 | } | ||
677 | 736 | |||
678 | 737 | void draw_item (Cairo.Context cr, DockItem item, PositionManager.DockItemDrawValue draw_value, int64 frame_time) | ||
679 | 738 | { | ||
680 | 739 | unowned PositionManager position_manager = controller.position_manager; | ||
681 | 740 | var icon_size = (int) draw_value.icon_size; | ||
682 | 702 | var position = position_manager.Position; | 741 | var position = position_manager.Position; |
683 | 703 | 742 | ||
684 | 704 | // load the icon | 743 | // load the icon |
685 | @@ -710,7 +749,7 @@ | |||
686 | 710 | 749 | ||
687 | 711 | DockSurface? icon_overlay_surface = null; | 750 | DockSurface? icon_overlay_surface = null; |
688 | 712 | if (item.CountVisible || item.ProgressVisible) | 751 | if (item.CountVisible || item.ProgressVisible) |
690 | 713 | icon_overlay_surface = item.get_foreground_surface (draw_item_foreground); | 752 | icon_overlay_surface = item.get_foreground_surface (icon_size * window_scale_factor, icon_size * window_scale_factor, item_buffer, (DrawDataFunc<DockItem>) draw_item_foreground); |
691 | 714 | 753 | ||
692 | 715 | if (icon_overlay_surface != null) { | 754 | if (icon_overlay_surface != null) { |
693 | 716 | icon_cr.set_source_surface (icon_overlay_surface.Internal, 0, 0); | 755 | icon_cr.set_source_surface (icon_overlay_surface.Internal, 0, 0); |
694 | @@ -766,15 +805,17 @@ | |||
695 | 766 | draw_indicator_state (cr, draw_value.hover_region, item.Indicator, item.State); | 805 | draw_indicator_state (cr, draw_value.hover_region, item.Indicator, item.State); |
696 | 767 | } | 806 | } |
697 | 768 | 807 | ||
699 | 769 | void draw_item_shadow (Cairo.Context cr, DockItem item, ref PositionManager.DockItemDrawValue draw_value) | 808 | void draw_item_shadow (Cairo.Context cr, DockItem item, PositionManager.DockItemDrawValue draw_value) |
700 | 770 | { | 809 | { |
701 | 771 | unowned PositionManager position_manager = controller.position_manager; | 810 | unowned PositionManager position_manager = controller.position_manager; |
702 | 772 | var shadow_size = position_manager.IconShadowSize; | 811 | var shadow_size = position_manager.IconShadowSize; |
704 | 773 | 812 | // Inflate size to fit shadow | |
705 | 813 | var icon_size = (int) draw_value.icon_size + 2 * shadow_size; | ||
706 | 814 | |||
707 | 774 | // load and draw the icon shadow | 815 | // load and draw the icon shadow |
708 | 775 | DockSurface? icon_shadow_surface = null; | 816 | DockSurface? icon_shadow_surface = null; |
709 | 776 | if (shadow_size > 0) | 817 | if (shadow_size > 0) |
711 | 777 | icon_shadow_surface = item.get_background_surface (draw_item_background); | 818 | icon_shadow_surface = item.get_background_surface (icon_size * window_scale_factor, icon_size * window_scale_factor, item_buffer, (DrawDataFunc<DockItem>) draw_item_background); |
712 | 778 | 819 | ||
713 | 779 | if (icon_shadow_surface != null) { | 820 | if (icon_shadow_surface != null) { |
714 | 780 | if (window_scale_factor > 1) { | 821 | if (window_scale_factor > 1) { |
715 | @@ -793,20 +834,13 @@ | |||
716 | 793 | } | 834 | } |
717 | 794 | } | 835 | } |
718 | 795 | 836 | ||
720 | 796 | DockSurface draw_item_foreground (DockItem item, DockSurface icon_surface, DockSurface? current_surface) | 837 | [CCode (instance_pos = -1)] |
721 | 838 | DockSurface draw_item_foreground (int width, int height, DockSurface model, DockItem item) | ||
722 | 797 | { | 839 | { |
723 | 798 | unowned PositionManager position_manager = controller.position_manager; | ||
724 | 799 | var width = icon_surface.Width; | ||
725 | 800 | var height = icon_surface.Height; | ||
726 | 801 | |||
727 | 802 | if (current_surface != null | ||
728 | 803 | && width == current_surface.Width && height == current_surface.Height) | ||
729 | 804 | return current_surface; | ||
730 | 805 | |||
731 | 806 | Logger.verbose ("DockItem.draw_item_overlay (width = %i, height = %i)", width, height); | 840 | Logger.verbose ("DockItem.draw_item_overlay (width = %i, height = %i)", width, height); |
733 | 807 | var surface = new DockSurface.with_dock_surface (width, height, icon_surface); | 841 | var surface = new DockSurface.with_dock_surface (width, height, model); |
734 | 808 | 842 | ||
736 | 809 | var icon_size = position_manager.IconSize * window_scale_factor; | 843 | var icon_size = int.min (width, height) * window_scale_factor; |
737 | 810 | var urgent_color = get_styled_color (); | 844 | var urgent_color = get_styled_color (); |
738 | 811 | urgent_color.add_hue (theme.UrgentHueShift); | 845 | urgent_color.add_hue (theme.UrgentHueShift); |
739 | 812 | 846 | ||
740 | @@ -821,21 +855,18 @@ | |||
741 | 821 | return surface; | 855 | return surface; |
742 | 822 | } | 856 | } |
743 | 823 | 857 | ||
745 | 824 | DockSurface draw_item_background (DockItem item, DockSurface icon_surface, DockSurface? current_surface) | 858 | [CCode (instance_pos = -1)] |
746 | 859 | DockSurface draw_item_background (int width, int height, DockSurface model, DockItem item) | ||
747 | 825 | { | 860 | { |
748 | 826 | unowned PositionManager position_manager = controller.position_manager; | 861 | unowned PositionManager position_manager = controller.position_manager; |
749 | 827 | var shadow_size = position_manager.IconShadowSize * window_scale_factor; | 862 | var shadow_size = position_manager.IconShadowSize * window_scale_factor; |
750 | 828 | 863 | ||
758 | 829 | // Inflate size to fit shadow | 864 | var draw_value = position_manager.get_draw_value_for_item (item); |
759 | 830 | var width = icon_surface.Width + 2 * shadow_size; | 865 | var icon_size = (int) draw_value.icon_size; |
760 | 831 | var height = icon_surface.Height + 2 * shadow_size; | 866 | var icon_surface = item.get_surface (icon_size, icon_size, model); |
754 | 832 | |||
755 | 833 | if (current_surface != null | ||
756 | 834 | && width == current_surface.Width && height == current_surface.Height) | ||
757 | 835 | return current_surface; | ||
761 | 836 | 867 | ||
762 | 837 | Logger.verbose ("DockItem.draw_icon_with_shadow (width = %i, height = %i, shadow_size = %i)", width, height, shadow_size); | 868 | Logger.verbose ("DockItem.draw_icon_with_shadow (width = %i, height = %i, shadow_size = %i)", width, height, shadow_size); |
764 | 838 | var surface = new DockSurface.with_dock_surface (width, height, icon_surface); | 869 | var surface = new DockSurface.with_dock_surface (width, height, model); |
765 | 839 | unowned Cairo.Context cr = surface.Context; | 870 | unowned Cairo.Context cr = surface.Context; |
766 | 840 | var shadow_surface = icon_surface.create_mask (0.4, null); | 871 | var shadow_surface = icon_surface.create_mask (0.4, null); |
767 | 841 | 872 | ||
768 | @@ -976,6 +1007,35 @@ | |||
769 | 976 | animated_draw (); | 1007 | animated_draw (); |
770 | 977 | } | 1008 | } |
771 | 978 | 1009 | ||
772 | 1010 | void hovered_changed () | ||
773 | 1011 | { | ||
774 | 1012 | force_frame_time_update (); | ||
775 | 1013 | var now = frame_time; | ||
776 | 1014 | var diff = now - last_hovered_changed; | ||
777 | 1015 | var time = 150 * 1000; | ||
778 | 1016 | |||
779 | 1017 | if (diff < time) | ||
780 | 1018 | last_hovered_changed = now + (diff - time); | ||
781 | 1019 | else | ||
782 | 1020 | last_hovered_changed = now; | ||
783 | 1021 | |||
784 | 1022 | animated_draw (); | ||
785 | 1023 | } | ||
786 | 1024 | |||
787 | 1025 | public void update_local_cursor (int x, int y) | ||
788 | 1026 | { | ||
789 | 1027 | Gdk.Point new_cursor = { x, y }; | ||
790 | 1028 | if (local_cursor == new_cursor) | ||
791 | 1029 | return; | ||
792 | 1030 | |||
793 | 1031 | local_cursor = new_cursor; | ||
794 | 1032 | |||
795 | 1033 | if (controller.prefs.ZoomEnabled) { | ||
796 | 1034 | zoom_changed = true; | ||
797 | 1035 | animated_draw (); | ||
798 | 1036 | } | ||
799 | 1037 | } | ||
800 | 1038 | |||
801 | 979 | public void animate_items (Gee.List<DockElement> elements) | 1039 | public void animate_items (Gee.List<DockElement> elements) |
802 | 980 | { | 1040 | { |
803 | 981 | if (!screen_is_composited) | 1041 | if (!screen_is_composited) |
804 | @@ -995,6 +1055,15 @@ | |||
805 | 995 | */ | 1055 | */ |
806 | 996 | protected override bool animation_needed (int64 frame_time) | 1056 | protected override bool animation_needed (int64 frame_time) |
807 | 997 | { | 1057 | { |
808 | 1058 | if (zoom_changed) { | ||
809 | 1059 | //FIXME reset at a better place | ||
810 | 1060 | zoom_changed = false; | ||
811 | 1061 | return true; | ||
812 | 1062 | } | ||
813 | 1063 | |||
814 | 1064 | if (frame_time - last_hovered_changed <= 150 * 1000) | ||
815 | 1065 | return true; | ||
816 | 1066 | |||
817 | 998 | if (theme.FadeOpacity == 1.0) { | 1067 | if (theme.FadeOpacity == 1.0) { |
818 | 999 | if (frame_time - last_hide <= theme.HideTime * 1000) | 1068 | if (frame_time - last_hide <= theme.HideTime * 1000) |
819 | 1000 | return true; | 1069 | return true; |
820 | @@ -1006,7 +1075,7 @@ | |||
821 | 1006 | if (transient_items.size > 0) | 1075 | if (transient_items.size > 0) |
822 | 1007 | return true; | 1076 | return true; |
823 | 1008 | 1077 | ||
825 | 1009 | foreach (var item in controller.VisibleItems) | 1078 | foreach (var item in current_items) |
826 | 1010 | if (item_animation_needed (item, frame_time)) | 1079 | if (item_animation_needed (item, frame_time)) |
827 | 1011 | return true; | 1080 | return true; |
828 | 1012 | 1081 | ||
829 | @@ -1039,5 +1108,22 @@ | |||
830 | 1039 | 1108 | ||
831 | 1040 | return false; | 1109 | return false; |
832 | 1041 | } | 1110 | } |
833 | 1111 | |||
834 | 1112 | static int compare_dock_item_position (DockItem i1, DockItem i2) | ||
835 | 1113 | { | ||
836 | 1114 | var p_i1 = i1.Position; | ||
837 | 1115 | var p_i2 = i2.Position; | ||
838 | 1116 | |||
839 | 1117 | if (p_i1 > p_i2) | ||
840 | 1118 | return 1; | ||
841 | 1119 | |||
842 | 1120 | if (p_i1 < p_i2) | ||
843 | 1121 | return -1; | ||
844 | 1122 | |||
845 | 1123 | if (i1.RemoveTime > i2.RemoveTime) | ||
846 | 1124 | return -1; | ||
847 | 1125 | |||
848 | 1126 | return 1; | ||
849 | 1127 | } | ||
850 | 1042 | } | 1128 | } |
851 | 1043 | } | 1129 | } |
852 | 1044 | 1130 | ||
853 | === modified file 'lib/DragManager.vala' | |||
854 | --- lib/DragManager.vala 2015-06-08 09:36:14 +0000 | |||
855 | +++ lib/DragManager.vala 2015-07-16 08:37:41 +0000 | |||
856 | @@ -178,7 +178,7 @@ | |||
857 | 178 | #if HAVE_HIDPI | 178 | #if HAVE_HIDPI |
858 | 179 | window_scale_factor = controller.window.get_window ().get_scale_factor (); | 179 | window_scale_factor = controller.window.get_window ().get_scale_factor (); |
859 | 180 | #endif | 180 | #endif |
861 | 181 | var drag_icon_size = (int) (1.2 * controller.position_manager.IconSize); | 181 | var drag_icon_size = (int) (1.2 * controller.position_manager.ZoomIconSize); |
862 | 182 | if (drag_icon_size % 2 == 1) | 182 | if (drag_icon_size % 2 == 1) |
863 | 183 | drag_icon_size++; | 183 | drag_icon_size++; |
864 | 184 | #if HAVE_HIDPI | 184 | #if HAVE_HIDPI |
865 | @@ -441,6 +441,7 @@ | |||
866 | 441 | Gdk.drag_status (context, Gdk.DragAction.COPY, time_); | 441 | Gdk.drag_status (context, Gdk.DragAction.COPY, time_); |
867 | 442 | } | 442 | } |
868 | 443 | 443 | ||
869 | 444 | controller.renderer.update_local_cursor (x, y); | ||
870 | 444 | hide_manager.update_hovered (); | 445 | hide_manager.update_hovered (); |
871 | 445 | window.update_hovered (x, y); | 446 | window.update_hovered (x, y); |
872 | 446 | 447 | ||
873 | 447 | 448 | ||
874 | === modified file 'lib/Drawing/DockSurface.vala' | |||
875 | --- lib/Drawing/DockSurface.vala 2015-05-16 18:48:15 +0000 | |||
876 | +++ lib/Drawing/DockSurface.vala 2015-07-16 08:37:41 +0000 | |||
877 | @@ -125,6 +125,27 @@ | |||
878 | 125 | } | 125 | } |
879 | 126 | 126 | ||
880 | 127 | /** | 127 | /** |
881 | 128 | * Create a scaled copy of the surface | ||
882 | 129 | * | ||
883 | 130 | * @param width the resulting width | ||
884 | 131 | * @param height the resulting height | ||
885 | 132 | * @return scaled copy of this surface | ||
886 | 133 | */ | ||
887 | 134 | public DockSurface scaled_copy (int width, int height) | ||
888 | 135 | { | ||
889 | 136 | var result = new DockSurface.with_dock_surface (width, height, this); | ||
890 | 137 | unowned Cairo.Context cr = result.Context; | ||
891 | 138 | |||
892 | 139 | cr.save (); | ||
893 | 140 | cr.scale ((double) width / Width, (double) height / Height); | ||
894 | 141 | cr.set_source_surface (Internal, 0, 0); | ||
895 | 142 | cr.paint (); | ||
896 | 143 | cr.restore (); | ||
897 | 144 | |||
898 | 145 | return result; | ||
899 | 146 | } | ||
900 | 147 | |||
901 | 148 | /** | ||
902 | 128 | * Saves the current dock surface to a {@link Gdk.Pixbuf}. | 149 | * Saves the current dock surface to a {@link Gdk.Pixbuf}. |
903 | 129 | * | 150 | * |
904 | 130 | * @return the {@link Gdk.Pixbuf} | 151 | * @return the {@link Gdk.Pixbuf} |
905 | 131 | 152 | ||
906 | === added file 'lib/Drawing/SurfaceCache.vala' | |||
907 | --- lib/Drawing/SurfaceCache.vala 1970-01-01 00:00:00 +0000 | |||
908 | +++ lib/Drawing/SurfaceCache.vala 2015-07-16 08:37:41 +0000 | |||
909 | @@ -0,0 +1,322 @@ | |||
910 | 1 | // | ||
911 | 2 | // Copyright (C) 2015 Rico Tzschichholz | ||
912 | 3 | // | ||
913 | 4 | // This file is part of Plank. | ||
914 | 5 | // | ||
915 | 6 | // Plank is free software: you can redistribute it and/or modify | ||
916 | 7 | // it under the terms of the GNU General Public License as published by | ||
917 | 8 | // the Free Software Foundation, either version 3 of the License, or | ||
918 | 9 | // (at your option) any later version. | ||
919 | 10 | // | ||
920 | 11 | // Plank is distributed in the hope that it will be useful, | ||
921 | 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
922 | 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
923 | 14 | // GNU General Public License for more details. | ||
924 | 15 | // | ||
925 | 16 | // You should have received a copy of the GNU General Public License | ||
926 | 17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
927 | 18 | // | ||
928 | 19 | |||
929 | 20 | using Plank.Services; | ||
930 | 21 | |||
931 | 22 | namespace Plank.Drawing | ||
932 | 23 | { | ||
933 | 24 | /** | ||
934 | 25 | * Creates a new surface based on the given information | ||
935 | 26 | * | ||
936 | 27 | * @param width the width | ||
937 | 28 | * @param height the height | ||
938 | 29 | * @param model existing surface to use as basis of new surface | ||
939 | 30 | * @param draw_data_func function which changes the surface | ||
940 | 31 | * @return the newly created surface or NULL | ||
941 | 32 | */ | ||
942 | 33 | public delegate DockSurface? DrawFunc<G> (int width, int height, DockSurface model, DrawDataFunc<G>? draw_data_func); | ||
943 | 34 | |||
944 | 35 | /** | ||
945 | 36 | * Creates a new surface using the given element and information | ||
946 | 37 | * | ||
947 | 38 | * @param width the width | ||
948 | 39 | * @param height the height | ||
949 | 40 | * @param model existing surface to use as basis of new surface | ||
950 | 41 | * @param data the data object used for drawing | ||
951 | 42 | * @return the newly created surface or NULL | ||
952 | 43 | */ | ||
953 | 44 | public delegate DockSurface? DrawDataFunc<G> (int width, int height, DockSurface model, G? data); | ||
954 | 45 | |||
955 | 46 | /** | ||
956 | 47 | * Controls some internal behaviors of a {@link Plank.Drawing.SurfaceCache} | ||
957 | 48 | */ | ||
958 | 49 | [Flags] | ||
959 | 50 | public enum SurfaceCacheFlags | ||
960 | 51 | { | ||
961 | 52 | NONE = 0, | ||
962 | 53 | /** | ||
963 | 54 | * Allow down-scaling of an existing cached surface for better performance | ||
964 | 55 | */ | ||
965 | 56 | ALLOW_DOWNSCALE = 1 << 0, | ||
966 | 57 | /** | ||
967 | 58 | * Allow up-scaling of an existing cached surface for better performance | ||
968 | 59 | */ | ||
969 | 60 | ALLOW_UPSCALE = 1 << 1, | ||
970 | 61 | /** | ||
971 | 62 | * Allow scaling of an existing cached surface for better performance | ||
972 | 63 | * (This basically means the cache will only contain one entry which will be scaled accordingly on request) | ||
973 | 64 | */ | ||
974 | 65 | ALLOW_SCALE = ALLOW_UPSCALE | ALLOW_DOWNSCALE, | ||
975 | 66 | /** | ||
976 | 67 | * Allow scaling if the drawing-time is significatly high | ||
977 | 68 | */ | ||
978 | 69 | ADAPTIVE_SCALE = 1 << 2, | ||
979 | 70 | } | ||
980 | 71 | |||
981 | 72 | /** | ||
982 | 73 | * Cache multiple sizes of the assumed same image | ||
983 | 74 | */ | ||
984 | 75 | public class SurfaceCache<G> : GLib.Object | ||
985 | 76 | { | ||
986 | 77 | const int64 MAX_CACHE_AGE = 5 * 60 * 1000 * 1000; | ||
987 | 78 | const int64 MIN_DRAWING_TIME = 10 * 1000; | ||
988 | 79 | const int64 ACCESS_REWARD = 500 * 1000; | ||
989 | 80 | |||
990 | 81 | class SurfaceInfo | ||
991 | 82 | { | ||
992 | 83 | public uint16 width; | ||
993 | 84 | public uint16 height; | ||
994 | 85 | public uint access_count; | ||
995 | 86 | public int64 last_access_time; | ||
996 | 87 | public int64 drawing_time; | ||
997 | 88 | public double scale; | ||
998 | 89 | |||
999 | 90 | public SurfaceInfo (uint16 width, uint16 height, int64 last_access_time, int64 drawing_time) | ||
1000 | 91 | { | ||
1001 | 92 | this.width = width; | ||
1002 | 93 | this.height = height; | ||
1003 | 94 | this.last_access_time = last_access_time; | ||
1004 | 95 | this.drawing_time = drawing_time; | ||
1005 | 96 | this.access_count = 0; | ||
1006 | 97 | this.scale = 1.0; | ||
1007 | 98 | } | ||
1008 | 99 | |||
1009 | 100 | public static uint hash (SurfaceInfo s) | ||
1010 | 101 | { | ||
1011 | 102 | uint n1 = s.width, n2 = s.height; | ||
1012 | 103 | return (n1 >= n2 ? n1 * n1 + n1 + n2 : n1 + n2 * n2); | ||
1013 | 104 | } | ||
1014 | 105 | |||
1015 | 106 | public static int compare (SurfaceInfo s1, SurfaceInfo s2) | ||
1016 | 107 | { | ||
1017 | 108 | if (s1 == s2) | ||
1018 | 109 | return 0; | ||
1019 | 110 | |||
1020 | 111 | return (2 * (s1.width - s2.width) + s2.height - s2.height); | ||
1021 | 112 | } | ||
1022 | 113 | |||
1023 | 114 | public int compare_with (uint16 width, uint16 height) | ||
1024 | 115 | { | ||
1025 | 116 | return (2 * (this.width - width) + this.height - height); | ||
1026 | 117 | } | ||
1027 | 118 | } | ||
1028 | 119 | |||
1029 | 120 | public SurfaceCacheFlags flags { get; construct; } | ||
1030 | 121 | |||
1031 | 122 | Gee.TreeSet<unowned SurfaceInfo> infos; | ||
1032 | 123 | Gee.HashMap<SurfaceInfo, DockSurface> cache_map; | ||
1033 | 124 | unowned SurfaceInfo? last_info; | ||
1034 | 125 | Mutex cache_mutex; | ||
1035 | 126 | |||
1036 | 127 | uint clean_up_timer = 0U; | ||
1037 | 128 | |||
1038 | 129 | public SurfaceCache (SurfaceCacheFlags flags = SurfaceCacheFlags.NONE) | ||
1039 | 130 | { | ||
1040 | 131 | Object (flags: flags); | ||
1041 | 132 | } | ||
1042 | 133 | |||
1043 | 134 | construct | ||
1044 | 135 | { | ||
1045 | 136 | infos = new Gee.TreeSet<unowned SurfaceInfo> ((CompareDataFunc) SurfaceInfo.compare); | ||
1046 | 137 | cache_map = new Gee.HashMap<SurfaceInfo, DockSurface> ((Gee.HashDataFunc<SurfaceInfo>) SurfaceInfo.hash); | ||
1047 | 138 | last_info = null; | ||
1048 | 139 | |||
1049 | 140 | //TODO Adaptive delay depending on the access rate | ||
1050 | 141 | clean_up_timer = Gdk.threads_add_timeout (5 * 60 * 1000, () => { | ||
1051 | 142 | clean_up (); | ||
1052 | 143 | return true; | ||
1053 | 144 | }); | ||
1054 | 145 | } | ||
1055 | 146 | |||
1056 | 147 | ~SurfaceCache () | ||
1057 | 148 | { | ||
1058 | 149 | if (clean_up_timer > 0U) { | ||
1059 | 150 | GLib.Source.remove (clean_up_timer); | ||
1060 | 151 | clean_up_timer = 0U; | ||
1061 | 152 | } | ||
1062 | 153 | |||
1063 | 154 | cache_map.clear (); | ||
1064 | 155 | infos.clear (); | ||
1065 | 156 | last_info = null; | ||
1066 | 157 | } | ||
1067 | 158 | |||
1068 | 159 | public DockSurface? get_surface<G> (int width, int height, DockSurface model, DrawFunc<G> draw_func, DrawDataFunc<G>? draw_data_func) | ||
1069 | 160 | requires (width >= 0 && height >= 0) | ||
1070 | 161 | { | ||
1071 | 162 | cache_mutex.lock (); | ||
1072 | 163 | |||
1073 | 164 | unowned SurfaceInfo? info; | ||
1074 | 165 | SurfaceInfo? current_info = null; | ||
1075 | 166 | DockSurface? surface = null; | ||
1076 | 167 | bool needs_scaling = false; | ||
1077 | 168 | |||
1078 | 169 | info = find_match ((uint16) width, (uint16) height, out needs_scaling); | ||
1079 | 170 | last_info = info; | ||
1080 | 171 | current_info = info; | ||
1081 | 172 | |||
1082 | 173 | var access_time = GLib.get_monotonic_time (); | ||
1083 | 174 | |||
1084 | 175 | if (current_info != null) { | ||
1085 | 176 | current_info.last_access_time = access_time; | ||
1086 | 177 | current_info.access_count++; | ||
1087 | 178 | surface = cache_map.get (current_info); | ||
1088 | 179 | |||
1089 | 180 | cache_mutex.unlock (); | ||
1090 | 181 | |||
1091 | 182 | if (needs_scaling) | ||
1092 | 183 | return surface.scaled_copy (width, height); | ||
1093 | 184 | else | ||
1094 | 185 | return surface; | ||
1095 | 186 | } | ||
1096 | 187 | |||
1097 | 188 | surface = draw_func (width, height, model, draw_data_func); | ||
1098 | 189 | |||
1099 | 190 | var finish_time = GLib.get_monotonic_time (); | ||
1100 | 191 | var time_elapsed = finish_time - access_time; | ||
1101 | 192 | |||
1102 | 193 | current_info = new SurfaceInfo ((uint16) width, (uint16) height, finish_time, time_elapsed); | ||
1103 | 194 | current_info.access_count++; | ||
1104 | 195 | |||
1105 | 196 | cache_map.set (current_info, surface); | ||
1106 | 197 | infos.add (current_info); | ||
1107 | 198 | |||
1108 | 199 | cache_mutex.unlock (); | ||
1109 | 200 | |||
1110 | 201 | return surface; | ||
1111 | 202 | } | ||
1112 | 203 | |||
1113 | 204 | unowned SurfaceInfo? find_match (uint16 width, uint16 height, out bool needs_scaling) | ||
1114 | 205 | { | ||
1115 | 206 | needs_scaling = false; | ||
1116 | 207 | |||
1117 | 208 | if (infos.is_empty) | ||
1118 | 209 | return null; | ||
1119 | 210 | |||
1120 | 211 | unowned SurfaceInfo? info; | ||
1121 | 212 | // Check if the last requested entry matches already | ||
1122 | 213 | if (last_info != null) { | ||
1123 | 214 | info = last_info; | ||
1124 | 215 | if (info.width == width && info.height == height) | ||
1125 | 216 | return info; | ||
1126 | 217 | |||
1127 | 218 | if ((flags & SurfaceCacheFlags.ALLOW_DOWNSCALE) != 0 | ||
1128 | 219 | && info.width > width && info.height > height) { | ||
1129 | 220 | needs_scaling = true; | ||
1130 | 221 | return info; | ||
1131 | 222 | } | ||
1132 | 223 | |||
1133 | 224 | if ((flags & SurfaceCacheFlags.ALLOW_UPSCALE) != 0 | ||
1134 | 225 | && info.width < width && info.height < height) { | ||
1135 | 226 | needs_scaling = true; | ||
1136 | 227 | return info; | ||
1137 | 228 | } | ||
1138 | 229 | } | ||
1139 | 230 | |||
1140 | 231 | Gee.BidirIterator<unowned SurfaceInfo> infos_it; | ||
1141 | 232 | if (last_info != null) | ||
1142 | 233 | infos_it = (Gee.BidirIterator<unowned SurfaceInfo>) infos.iterator_at (last_info); | ||
1143 | 234 | else | ||
1144 | 235 | infos_it = infos.bidir_iterator (); | ||
1145 | 236 | |||
1146 | 237 | if (last_info != null && last_info.compare_with (width, height) > 0) { | ||
1147 | 238 | while (infos_it.previous ()) { | ||
1148 | 239 | info = infos_it.get (); | ||
1149 | 240 | |||
1150 | 241 | if (info.width == width && info.height == height) | ||
1151 | 242 | return info; | ||
1152 | 243 | |||
1153 | 244 | if ((flags & SurfaceCacheFlags.ALLOW_DOWNSCALE) != 0 | ||
1154 | 245 | && info.width > width && info.height > height) { | ||
1155 | 246 | needs_scaling = true; | ||
1156 | 247 | return info; | ||
1157 | 248 | } | ||
1158 | 249 | |||
1159 | 250 | if ((flags & SurfaceCacheFlags.ALLOW_UPSCALE) != 0 | ||
1160 | 251 | && info.width < width && info.height < height) { | ||
1161 | 252 | needs_scaling = true; | ||
1162 | 253 | return info; | ||
1163 | 254 | } | ||
1164 | 255 | } | ||
1165 | 256 | } else { | ||
1166 | 257 | while (infos_it.next ()) { | ||
1167 | 258 | info = infos_it.get (); | ||
1168 | 259 | |||
1169 | 260 | if (info.width == width && info.height == height) | ||
1170 | 261 | return info; | ||
1171 | 262 | |||
1172 | 263 | if ((flags & SurfaceCacheFlags.ALLOW_DOWNSCALE) != 0 | ||
1173 | 264 | && info.width > width && info.height > height) { | ||
1174 | 265 | needs_scaling = true; | ||
1175 | 266 | return info; | ||
1176 | 267 | } | ||
1177 | 268 | |||
1178 | 269 | if ((flags & SurfaceCacheFlags.ALLOW_UPSCALE) != 0 | ||
1179 | 270 | && info.width < width && info.height < height) { | ||
1180 | 271 | needs_scaling = true; | ||
1181 | 272 | return info; | ||
1182 | 273 | } | ||
1183 | 274 | } | ||
1184 | 275 | } | ||
1185 | 276 | |||
1186 | 277 | return null; | ||
1187 | 278 | } | ||
1188 | 279 | |||
1189 | 280 | public void clear () | ||
1190 | 281 | { | ||
1191 | 282 | cache_mutex.lock (); | ||
1192 | 283 | |||
1193 | 284 | infos.clear (); | ||
1194 | 285 | cache_map.clear (); | ||
1195 | 286 | last_info = null; | ||
1196 | 287 | |||
1197 | 288 | cache_mutex.unlock (); | ||
1198 | 289 | } | ||
1199 | 290 | |||
1200 | 291 | void clean_up () | ||
1201 | 292 | { | ||
1202 | 293 | cache_mutex.lock (); | ||
1203 | 294 | |||
1204 | 295 | if (cache_map.size <= 1) | ||
1205 | 296 | return; | ||
1206 | 297 | |||
1207 | 298 | var now = GLib.get_monotonic_time (); | ||
1208 | 299 | var size_before = cache_map.size; | ||
1209 | 300 | |||
1210 | 301 | var cache_it = cache_map.map_iterator (); | ||
1211 | 302 | while (cache_it.next ()) { | ||
1212 | 303 | var info = cache_it.get_key (); | ||
1213 | 304 | |||
1214 | 305 | if (now - info.last_access_time < ACCESS_REWARD * info.access_count) | ||
1215 | 306 | continue; | ||
1216 | 307 | |||
1217 | 308 | if (info.drawing_time > MIN_DRAWING_TIME) | ||
1218 | 309 | continue; | ||
1219 | 310 | |||
1220 | 311 | infos.remove (info); | ||
1221 | 312 | cache_it.unset (); | ||
1222 | 313 | } | ||
1223 | 314 | |||
1224 | 315 | last_info = null; | ||
1225 | 316 | |||
1226 | 317 | Logger.verbose ("SurfaceCache.clean_up (%i -> %i) ", size_before, cache_map.size); | ||
1227 | 318 | |||
1228 | 319 | cache_mutex.unlock (); | ||
1229 | 320 | } | ||
1230 | 321 | } | ||
1231 | 322 | } | ||
1232 | 0 | 323 | ||
1233 | === modified file 'lib/Items/DockItem.vala' | |||
1234 | --- lib/Items/DockItem.vala 2015-06-10 20:26:28 +0000 | |||
1235 | +++ lib/Items/DockItem.vala 2015-07-16 08:37:41 +0000 | |||
1236 | @@ -24,16 +24,6 @@ | |||
1237 | 24 | namespace Plank.Items | 24 | namespace Plank.Items |
1238 | 25 | { | 25 | { |
1239 | 26 | /** | 26 | /** |
1240 | 27 | * Draws a modified surface onto another newly created or given surface | ||
1241 | 28 | * | ||
1242 | 29 | * @param item the dock-item | ||
1243 | 30 | * @param source original surface which may not be changed | ||
1244 | 31 | * @param target the previously modified surface | ||
1245 | 32 | * @return the modified surface or passed through target | ||
1246 | 33 | */ | ||
1247 | 34 | public delegate DockSurface DrawItemFunc (DockItem item, DockSurface source, DockSurface? target); | ||
1248 | 35 | |||
1249 | 36 | /** | ||
1250 | 37 | * The base class for all dock items. | 27 | * The base class for all dock items. |
1251 | 38 | */ | 28 | */ |
1252 | 39 | public abstract class DockItem : DockElement | 29 | public abstract class DockItem : DockElement |
1253 | @@ -134,8 +124,8 @@ | |||
1254 | 134 | */ | 124 | */ |
1255 | 135 | public DockItemPreferences Prefs { get; construct; } | 125 | public DockItemPreferences Prefs { get; construct; } |
1256 | 136 | 126 | ||
1259 | 137 | DockSurface? surface = null; | 127 | SurfaceCache<DockItem> buffer; |
1260 | 138 | DockSurface? background_surface = null; | 128 | SurfaceCache<DockItem> background_buffer; |
1261 | 139 | DockSurface? foreground_surface = null; | 129 | DockSurface? foreground_surface = null; |
1262 | 140 | 130 | ||
1263 | 141 | FileMonitor? launcher_file_monitor = null; | 131 | FileMonitor? launcher_file_monitor = null; |
1264 | @@ -154,6 +144,9 @@ | |||
1265 | 154 | 144 | ||
1266 | 155 | construct | 145 | construct |
1267 | 156 | { | 146 | { |
1268 | 147 | buffer = new SurfaceCache<DockItem> (SurfaceCacheFlags.NONE); | ||
1269 | 148 | background_buffer = new SurfaceCache<DockItem> (SurfaceCacheFlags.ALLOW_SCALE); | ||
1270 | 149 | |||
1271 | 157 | Prefs.deleted.connect (handle_deleted); | 150 | Prefs.deleted.connect (handle_deleted); |
1272 | 158 | Prefs.notify["Launcher"].connect (handle_launcher_changed); | 151 | Prefs.notify["Launcher"].connect (handle_launcher_changed); |
1273 | 159 | 152 | ||
1274 | @@ -173,6 +166,9 @@ | |||
1275 | 173 | 166 | ||
1276 | 174 | ~DockItem () | 167 | ~DockItem () |
1277 | 175 | { | 168 | { |
1278 | 169 | buffer.clear (); | ||
1279 | 170 | background_buffer.clear (); | ||
1280 | 171 | |||
1281 | 176 | Prefs.deleted.disconnect (handle_deleted); | 172 | Prefs.deleted.disconnect (handle_deleted); |
1282 | 177 | Prefs.notify["Launcher"].disconnect (handle_launcher_changed); | 173 | Prefs.notify["Launcher"].disconnect (handle_launcher_changed); |
1283 | 178 | 174 | ||
1284 | @@ -232,8 +228,8 @@ | |||
1285 | 232 | */ | 228 | */ |
1286 | 233 | protected void reset_icon_buffer () | 229 | protected void reset_icon_buffer () |
1287 | 234 | { | 230 | { |
1290 | 235 | surface = null; | 231 | buffer.clear (); |
1291 | 236 | background_surface = null; | 232 | background_buffer.clear (); |
1292 | 237 | foreground_surface = null; | 233 | foreground_surface = null; |
1293 | 238 | 234 | ||
1294 | 239 | needs_redraw (); | 235 | needs_redraw (); |
1295 | @@ -244,7 +240,7 @@ | |||
1296 | 244 | */ | 240 | */ |
1297 | 245 | public override void reset_buffers () | 241 | public override void reset_buffers () |
1298 | 246 | { | 242 | { |
1300 | 247 | background_surface = null; | 243 | background_buffer.clear (); |
1301 | 248 | foreground_surface = null; | 244 | foreground_surface = null; |
1302 | 249 | } | 245 | } |
1303 | 250 | 246 | ||
1304 | @@ -420,16 +416,31 @@ | |||
1305 | 420 | return true; | 416 | return true; |
1306 | 421 | } | 417 | } |
1307 | 422 | 418 | ||
1318 | 423 | unowned DockSurface get_surface (int width, int height, DockSurface model) | 419 | /** |
1319 | 424 | { | 420 | * Returns the dock surface for this item. |
1320 | 425 | if (surface == null || width != surface.Width || height != surface.Height) { | 421 | * |
1321 | 426 | surface = new DockSurface.with_dock_surface (width, height, model); | 422 | * It might trigger an internal redraw if the requested size |
1322 | 427 | 423 | * isn't cached yet. | |
1323 | 428 | Logger.verbose ("DockItem.draw_icon (width = %i, height = %i)", width, height); | 424 | * |
1324 | 429 | draw_icon (surface); | 425 | * @param width width of the icon surface |
1325 | 430 | 426 | * @param height height of the icon surface | |
1326 | 431 | AverageIconColor = surface.average_color (); | 427 | * @param model existing surface to use as basis of new surface |
1327 | 432 | } | 428 | * @return the dock surface for this item which may not be changed |
1328 | 429 | */ | ||
1329 | 430 | public DockSurface get_surface (int width, int height, DockSurface model) | ||
1330 | 431 | { | ||
1331 | 432 | return buffer.get_surface<DockItem> (width, height, model, (DrawFunc<DockItem>) internal_get_surface, null); | ||
1332 | 433 | } | ||
1333 | 434 | |||
1334 | 435 | [CCode (instance_pos = -1)] | ||
1335 | 436 | DockSurface internal_get_surface (int width, int height, DockSurface model, DrawDataFunc<DockItem>? draw_data_func) | ||
1336 | 437 | { | ||
1337 | 438 | var surface = new DockSurface.with_dock_surface (width, height, model); | ||
1338 | 439 | |||
1339 | 440 | Logger.verbose ("DockItem.draw_icon (width = %i, height = %i)", width, height); | ||
1340 | 441 | draw_icon (surface); | ||
1341 | 442 | |||
1342 | 443 | AverageIconColor = surface.average_color (); | ||
1343 | 433 | 444 | ||
1344 | 434 | return surface; | 445 | return surface; |
1345 | 435 | } | 446 | } |
1346 | @@ -442,18 +453,21 @@ | |||
1347 | 442 | * | 453 | * |
1348 | 443 | * Passing null as draw_func will destroy the internal background buffer. | 454 | * Passing null as draw_func will destroy the internal background buffer. |
1349 | 444 | * | 455 | * |
1351 | 445 | * @param draw_func function which creates/changes the background surface | 456 | * @param draw_data_func function which creates/changes the background surface |
1352 | 446 | * @return the background surface of this item which may not be changed | 457 | * @return the background surface of this item which may not be changed |
1353 | 447 | */ | 458 | */ |
1361 | 448 | public unowned DockSurface? get_background_surface (DrawItemFunc? draw_func = null) | 459 | public DockSurface? get_background_surface (int width, int height, DockSurface model, DrawDataFunc<DockItem>? draw_data_func) |
1362 | 449 | requires (surface != null) | 460 | { |
1363 | 450 | { | 461 | return background_buffer.get_surface<DockItem> (width, height, model, (DrawFunc<DockItem>) internal_get_background_surface, (DrawDataFunc<DockItem>) draw_data_func); |
1364 | 451 | if (draw_func != null) | 462 | } |
1365 | 452 | background_surface = draw_func (this, surface, background_surface); | 463 | |
1366 | 453 | else | 464 | [CCode (instance_pos = -1)] |
1367 | 454 | background_surface = null; | 465 | DockSurface? internal_get_background_surface (int width, int height, DockSurface model, DrawDataFunc<DockItem>? draw_data_func) |
1368 | 466 | { | ||
1369 | 467 | if (draw_data_func == null) | ||
1370 | 468 | return null; | ||
1371 | 455 | 469 | ||
1373 | 456 | return background_surface; | 470 | return draw_data_func (width, height, model, this); |
1374 | 457 | } | 471 | } |
1375 | 458 | 472 | ||
1376 | 459 | /** | 473 | /** |
1377 | @@ -464,16 +478,21 @@ | |||
1378 | 464 | * | 478 | * |
1379 | 465 | * Passing null as draw_func will destroy the internal foreground buffer. | 479 | * Passing null as draw_func will destroy the internal foreground buffer. |
1380 | 466 | * | 480 | * |
1382 | 467 | * @param draw_func function which creates/changes the foreground surface | 481 | * @param draw_data_func function which creates/changes the foreground surface |
1383 | 468 | * @return the background surface of this item which may not be changed | 482 | * @return the background surface of this item which may not be changed |
1384 | 469 | */ | 483 | */ |
1387 | 470 | public unowned DockSurface? get_foreground_surface (DrawItemFunc? draw_func = null) | 484 | public DockSurface? get_foreground_surface (int width, int height, DockSurface model, DrawDataFunc<DockItem>? draw_data_func) |
1386 | 471 | requires (surface != null) | ||
1388 | 472 | { | 485 | { |
1392 | 473 | if (draw_func != null) | 486 | if (draw_data_func == null) { |
1390 | 474 | foreground_surface = draw_func (this, surface, foreground_surface); | ||
1391 | 475 | else | ||
1393 | 476 | foreground_surface = null; | 487 | foreground_surface = null; |
1394 | 488 | return null; | ||
1395 | 489 | } | ||
1396 | 490 | |||
1397 | 491 | if (foreground_surface != null | ||
1398 | 492 | && foreground_surface.Width == width && foreground_surface.Height == height) | ||
1399 | 493 | return foreground_surface; | ||
1400 | 494 | |||
1401 | 495 | foreground_surface = draw_data_func (width, height, model, this); | ||
1402 | 477 | 496 | ||
1403 | 478 | return foreground_surface; | 497 | return foreground_surface; |
1404 | 479 | } | 498 | } |
1405 | 480 | 499 | ||
1406 | === modified file 'lib/Makefile.am' | |||
1407 | --- lib/Makefile.am 2015-06-08 21:48:12 +0000 | |||
1408 | +++ lib/Makefile.am 2015-07-16 08:37:41 +0000 | |||
1409 | @@ -79,6 +79,7 @@ | |||
1410 | 79 | Drawing/DockSurface.vala \ | 79 | Drawing/DockSurface.vala \ |
1411 | 80 | Drawing/DockTheme.vala \ | 80 | Drawing/DockTheme.vala \ |
1412 | 81 | Drawing/Easing.vala \ | 81 | Drawing/Easing.vala \ |
1413 | 82 | Drawing/SurfaceCache.vala \ | ||
1414 | 82 | Drawing/Theme.vala \ | 83 | Drawing/Theme.vala \ |
1415 | 83 | Factories/AbstractMain.vala \ | 84 | Factories/AbstractMain.vala \ |
1416 | 84 | Factories/Factory.vala \ | 85 | Factories/Factory.vala \ |
1417 | 85 | 86 | ||
1418 | === modified file 'lib/PositionManager.vala' | |||
1419 | --- lib/PositionManager.vala 2015-06-11 05:36:16 +0000 | |||
1420 | +++ lib/PositionManager.vala 2015-07-16 08:37:41 +0000 | |||
1421 | @@ -29,12 +29,41 @@ | |||
1422 | 29 | */ | 29 | */ |
1423 | 30 | public class PositionManager : GLib.Object | 30 | public class PositionManager : GLib.Object |
1424 | 31 | { | 31 | { |
1427 | 32 | public struct DockItemDrawValue | 32 | public struct PointD |
1428 | 33 | { | 33 | { |
1429 | 34 | public double x; | ||
1430 | 35 | public double y; | ||
1431 | 36 | } | ||
1432 | 37 | |||
1433 | 38 | /** | ||
1434 | 39 | * Modify the given DrawItemValue | ||
1435 | 40 | * | ||
1436 | 41 | * @param item the dock-item | ||
1437 | 42 | * @param draw_value the dock-item-drawvalue | ||
1438 | 43 | */ | ||
1439 | 44 | public delegate void DockItemDrawValueFunc (DockItem item, DockItemDrawValue draw_value); | ||
1440 | 45 | |||
1441 | 46 | /** | ||
1442 | 47 | * Modify the all DrawItemValue of all dock-items | ||
1443 | 48 | * | ||
1444 | 49 | * @param draw_values the map of all current dock-items and their draw-values | ||
1445 | 50 | */ | ||
1446 | 51 | public delegate void DrawValuesFunc (Gee.HashMap<DockElement, DockItemDrawValue> draw_values); | ||
1447 | 52 | |||
1448 | 53 | /** | ||
1449 | 54 | * Contains all positions and modifications to draw a dock-item on the dock | ||
1450 | 55 | */ | ||
1451 | 56 | public class DockItemDrawValue | ||
1452 | 57 | { | ||
1453 | 58 | public PointD center; | ||
1454 | 59 | public PointD static_center; | ||
1455 | 60 | public double icon_size; | ||
1456 | 61 | |||
1457 | 34 | public Gdk.Rectangle hover_region; | 62 | public Gdk.Rectangle hover_region; |
1458 | 35 | public Gdk.Rectangle draw_region; | 63 | public Gdk.Rectangle draw_region; |
1459 | 36 | public Gdk.Rectangle background_region; | 64 | public Gdk.Rectangle background_region; |
1460 | 37 | 65 | ||
1461 | 66 | public double zoom; | ||
1462 | 38 | public double opacity; | 67 | public double opacity; |
1463 | 39 | 68 | ||
1464 | 40 | public double darken; | 69 | public double darken; |
1465 | @@ -49,18 +78,26 @@ | |||
1466 | 49 | switch (position) { | 78 | switch (position) { |
1467 | 50 | default: | 79 | default: |
1468 | 51 | case Gtk.PositionType.BOTTOM: | 80 | case Gtk.PositionType.BOTTOM: |
1469 | 81 | center.y -= damount; | ||
1470 | 82 | static_center.y -= damount; | ||
1471 | 52 | hover_region.y -= amount; | 83 | hover_region.y -= amount; |
1472 | 53 | draw_region.y -= amount; | 84 | draw_region.y -= amount; |
1473 | 54 | break; | 85 | break; |
1474 | 55 | case Gtk.PositionType.TOP: | 86 | case Gtk.PositionType.TOP: |
1475 | 87 | center.y += damount; | ||
1476 | 88 | static_center.y += damount; | ||
1477 | 56 | hover_region.y += amount; | 89 | hover_region.y += amount; |
1478 | 57 | draw_region.y += amount; | 90 | draw_region.y += amount; |
1479 | 58 | break; | 91 | break; |
1480 | 59 | case Gtk.PositionType.LEFT: | 92 | case Gtk.PositionType.LEFT: |
1481 | 93 | center.x += damount; | ||
1482 | 94 | static_center.x += damount; | ||
1483 | 60 | hover_region.x += amount; | 95 | hover_region.x += amount; |
1484 | 61 | draw_region.x += amount; | 96 | draw_region.x += amount; |
1485 | 62 | break; | 97 | break; |
1486 | 63 | case Gtk.PositionType.RIGHT: | 98 | case Gtk.PositionType.RIGHT: |
1487 | 99 | center.x -= damount; | ||
1488 | 100 | static_center.x -= damount; | ||
1489 | 64 | hover_region.x -= amount; | 101 | hover_region.x -= amount; |
1490 | 65 | draw_region.x -= amount; | 102 | draw_region.x -= amount; |
1491 | 66 | break; | 103 | break; |
1492 | @@ -74,21 +111,29 @@ | |||
1493 | 74 | switch (position) { | 111 | switch (position) { |
1494 | 75 | default: | 112 | default: |
1495 | 76 | case Gtk.PositionType.BOTTOM: | 113 | case Gtk.PositionType.BOTTOM: |
1496 | 114 | center.x += damount; | ||
1497 | 115 | static_center.x += damount; | ||
1498 | 77 | hover_region.x += amount; | 116 | hover_region.x += amount; |
1499 | 78 | draw_region.x += amount; | 117 | draw_region.x += amount; |
1500 | 79 | background_region.x += amount; | 118 | background_region.x += amount; |
1501 | 80 | break; | 119 | break; |
1502 | 81 | case Gtk.PositionType.TOP: | 120 | case Gtk.PositionType.TOP: |
1503 | 121 | center.x += damount; | ||
1504 | 122 | static_center.x += damount; | ||
1505 | 82 | hover_region.x += amount; | 123 | hover_region.x += amount; |
1506 | 83 | draw_region.x += amount; | 124 | draw_region.x += amount; |
1507 | 84 | background_region.x += amount; | 125 | background_region.x += amount; |
1508 | 85 | break; | 126 | break; |
1509 | 86 | case Gtk.PositionType.LEFT: | 127 | case Gtk.PositionType.LEFT: |
1510 | 128 | center.y += damount; | ||
1511 | 129 | static_center.y += damount; | ||
1512 | 87 | hover_region.y += amount; | 130 | hover_region.y += amount; |
1513 | 88 | draw_region.y += amount; | 131 | draw_region.y += amount; |
1514 | 89 | background_region.y += amount; | 132 | background_region.y += amount; |
1515 | 90 | break; | 133 | break; |
1516 | 91 | case Gtk.PositionType.RIGHT: | 134 | case Gtk.PositionType.RIGHT: |
1517 | 135 | center.y += damount; | ||
1518 | 136 | static_center.y += damount; | ||
1519 | 92 | hover_region.y += amount; | 137 | hover_region.y += amount; |
1520 | 93 | draw_region.y += amount; | 138 | draw_region.y += amount; |
1521 | 94 | background_region.y += amount; | 139 | background_region.y += amount; |
1522 | @@ -102,7 +147,7 @@ | |||
1523 | 102 | public bool screen_is_composited { get; private set; } | 147 | public bool screen_is_composited { get; private set; } |
1524 | 103 | 148 | ||
1525 | 104 | Gdk.Rectangle static_dock_region; | 149 | Gdk.Rectangle static_dock_region; |
1527 | 105 | Gee.HashMap<DockElement, DockItemDrawValue?> draw_values; | 150 | Gee.HashMap<DockElement, DockItemDrawValue> draw_values; |
1528 | 106 | 151 | ||
1529 | 107 | Gdk.Rectangle monitor_geo; | 152 | Gdk.Rectangle monitor_geo; |
1530 | 108 | 153 | ||
1531 | @@ -121,9 +166,9 @@ | |||
1532 | 121 | construct | 166 | construct |
1533 | 122 | { | 167 | { |
1534 | 123 | static_dock_region = {}; | 168 | static_dock_region = {}; |
1536 | 124 | draw_values = new Gee.HashMap<DockElement, DockItemDrawValue?> (); | 169 | draw_values = new Gee.HashMap<DockElement, DockItemDrawValue> (); |
1537 | 125 | 170 | ||
1539 | 126 | controller.prefs.notify["Monitor"].connect (prefs_monitor_changed); | 171 | controller.prefs.notify.connect (prefs_changed); |
1540 | 127 | } | 172 | } |
1541 | 128 | 173 | ||
1542 | 129 | /** | 174 | /** |
1543 | @@ -151,11 +196,27 @@ | |||
1544 | 151 | screen.monitors_changed.disconnect (screen_changed); | 196 | screen.monitors_changed.disconnect (screen_changed); |
1545 | 152 | screen.size_changed.disconnect (screen_changed); | 197 | screen.size_changed.disconnect (screen_changed); |
1546 | 153 | screen.composited_changed.disconnect (screen_composited_changed); | 198 | screen.composited_changed.disconnect (screen_composited_changed); |
1548 | 154 | controller.prefs.notify["Monitor"].disconnect (prefs_monitor_changed); | 199 | controller.prefs.notify.disconnect (prefs_changed); |
1549 | 155 | 200 | ||
1550 | 156 | draw_values.clear (); | 201 | draw_values.clear (); |
1551 | 157 | } | 202 | } |
1552 | 158 | 203 | ||
1553 | 204 | void prefs_changed (Object prefs, ParamSpec prop) | ||
1554 | 205 | { | ||
1555 | 206 | switch (prop.name) { | ||
1556 | 207 | case "Monitor": | ||
1557 | 208 | prefs_monitor_changed (); | ||
1558 | 209 | break; | ||
1559 | 210 | case "ZoomPercent": | ||
1560 | 211 | case "ZoomEnabled": | ||
1561 | 212 | prefs_zoom_changed (); | ||
1562 | 213 | break; | ||
1563 | 214 | default: | ||
1564 | 215 | // Nothing important for us changed | ||
1565 | 216 | break; | ||
1566 | 217 | } | ||
1567 | 218 | } | ||
1568 | 219 | |||
1569 | 159 | public static string[] get_monitor_plug_names (Gdk.Screen screen) | 220 | public static string[] get_monitor_plug_names (Gdk.Screen screen) |
1570 | 160 | { | 221 | { |
1571 | 161 | int n_monitors = screen.get_n_monitors (); | 222 | int n_monitors = screen.get_n_monitors (); |
1572 | @@ -231,7 +292,12 @@ | |||
1573 | 231 | * Cached current icon size for the dock. | 292 | * Cached current icon size for the dock. |
1574 | 232 | */ | 293 | */ |
1575 | 233 | public int IconSize { get; private set; } | 294 | public int IconSize { get; private set; } |
1577 | 234 | 295 | ||
1578 | 296 | /** | ||
1579 | 297 | * Cached current icon size for the dock. | ||
1580 | 298 | */ | ||
1581 | 299 | public int ZoomIconSize { get; private set; } | ||
1582 | 300 | |||
1583 | 235 | /** | 301 | /** |
1584 | 236 | * Cached position of the dock. | 302 | * Cached position of the dock. |
1585 | 237 | */ | 303 | */ |
1586 | @@ -330,6 +396,10 @@ | |||
1587 | 330 | */ | 396 | */ |
1588 | 331 | int DockBackgroundWidth; | 397 | int DockBackgroundWidth; |
1589 | 332 | 398 | ||
1590 | 399 | double ZoomPercent; | ||
1591 | 400 | |||
1592 | 401 | Gdk.Rectangle background_rect; | ||
1593 | 402 | |||
1594 | 333 | /** | 403 | /** |
1595 | 334 | * The maximum item count which fit the dock in its maximum | 404 | * The maximum item count which fit the dock in its maximum |
1596 | 335 | * size with the current theme and icon-size. | 405 | * size with the current theme and icon-size. |
1597 | @@ -363,24 +433,6 @@ | |||
1598 | 363 | thaw_notify (); | 433 | thaw_notify (); |
1599 | 364 | } | 434 | } |
1600 | 365 | 435 | ||
1601 | 366 | /** | ||
1602 | 367 | * Resets all internal caches for the given item. | ||
1603 | 368 | * | ||
1604 | 369 | * @param item the dock item | ||
1605 | 370 | */ | ||
1606 | 371 | public void reset_item_cache (DockElement item) | ||
1607 | 372 | { | ||
1608 | 373 | draw_values.unset (item); | ||
1609 | 374 | } | ||
1610 | 375 | |||
1611 | 376 | /** | ||
1612 | 377 | * Resets all internal item caches. | ||
1613 | 378 | */ | ||
1614 | 379 | public void reset_item_caches () | ||
1615 | 380 | { | ||
1616 | 381 | draw_values.clear (); | ||
1617 | 382 | } | ||
1618 | 383 | |||
1619 | 384 | void update_caches (DockTheme theme) | 436 | void update_caches (DockTheme theme) |
1620 | 385 | { | 437 | { |
1621 | 386 | unowned DockPreferences prefs = controller.prefs; | 438 | unowned DockPreferences prefs = controller.prefs; |
1622 | @@ -413,6 +465,8 @@ | |||
1623 | 413 | } | 465 | } |
1624 | 414 | 466 | ||
1625 | 415 | IconSize = int.min (MaxIconSize, prefs.IconSize); | 467 | IconSize = int.min (MaxIconSize, prefs.IconSize); |
1626 | 468 | ZoomPercent = (screen_is_composited ? prefs.ZoomPercent / 100.0 : 1.0); | ||
1627 | 469 | ZoomIconSize = (screen_is_composited && prefs.ZoomEnabled ? (int) Math.round (IconSize * ZoomPercent) : IconSize); | ||
1628 | 416 | 470 | ||
1629 | 417 | var scaled_icon_size = IconSize / 10.0; | 471 | var scaled_icon_size = IconSize / 10.0; |
1630 | 418 | 472 | ||
1631 | @@ -445,8 +499,14 @@ | |||
1632 | 445 | extra_hide_offset = (IconShadowSize - top_offset); | 499 | extra_hide_offset = (IconShadowSize - top_offset); |
1633 | 446 | else | 500 | else |
1634 | 447 | extra_hide_offset = 0; | 501 | extra_hide_offset = 0; |
1635 | 502 | } | ||
1636 | 503 | |||
1637 | 504 | void prefs_zoom_changed () | ||
1638 | 505 | { | ||
1639 | 506 | unowned DockPreferences prefs = controller.prefs; | ||
1640 | 448 | 507 | ||
1642 | 449 | draw_values.clear (); | 508 | ZoomPercent = (screen_is_composited ? prefs.ZoomPercent / 100.0 : 1.0); |
1643 | 509 | ZoomIconSize = (screen_is_composited && prefs.ZoomEnabled ? (int) Math.round (IconSize * ZoomPercent) : IconSize); | ||
1644 | 450 | } | 510 | } |
1645 | 451 | 511 | ||
1646 | 452 | /** | 512 | /** |
1647 | @@ -563,6 +623,15 @@ | |||
1648 | 563 | window_scale_factor = controller.window.get_window ().get_scale_factor (); | 623 | window_scale_factor = controller.window.get_window ().get_scale_factor (); |
1649 | 564 | #endif | 624 | #endif |
1650 | 565 | 625 | ||
1651 | 626 | // If zoom is enabled extend cursor-region based on current hovered-item | ||
1652 | 627 | if (controller.prefs.ZoomEnabled) { | ||
1653 | 628 | unowned DockItem? hovered_item = controller.window.HoveredItem; | ||
1654 | 629 | if (hovered_item != null) { | ||
1655 | 630 | var hover_region = get_hover_region_for_element (hovered_item); | ||
1656 | 631 | cursor_region.union (hover_region, out cursor_region); | ||
1657 | 632 | } | ||
1658 | 633 | } | ||
1659 | 634 | |||
1660 | 566 | switch (Position) { | 635 | switch (Position) { |
1661 | 567 | default: | 636 | default: |
1662 | 568 | case Gtk.PositionType.BOTTOM: | 637 | case Gtk.PositionType.BOTTOM: |
1663 | @@ -691,9 +760,6 @@ | |||
1664 | 691 | 760 | ||
1665 | 692 | update_dock_position (); | 761 | update_dock_position (); |
1666 | 693 | 762 | ||
1667 | 694 | // FIXME Maybe no need to purge all cached values? | ||
1668 | 695 | draw_values.clear (); | ||
1669 | 696 | |||
1670 | 697 | if (!screen_is_composited | 763 | if (!screen_is_composited |
1671 | 698 | || old_region.x != static_dock_region.x | 764 | || old_region.x != static_dock_region.x |
1672 | 699 | || old_region.y != static_dock_region.y | 765 | || old_region.y != static_dock_region.y |
1673 | @@ -721,91 +787,337 @@ | |||
1674 | 721 | */ | 787 | */ |
1675 | 722 | public DockItemDrawValue get_draw_value_for_item (DockItem item) | 788 | public DockItemDrawValue get_draw_value_for_item (DockItem item) |
1676 | 723 | { | 789 | { |
1686 | 724 | DockItemDrawValue? draw_value; | 790 | if (draw_values.size == 0) { |
1687 | 725 | 791 | critical ("Without draw_values there is trouble ahead"); | |
1688 | 726 | if ((draw_value = draw_values.get (item)) == null) { | 792 | update_draw_values (controller.VisibleItems); |
1689 | 727 | var hover_rect = internal_get_item_hover_region (item); | 793 | } |
1690 | 728 | var draw_rect = get_item_draw_region (hover_rect); | 794 | |
1691 | 729 | var background_rect = get_item_background_region (hover_rect); | 795 | var draw_value = draw_values[item]; |
1692 | 730 | 796 | if (draw_value == null) { | |
1693 | 731 | draw_value = { hover_rect, draw_rect, background_rect, 1.0, 0.0, 0.0, true }; | 797 | critical ("Without a draw_value there is trouble ahead for '%s'", item.Text); |
1694 | 732 | draw_values.set (item, draw_value); | 798 | draw_value = new DockItemDrawValue (); |
1695 | 733 | } | 799 | } |
1696 | 734 | 800 | ||
1697 | 735 | return draw_value; | 801 | return draw_value; |
1698 | 736 | } | 802 | } |
1699 | 737 | 803 | ||
1700 | 738 | /** | 804 | /** |
1701 | 805 | * Update and recalculated all internal draw-values using the given methodes for custom manipulations. | ||
1702 | 806 | * | ||
1703 | 807 | * @param items the ordered list of all current item which are suppose to be shown on the dock | ||
1704 | 808 | * @param func a function which adjusts the draw-value per item | ||
1705 | 809 | * @param post_func a function which post-processes all draw-values | ||
1706 | 810 | */ | ||
1707 | 811 | public void update_draw_values (Gee.ArrayList<unowned DockItem> items, DockItemDrawValueFunc? func = null, | ||
1708 | 812 | DrawValuesFunc? post_func = null) | ||
1709 | 813 | { | ||
1710 | 814 | unowned DockPreferences prefs = controller.prefs; | ||
1711 | 815 | |||
1712 | 816 | draw_values.clear (); | ||
1713 | 817 | |||
1714 | 818 | bool external_drag_active = controller.drag_manager.ExternalDragActive; | ||
1715 | 819 | |||
1716 | 820 | // first we do the math as if this is a top dock, to do this we need to set | ||
1717 | 821 | // up some "pretend" variables. we pretend we are a top dock because 0,0 is | ||
1718 | 822 | // at the top. | ||
1719 | 823 | int width = DockWidth; | ||
1720 | 824 | int height = DockHeight; | ||
1721 | 825 | int icon_size = IconSize; | ||
1722 | 826 | |||
1723 | 827 | double zoom_in_progress = controller.renderer.zoom_in_progress; | ||
1724 | 828 | Gdk.Point cursor = controller.renderer.local_cursor; | ||
1725 | 829 | |||
1726 | 830 | // "relocate" our cursor to be on the top | ||
1727 | 831 | switch (Position) { | ||
1728 | 832 | case Gtk.PositionType.RIGHT: | ||
1729 | 833 | cursor.x = width - cursor.x; | ||
1730 | 834 | break; | ||
1731 | 835 | case Gtk.PositionType.BOTTOM: | ||
1732 | 836 | cursor.y = height - cursor.y; | ||
1733 | 837 | break; | ||
1734 | 838 | default: | ||
1735 | 839 | break; | ||
1736 | 840 | } | ||
1737 | 841 | |||
1738 | 842 | // our width and height switch around if we have a vertical dock | ||
1739 | 843 | if (!is_horizontal_dock ()) { | ||
1740 | 844 | int tmp = cursor.y; | ||
1741 | 845 | cursor.y = cursor.x; | ||
1742 | 846 | cursor.x = tmp; | ||
1743 | 847 | |||
1744 | 848 | tmp = width; | ||
1745 | 849 | width = height; | ||
1746 | 850 | height = tmp; | ||
1747 | 851 | } | ||
1748 | 852 | |||
1749 | 853 | //FIXME | ||
1750 | 854 | // the line along the dock width about which the center of unzoomed icons sit | ||
1751 | 855 | double center_y = (is_horizontal_dock () ? static_dock_region.height / 2.0 : static_dock_region.width / 2.0); | ||
1752 | 856 | |||
1753 | 857 | double center_x = (icon_size + ItemPadding) / 2.0 + items_offset; | ||
1754 | 858 | if (Alignment == Gtk.Align.FILL) { | ||
1755 | 859 | switch (ItemsAlignment) { | ||
1756 | 860 | default: | ||
1757 | 861 | case Gtk.Align.FILL: | ||
1758 | 862 | case Gtk.Align.CENTER: | ||
1759 | 863 | if (is_horizontal_dock ()) | ||
1760 | 864 | center_x += static_dock_region.x + (static_dock_region.width - 2 * items_offset - items_width) / 2; | ||
1761 | 865 | else | ||
1762 | 866 | center_x += static_dock_region.y + (static_dock_region.height - 2 * items_offset - items_width) / 2; | ||
1763 | 867 | break; | ||
1764 | 868 | case Gtk.Align.START: | ||
1765 | 869 | break; | ||
1766 | 870 | case Gtk.Align.END: | ||
1767 | 871 | if (is_horizontal_dock ()) | ||
1768 | 872 | center_x += static_dock_region.x + (static_dock_region.width - 2 * items_offset - items_width); | ||
1769 | 873 | else | ||
1770 | 874 | center_x += static_dock_region.y + (static_dock_region.height - 2 * items_offset - items_width); | ||
1771 | 875 | break; | ||
1772 | 876 | } | ||
1773 | 877 | } else { | ||
1774 | 878 | if (is_horizontal_dock ()) | ||
1775 | 879 | center_x += static_dock_region.x; | ||
1776 | 880 | else | ||
1777 | 881 | center_x += static_dock_region.y; | ||
1778 | 882 | } | ||
1779 | 883 | |||
1780 | 884 | PointD center = { Math.floor (center_x), Math.floor (center_y) }; | ||
1781 | 885 | |||
1782 | 886 | // ZoomPercent is a number greater than 1. It should never be less than one. | ||
1783 | 887 | |||
1784 | 888 | // zoom_in_percent is a range of 1 to ZoomPercent. | ||
1785 | 889 | // We need a number that is 1 when ZoomIn is 0, and ZoomPercent when ZoomIn is 1. | ||
1786 | 890 | // Then we treat this as if it were the ZoomPercent for the rest of the calculation. | ||
1787 | 891 | double zoom_in_percent = (prefs.ZoomEnabled ? 1.0 + (ZoomPercent - 1.0) * zoom_in_progress : 1.0); | ||
1788 | 892 | double zoom_icon_size = (prefs.ZoomEnabled ? ZoomIconSize : 2.0 * icon_size); | ||
1789 | 893 | |||
1790 | 894 | foreach (unowned DockItem item in items) { | ||
1791 | 895 | DockItemDrawValue val = new DockItemDrawValue (); | ||
1792 | 896 | val.opacity = 1.0; | ||
1793 | 897 | val.darken = 0.0; | ||
1794 | 898 | val.lighten = 0.0; | ||
1795 | 899 | val.show_indicator = true; | ||
1796 | 900 | val.zoom = 1.0; | ||
1797 | 901 | |||
1798 | 902 | val.static_center = center; | ||
1799 | 903 | |||
1800 | 904 | // get us some handy doubles with fancy names | ||
1801 | 905 | double cursor_position = cursor.x; | ||
1802 | 906 | double center_position = center.x; | ||
1803 | 907 | |||
1804 | 908 | // offset from the center of the true position, ranged between 0 and the zoom size | ||
1805 | 909 | double offset = double.min (Math.fabs (cursor_position - center_position), zoom_icon_size); | ||
1806 | 910 | |||
1807 | 911 | double offset_percent; | ||
1808 | 912 | if (external_drag_active) { | ||
1809 | 913 | // Provide space for dropping between items | ||
1810 | 914 | offset += offset * zoom_icon_size / icon_size; | ||
1811 | 915 | offset_percent = double.min (1.0, offset / (zoom_icon_size + ZoomIconSize)); | ||
1812 | 916 | } else { | ||
1813 | 917 | offset_percent = offset / zoom_icon_size; | ||
1814 | 918 | } | ||
1815 | 919 | |||
1816 | 920 | if (offset_percent > 0.99) | ||
1817 | 921 | offset_percent = 1.0; | ||
1818 | 922 | |||
1819 | 923 | // pull in our offset to make things less spaced out | ||
1820 | 924 | // explaination since this is a bit tricky... | ||
1821 | 925 | // we have three terms, basically offset = f(x) * h(x) * g(x) | ||
1822 | 926 | // f(x) == offset identity | ||
1823 | 927 | // h(x) == a number from 0 to DockPreference.ZoomPercent - 1. This is used to get the smooth "zoom in" effect. | ||
1824 | 928 | // additionally serves to "curve" the offset based on the max zoom | ||
1825 | 929 | // g(x) == a term used to move the ends of the zoom inward. Precalculated that the edges should be 66% of the current | ||
1826 | 930 | // value. The center is 100%. (1 - offset_percent) == 0,1 distance from center | ||
1827 | 931 | // 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. | ||
1828 | 932 | |||
1829 | 933 | // for external drags with no zoom, we pretend there is actually a zoom of 200% | ||
1830 | 934 | if (external_drag_active && ZoomPercent == 1.0) | ||
1831 | 935 | offset *= zoom_in_progress / 2.0; | ||
1832 | 936 | else | ||
1833 | 937 | offset *= zoom_in_percent - 1.0; | ||
1834 | 938 | offset *= 1.0 - offset_percent / 3.0; | ||
1835 | 939 | |||
1836 | 940 | if (cursor_position > center_position) | ||
1837 | 941 | center_position -= offset; | ||
1838 | 942 | else | ||
1839 | 943 | center_position += offset; | ||
1840 | 944 | |||
1841 | 945 | // zoom is calculated as 1 through target_zoom (default 2). | ||
1842 | 946 | // The larger your offset, the smaller your zoom | ||
1843 | 947 | |||
1844 | 948 | // First we get the point on our curve that defines our current zoom | ||
1845 | 949 | // offset is always going to fall on a point on the curve >= 0 | ||
1846 | 950 | var zoom = 1.0 - Math.pow (offset_percent, 2); | ||
1847 | 951 | |||
1848 | 952 | // scale this to match our zoom_in_percent | ||
1849 | 953 | zoom = 1.0 + zoom * (zoom_in_percent - 1.0); | ||
1850 | 954 | |||
1851 | 955 | double zoomed_center_height = (icon_size * zoom / 2.0); | ||
1852 | 956 | |||
1853 | 957 | if (zoom == 1.0) | ||
1854 | 958 | center_position = Math.round (center_position); | ||
1855 | 959 | |||
1856 | 960 | val.center = { center_position, zoomed_center_height }; | ||
1857 | 961 | val.zoom = zoom; | ||
1858 | 962 | val.icon_size = Math.round (zoom * icon_size); | ||
1859 | 963 | |||
1860 | 964 | // now we undo our transforms to the point | ||
1861 | 965 | if (!is_horizontal_dock ()) { | ||
1862 | 966 | double tmp = val.center.y; | ||
1863 | 967 | val.center.y = val.center.x; | ||
1864 | 968 | val.center.x = tmp; | ||
1865 | 969 | |||
1866 | 970 | tmp = val.static_center.y; | ||
1867 | 971 | val.static_center.y = val.static_center.x; | ||
1868 | 972 | val.static_center.x = tmp; | ||
1869 | 973 | } | ||
1870 | 974 | |||
1871 | 975 | switch (Position) { | ||
1872 | 976 | case Gtk.PositionType.RIGHT: | ||
1873 | 977 | val.center.x = height - val.center.x; | ||
1874 | 978 | val.static_center.x = height - val.static_center.x; | ||
1875 | 979 | break; | ||
1876 | 980 | case Gtk.PositionType.BOTTOM: | ||
1877 | 981 | val.center.y = height - val.center.y; | ||
1878 | 982 | val.static_center.y = height - val.static_center.y; | ||
1879 | 983 | break; | ||
1880 | 984 | default: | ||
1881 | 985 | break; | ||
1882 | 986 | } | ||
1883 | 987 | |||
1884 | 988 | //FIXME | ||
1885 | 989 | val.move_in (Position, bottom_offset); | ||
1886 | 990 | |||
1887 | 991 | // let the draw-value be modified by the given function | ||
1888 | 992 | if (func != null) | ||
1889 | 993 | func (item, val); | ||
1890 | 994 | |||
1891 | 995 | draw_values[item] = val; | ||
1892 | 996 | |||
1893 | 997 | //FIXME | ||
1894 | 998 | // Don't reserve space for removed items | ||
1895 | 999 | if (item.RemoveTime == 0) | ||
1896 | 1000 | center.x += icon_size + ItemPadding; | ||
1897 | 1001 | } | ||
1898 | 1002 | |||
1899 | 1003 | if (post_func != null) | ||
1900 | 1004 | post_func (draw_values); | ||
1901 | 1005 | |||
1902 | 1006 | update_background_region (draw_values[items.first ()], draw_values[items.last ()]); | ||
1903 | 1007 | |||
1904 | 1008 | // precalculate and cache regions (for the current frame) | ||
1905 | 1009 | #if HAVE_GEE_0_8 | ||
1906 | 1010 | draw_values.map_iterator ().foreach ((i, val) => { | ||
1907 | 1011 | val.draw_region = get_item_draw_region (val); | ||
1908 | 1012 | val.hover_region = get_item_hover_region (val); | ||
1909 | 1013 | val.background_region = get_item_background_region (val); | ||
1910 | 1014 | return true; | ||
1911 | 1015 | }); | ||
1912 | 1016 | #else | ||
1913 | 1017 | var draw_values_it = draw_values.map_iterator (); | ||
1914 | 1018 | while (draw_values_it.next ()) { | ||
1915 | 1019 | var val = draw_values_it.get_value (); | ||
1916 | 1020 | val.draw_region = get_item_draw_region (val); | ||
1917 | 1021 | val.hover_region = get_item_hover_region (val); | ||
1918 | 1022 | val.background_region = get_item_background_region (val); | ||
1919 | 1023 | } | ||
1920 | 1024 | #endif | ||
1921 | 1025 | } | ||
1922 | 1026 | /** | ||
1923 | 739 | * The region for drawing a dock item. | 1027 | * The region for drawing a dock item. |
1924 | 740 | * | 1028 | * |
1930 | 741 | * @param hover_rect the item's hover region | 1029 | * @param val the item's DockItemDrawValue |
1931 | 742 | * @return the region for the dock item | 1030 | * @return the region for the dock item |
1932 | 743 | */ | 1031 | */ |
1933 | 744 | Gdk.Rectangle get_item_draw_region (Gdk.Rectangle hover_rect) | 1032 | Gdk.Rectangle get_item_draw_region (DockItemDrawValue val) |
1934 | 745 | { | 1033 | { |
1935 | 1034 | var width = val.icon_size, height = val.icon_size; | ||
1936 | 1035 | |||
1937 | 1036 | return { (int) Math.round (val.center.x - width / 2.0), | ||
1938 | 1037 | (int) Math.round (val.center.y - height / 2.0), | ||
1939 | 1038 | (int) width, | ||
1940 | 1039 | (int) height }; | ||
1941 | 1040 | } | ||
1942 | 1041 | |||
1943 | 1042 | /** | ||
1944 | 1043 | * The intersecting region of a dock item's hover region and the background. | ||
1945 | 1044 | * | ||
1946 | 1045 | * @param val the item's DockItemDrawValue | ||
1947 | 1046 | * @return the region for the dock item | ||
1948 | 1047 | */ | ||
1949 | 1048 | Gdk.Rectangle get_item_background_region (DockItemDrawValue val) | ||
1950 | 1049 | { | ||
1951 | 1050 | Gdk.Rectangle rect; | ||
1952 | 1051 | |||
1953 | 1052 | if (!val.hover_region.intersect (get_background_region (), out rect)) | ||
1954 | 1053 | return {}; | ||
1955 | 1054 | |||
1956 | 1055 | return rect; | ||
1957 | 1056 | } | ||
1958 | 1057 | |||
1959 | 1058 | /** | ||
1960 | 1059 | * The cursor region for interacting with a dock element. | ||
1961 | 1060 | * | ||
1962 | 1061 | * @param val the item's DockItemDrawValue | ||
1963 | 1062 | * @return the region for the dock item | ||
1964 | 1063 | */ | ||
1965 | 1064 | Gdk.Rectangle get_item_hover_region (DockItemDrawValue val) | ||
1966 | 1065 | { | ||
1967 | 1066 | Gdk.Rectangle rect; | ||
1968 | 1067 | |||
1969 | 746 | var item_padding = ItemPadding; | 1068 | var item_padding = ItemPadding; |
1970 | 747 | var top_padding = (top_offset < 0 ? 0 : top_offset); | 1069 | var top_padding = (top_offset < 0 ? 0 : top_offset); |
1971 | 748 | var bottom_padding = bottom_offset; | 1070 | var bottom_padding = bottom_offset; |
1972 | 1071 | var width = val.icon_size, height = val.icon_size; | ||
1973 | 749 | 1072 | ||
1974 | 1073 | // Apply scalable padding | ||
1975 | 750 | switch (Position) { | 1074 | switch (Position) { |
1976 | 751 | default: | 1075 | default: |
1977 | 752 | case Gtk.PositionType.BOTTOM: | 1076 | case Gtk.PositionType.BOTTOM: |
1982 | 753 | hover_rect.x += item_padding / 2; | 1077 | width += item_padding; |
1979 | 754 | hover_rect.y += top_padding; | ||
1980 | 755 | hover_rect.width -= item_padding; | ||
1981 | 756 | hover_rect.height -= bottom_padding + top_padding; | ||
1983 | 757 | break; | 1078 | break; |
1984 | 758 | case Gtk.PositionType.TOP: | 1079 | case Gtk.PositionType.TOP: |
1989 | 759 | hover_rect.x += item_padding / 2; | 1080 | width += item_padding; |
1986 | 760 | hover_rect.y += bottom_padding; | ||
1987 | 761 | hover_rect.width -= item_padding; | ||
1988 | 762 | hover_rect.height -= bottom_padding + top_padding; | ||
1990 | 763 | break; | 1081 | break; |
1991 | 764 | case Gtk.PositionType.LEFT: | 1082 | case Gtk.PositionType.LEFT: |
1996 | 765 | hover_rect.x += bottom_padding; | 1083 | height += item_padding; |
1993 | 766 | hover_rect.y += item_padding / 2; | ||
1994 | 767 | hover_rect.width -= bottom_padding + top_padding; | ||
1995 | 768 | hover_rect.height -= item_padding; | ||
1997 | 769 | break; | 1084 | break; |
1998 | 770 | case Gtk.PositionType.RIGHT: | 1085 | case Gtk.PositionType.RIGHT: |
2003 | 771 | hover_rect.x += top_padding; | 1086 | height += item_padding; |
2000 | 772 | hover_rect.y += item_padding / 2; | ||
2001 | 773 | hover_rect.width -= bottom_padding + top_padding; | ||
2002 | 774 | hover_rect.height -= item_padding; | ||
2004 | 775 | break; | 1087 | break; |
2005 | 776 | } | 1088 | } |
2006 | 777 | 1089 | ||
2019 | 778 | return hover_rect; | 1090 | rect = { (int) Math.round (val.center.x - width / 2.0), |
2020 | 779 | } | 1091 | (int) Math.round (val.center.y - height / 2.0), |
2021 | 780 | 1092 | (int) width, | |
2022 | 781 | /** | 1093 | (int) height }; |
2011 | 782 | * The intersecting region of a dock item's hover region and the background. | ||
2012 | 783 | * | ||
2013 | 784 | * @param rect the item's hover region | ||
2014 | 785 | * @return the region for the dock item | ||
2015 | 786 | */ | ||
2016 | 787 | Gdk.Rectangle get_item_background_region (Gdk.Rectangle rect) | ||
2017 | 788 | { | ||
2018 | 789 | var top_padding = (top_offset > 0 ? 0 : top_offset); | ||
2023 | 790 | 1094 | ||
2024 | 1095 | // Apply static padding | ||
2025 | 791 | switch (Position) { | 1096 | switch (Position) { |
2026 | 792 | default: | 1097 | default: |
2027 | 793 | case Gtk.PositionType.BOTTOM: | 1098 | case Gtk.PositionType.BOTTOM: |
2028 | 794 | rect.y -= top_padding; | 1099 | rect.y -= top_padding; |
2030 | 795 | rect.height += top_padding; | 1100 | rect.height += bottom_padding + top_padding; |
2031 | 796 | break; | 1101 | break; |
2032 | 797 | case Gtk.PositionType.TOP: | 1102 | case Gtk.PositionType.TOP: |
2034 | 798 | rect.height += top_padding; | 1103 | rect.y -= bottom_padding; |
2035 | 1104 | rect.height += bottom_padding + top_padding; | ||
2036 | 799 | break; | 1105 | break; |
2037 | 800 | case Gtk.PositionType.LEFT: | 1106 | case Gtk.PositionType.LEFT: |
2039 | 801 | rect.width += top_padding; | 1107 | rect.x -= bottom_padding; |
2040 | 1108 | rect.width += bottom_padding + top_padding; | ||
2041 | 802 | break; | 1109 | break; |
2042 | 803 | case Gtk.PositionType.RIGHT: | 1110 | case Gtk.PositionType.RIGHT: |
2043 | 804 | rect.x -= top_padding; | 1111 | rect.x -= top_padding; |
2045 | 805 | rect.width += top_padding; | 1112 | rect.width += bottom_padding + top_padding; |
2046 | 806 | break; | 1113 | break; |
2047 | 807 | } | 1114 | } |
2048 | 808 | 1115 | ||
2049 | 1116 | Gdk.Rectangle background_region; | ||
2050 | 1117 | |||
2051 | 1118 | if (rect.intersect (get_background_region (), out background_region)) | ||
2052 | 1119 | background_region.union (get_item_draw_region (val), out rect); | ||
2053 | 1120 | |||
2054 | 809 | return rect; | 1121 | return rect; |
2055 | 810 | } | 1122 | } |
2056 | 811 | 1123 | ||
2057 | @@ -815,7 +1127,7 @@ | |||
2058 | 815 | * @param element the dock element to find a region for | 1127 | * @param element the dock element to find a region for |
2059 | 816 | * @return the region for the dock item | 1128 | * @return the region for the dock item |
2060 | 817 | */ | 1129 | */ |
2062 | 818 | public Gdk.Rectangle get_item_hover_region (DockElement element) | 1130 | public Gdk.Rectangle get_hover_region_for_element (DockElement element) |
2063 | 819 | { | 1131 | { |
2064 | 820 | unowned DockItem? item = (element as DockItem); | 1132 | unowned DockItem? item = (element as DockItem); |
2065 | 821 | if (item != null) | 1133 | if (item != null) |
2066 | @@ -830,73 +1142,16 @@ | |||
2067 | 830 | if (items.size == 0) | 1142 | if (items.size == 0) |
2068 | 831 | return {}; | 1143 | return {}; |
2069 | 832 | 1144 | ||
2071 | 833 | var first_rect = get_item_hover_region (items.first ()); | 1145 | var first_rect = get_hover_region_for_element (items.first ()); |
2072 | 834 | if (items.size == 1) | 1146 | if (items.size == 1) |
2073 | 835 | return first_rect; | 1147 | return first_rect; |
2074 | 836 | 1148 | ||
2076 | 837 | var last_rect = get_item_hover_region (items.last ()); | 1149 | var last_rect = get_hover_region_for_element (items.last ()); |
2077 | 838 | 1150 | ||
2078 | 839 | Gdk.Rectangle result; | 1151 | Gdk.Rectangle result; |
2079 | 840 | first_rect.union (last_rect, out result); | 1152 | first_rect.union (last_rect, out result); |
2080 | 841 | return result; | 1153 | return result; |
2081 | 842 | } | 1154 | } |
2082 | 843 | |||
2083 | 844 | Gdk.Rectangle internal_get_item_hover_region (DockItem item) | ||
2084 | 845 | { | ||
2085 | 846 | Gdk.Rectangle rect = {}; | ||
2086 | 847 | |||
2087 | 848 | switch (Position) { | ||
2088 | 849 | default: | ||
2089 | 850 | case Gtk.PositionType.BOTTOM: | ||
2090 | 851 | rect.width = IconSize + ItemPadding; | ||
2091 | 852 | rect.height = VisibleDockHeight; | ||
2092 | 853 | rect.x = static_dock_region.x + items_offset + item.Position * (ItemPadding + IconSize); | ||
2093 | 854 | rect.y = DockHeight - rect.height; | ||
2094 | 855 | break; | ||
2095 | 856 | case Gtk.PositionType.TOP: | ||
2096 | 857 | rect.width = IconSize + ItemPadding; | ||
2097 | 858 | rect.height = VisibleDockHeight; | ||
2098 | 859 | rect.x = static_dock_region.x + items_offset + item.Position * (ItemPadding + IconSize); | ||
2099 | 860 | rect.y = 0; | ||
2100 | 861 | break; | ||
2101 | 862 | case Gtk.PositionType.LEFT: | ||
2102 | 863 | rect.height = IconSize + ItemPadding; | ||
2103 | 864 | rect.width = VisibleDockWidth; | ||
2104 | 865 | rect.y = static_dock_region.y + items_offset + item.Position * (ItemPadding + IconSize); | ||
2105 | 866 | rect.x = 0; | ||
2106 | 867 | break; | ||
2107 | 868 | case Gtk.PositionType.RIGHT: | ||
2108 | 869 | rect.height = IconSize + ItemPadding; | ||
2109 | 870 | rect.width = VisibleDockWidth; | ||
2110 | 871 | rect.y = static_dock_region.y + items_offset + item.Position * (ItemPadding + IconSize); | ||
2111 | 872 | rect.x = DockWidth - rect.width; | ||
2112 | 873 | break; | ||
2113 | 874 | } | ||
2114 | 875 | |||
2115 | 876 | if (Alignment != Gtk.Align.FILL) | ||
2116 | 877 | return rect; | ||
2117 | 878 | |||
2118 | 879 | switch (ItemsAlignment) { | ||
2119 | 880 | default: | ||
2120 | 881 | case Gtk.Align.FILL: | ||
2121 | 882 | case Gtk.Align.CENTER: | ||
2122 | 883 | if (is_horizontal_dock ()) | ||
2123 | 884 | rect.x += (static_dock_region.width - 2 * items_offset - items_width) / 2; | ||
2124 | 885 | else | ||
2125 | 886 | rect.y += (static_dock_region.height - 2 * items_offset - items_width) / 2; | ||
2126 | 887 | break; | ||
2127 | 888 | case Gtk.Align.START: | ||
2128 | 889 | break; | ||
2129 | 890 | case Gtk.Align.END: | ||
2130 | 891 | if (is_horizontal_dock ()) | ||
2131 | 892 | rect.x += (static_dock_region.width - 2 * items_offset - items_width); | ||
2132 | 893 | else | ||
2133 | 894 | rect.y += (static_dock_region.height - 2 * items_offset - items_width); | ||
2134 | 895 | break; | ||
2135 | 896 | } | ||
2136 | 897 | |||
2137 | 898 | return rect; | ||
2138 | 899 | } | ||
2139 | 900 | 1155 | ||
2140 | 901 | /** | 1156 | /** |
2141 | 902 | * Get's the x and y position to display a menu for a dock item. | 1157 | * Get's the x and y position to display a menu for a dock item. |
2142 | @@ -908,7 +1163,7 @@ | |||
2143 | 908 | */ | 1163 | */ |
2144 | 909 | public void get_menu_position (DockItem hovered, Gtk.Requisition requisition, out int x, out int y) | 1164 | public void get_menu_position (DockItem hovered, Gtk.Requisition requisition, out int x, out int y) |
2145 | 910 | { | 1165 | { |
2147 | 911 | var rect = get_item_hover_region (hovered); | 1166 | var rect = get_hover_region_for_element (hovered); |
2148 | 912 | 1167 | ||
2149 | 913 | var offset = 10; | 1168 | var offset = 10; |
2150 | 914 | switch (Position) { | 1169 | switch (Position) { |
2151 | @@ -941,25 +1196,26 @@ | |||
2152 | 941 | */ | 1196 | */ |
2153 | 942 | public void get_hover_position (DockItem hovered, out int x, out int y) | 1197 | public void get_hover_position (DockItem hovered, out int x, out int y) |
2154 | 943 | { | 1198 | { |
2156 | 944 | var rect = get_item_hover_region (hovered); | 1199 | var center = get_draw_value_for_item (hovered).static_center; |
2157 | 1200 | var offset = (ZoomIconSize - IconSize / 2.0); | ||
2158 | 945 | 1201 | ||
2159 | 946 | switch (Position) { | 1202 | switch (Position) { |
2160 | 947 | default: | 1203 | default: |
2161 | 948 | case Gtk.PositionType.BOTTOM: | 1204 | case Gtk.PositionType.BOTTOM: |
2164 | 949 | x = rect.x + win_x + rect.width / 2; | 1205 | x = (int) Math.round (center.x + win_x); |
2165 | 950 | y = rect.y + win_y; | 1206 | y = (int) Math.round (center.y + win_y - offset); |
2166 | 951 | break; | 1207 | break; |
2167 | 952 | case Gtk.PositionType.TOP: | 1208 | case Gtk.PositionType.TOP: |
2170 | 953 | x = rect.x + win_x + rect.width / 2; | 1209 | x = (int) Math.round (center.x + win_x); |
2171 | 954 | y = rect.y + win_y + rect.height; | 1210 | y = (int) Math.round (center.y + win_y + offset); |
2172 | 955 | break; | 1211 | break; |
2173 | 956 | case Gtk.PositionType.LEFT: | 1212 | case Gtk.PositionType.LEFT: |
2176 | 957 | y = rect.y + win_y + rect.height / 2; | 1213 | x = (int) Math.round (center.x + win_x + offset); |
2177 | 958 | x = rect.x + win_x + rect.width; | 1214 | y = (int) Math.round (center.y + win_y); |
2178 | 959 | break; | 1215 | break; |
2179 | 960 | case Gtk.PositionType.RIGHT: | 1216 | case Gtk.PositionType.RIGHT: |
2182 | 961 | y = rect.y + win_y + rect.height / 2; | 1217 | x = (int) Math.round (center.x + win_x - offset); |
2183 | 962 | x = rect.x + win_x; | 1218 | y = (int) Math.round (center.y + win_y); |
2184 | 963 | break; | 1219 | break; |
2185 | 964 | } | 1220 | } |
2186 | 965 | } | 1221 | } |
2187 | @@ -973,7 +1229,7 @@ | |||
2188 | 973 | */ | 1229 | */ |
2189 | 974 | public void get_urgent_glow_position (DockItem item, out int x, out int y) | 1230 | public void get_urgent_glow_position (DockItem item, out int x, out int y) |
2190 | 975 | { | 1231 | { |
2192 | 976 | var rect = get_item_hover_region (item); | 1232 | var rect = get_hover_region_for_element (item); |
2193 | 977 | var glow_size = GlowSize; | 1233 | var glow_size = GlowSize; |
2194 | 978 | 1234 | ||
2195 | 979 | switch (Position) { | 1235 | switch (Position) { |
2196 | @@ -1130,8 +1386,12 @@ | |||
2197 | 1130 | */ | 1386 | */ |
2198 | 1131 | public Gdk.Rectangle get_background_region () | 1387 | public Gdk.Rectangle get_background_region () |
2199 | 1132 | { | 1388 | { |
2202 | 1133 | var x = 0, y = 0; | 1389 | return background_rect; |
2203 | 1134 | var width = 0, height = 0; | 1390 | } |
2204 | 1391 | |||
2205 | 1392 | void update_background_region (DockItemDrawValue val_first, DockItemDrawValue val_last) | ||
2206 | 1393 | { | ||
2207 | 1394 | var x = 0, y = 0, width = 0, height = 0; | ||
2208 | 1135 | 1395 | ||
2209 | 1136 | if (screen_is_composited) { | 1396 | if (screen_is_composited) { |
2210 | 1137 | x = static_dock_region.x; | 1397 | x = static_dock_region.x; |
2211 | @@ -1143,27 +1403,64 @@ | |||
2212 | 1143 | height = DockHeight; | 1403 | height = DockHeight; |
2213 | 1144 | } | 1404 | } |
2214 | 1145 | 1405 | ||
2215 | 1406 | if (Alignment == Gtk.Align.FILL) { | ||
2216 | 1407 | switch (Position) { | ||
2217 | 1408 | default: | ||
2218 | 1409 | case Gtk.PositionType.BOTTOM: | ||
2219 | 1410 | x += (width - DockBackgroundWidth) / 2; | ||
2220 | 1411 | y += height - DockBackgroundHeight; | ||
2221 | 1412 | break; | ||
2222 | 1413 | case Gtk.PositionType.TOP: | ||
2223 | 1414 | x += (width - DockBackgroundWidth) / 2; | ||
2224 | 1415 | y = 0; | ||
2225 | 1416 | break; | ||
2226 | 1417 | case Gtk.PositionType.LEFT: | ||
2227 | 1418 | x = 0; | ||
2228 | 1419 | y += (height - DockBackgroundHeight) / 2; | ||
2229 | 1420 | break; | ||
2230 | 1421 | case Gtk.PositionType.RIGHT: | ||
2231 | 1422 | x += width - DockBackgroundWidth; | ||
2232 | 1423 | y += (height - DockBackgroundHeight) / 2; | ||
2233 | 1424 | break; | ||
2234 | 1425 | } | ||
2235 | 1426 | |||
2236 | 1427 | background_rect = { x, y, DockBackgroundWidth, DockBackgroundHeight }; | ||
2237 | 1428 | return; | ||
2238 | 1429 | } | ||
2239 | 1430 | |||
2240 | 1431 | var center_first = val_first.center; | ||
2241 | 1432 | var center_last = val_last.center; | ||
2242 | 1433 | var padding = IconSize + ItemPadding + 2 * HorizPadding + 4 * LineWidth; | ||
2243 | 1434 | |||
2244 | 1146 | switch (Position) { | 1435 | switch (Position) { |
2245 | 1147 | default: | 1436 | default: |
2246 | 1148 | case Gtk.PositionType.BOTTOM: | 1437 | case Gtk.PositionType.BOTTOM: |
2248 | 1149 | x += (width - DockBackgroundWidth) / 2; | 1438 | x = (int) Math.round (center_first.x - padding / 2.0); |
2249 | 1150 | y += height - DockBackgroundHeight; | 1439 | y += height - DockBackgroundHeight; |
2250 | 1440 | width = (int) Math.round (center_last.x - center_first.x + padding); | ||
2251 | 1441 | height = DockBackgroundHeight; | ||
2252 | 1151 | break; | 1442 | break; |
2253 | 1152 | case Gtk.PositionType.TOP: | 1443 | case Gtk.PositionType.TOP: |
2255 | 1153 | x += (width - DockBackgroundWidth) / 2; | 1444 | x = (int) Math.round (center_first.x - padding / 2.0); |
2256 | 1154 | y = 0; | 1445 | y = 0; |
2257 | 1446 | width = (int) Math.round (center_last.x - center_first.x + padding); | ||
2258 | 1447 | height = DockBackgroundHeight; | ||
2259 | 1155 | break; | 1448 | break; |
2260 | 1156 | case Gtk.PositionType.LEFT: | 1449 | case Gtk.PositionType.LEFT: |
2261 | 1157 | x = 0; | 1450 | x = 0; |
2263 | 1158 | y += (height - DockBackgroundHeight) / 2; | 1451 | y = (int) Math.round (center_first.y - padding / 2.0); |
2264 | 1452 | width = DockBackgroundWidth; | ||
2265 | 1453 | height = (int) Math.round (center_last.y - center_first.y + padding); | ||
2266 | 1159 | break; | 1454 | break; |
2267 | 1160 | case Gtk.PositionType.RIGHT: | 1455 | case Gtk.PositionType.RIGHT: |
2268 | 1161 | x += width - DockBackgroundWidth; | 1456 | x += width - DockBackgroundWidth; |
2270 | 1162 | y += (height - DockBackgroundHeight) / 2; | 1457 | y = (int) Math.round (center_first.y - padding / 2.0); |
2271 | 1458 | width = DockBackgroundWidth; | ||
2272 | 1459 | height = (int) Math.round (center_last.y - center_first.y + padding); | ||
2273 | 1163 | break; | 1460 | break; |
2274 | 1164 | } | 1461 | } |
2275 | 1165 | 1462 | ||
2277 | 1166 | return { x, y, DockBackgroundWidth, DockBackgroundHeight }; | 1463 | background_rect = { x, y, width, height }; |
2278 | 1167 | } | 1464 | } |
2279 | 1168 | 1465 | ||
2280 | 1169 | /** | 1466 | /** |
2281 | @@ -1175,7 +1472,7 @@ | |||
2282 | 1175 | */ | 1472 | */ |
2283 | 1176 | public Gdk.Rectangle get_icon_geometry (ApplicationDockItem item, bool for_hidden) | 1473 | public Gdk.Rectangle get_icon_geometry (ApplicationDockItem item, bool for_hidden) |
2284 | 1177 | { | 1474 | { |
2286 | 1178 | var region = get_item_hover_region (item); | 1475 | var region = get_hover_region_for_element (item); |
2287 | 1179 | 1476 | ||
2288 | 1180 | if (!for_hidden) { | 1477 | if (!for_hidden) { |
2289 | 1181 | region.x += win_x; | 1478 | region.x += win_x; |
2290 | 1182 | 1479 | ||
2291 | === modified file 'lib/Widgets/DockWindow.vala' | |||
2292 | --- lib/Widgets/DockWindow.vala 2015-06-10 16:44:08 +0000 | |||
2293 | +++ lib/Widgets/DockWindow.vala 2015-07-16 08:37:41 +0000 | |||
2294 | @@ -234,6 +234,7 @@ | |||
2295 | 234 | if (menu_is_visible ()) | 234 | if (menu_is_visible ()) |
2296 | 235 | return Gdk.EVENT_STOP; | 235 | return Gdk.EVENT_STOP; |
2297 | 236 | 236 | ||
2298 | 237 | controller.renderer.update_local_cursor ((int) event.x, (int) event.y); | ||
2299 | 237 | update_hovered ((int) event.x, (int) event.y); | 238 | update_hovered ((int) event.x, (int) event.y); |
2300 | 238 | 239 | ||
2301 | 239 | return Gdk.EVENT_PROPAGATE; | 240 | return Gdk.EVENT_PROPAGATE; |
2302 | @@ -394,7 +395,7 @@ | |||
2303 | 394 | 395 | ||
2304 | 395 | // check if there already was a hovered-item and if it is still hovered to speed up things | 396 | // check if there already was a hovered-item and if it is still hovered to speed up things |
2305 | 396 | if (HoveredItem != null) { | 397 | if (HoveredItem != null) { |
2307 | 397 | rect = position_manager.get_item_hover_region (HoveredItem); | 398 | rect = position_manager.get_hover_region_for_element (HoveredItem); |
2308 | 398 | if (y >= rect.y && y < rect.y + rect.height && x >= rect.x && x < rect.x + rect.width) | 399 | if (y >= rect.y && y < rect.y + rect.height && x >= rect.x && x < rect.x + rect.width) |
2309 | 399 | // Do not allow the hovered-item to be the drag-item | 400 | // Do not allow the hovered-item to be the drag-item |
2310 | 400 | if (drag_item == HoveredItem) { | 401 | if (drag_item == HoveredItem) { |
2311 | @@ -421,7 +422,7 @@ | |||
2312 | 421 | foreach (var element in controller.VisibleElements) { | 422 | foreach (var element in controller.VisibleElements) { |
2313 | 422 | item = (element as DockItem); | 423 | item = (element as DockItem); |
2314 | 423 | if (item != null) { | 424 | if (item != null) { |
2316 | 424 | rect = position_manager.get_item_hover_region (item); | 425 | rect = position_manager.get_hover_region_for_element (item); |
2317 | 425 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) | 426 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) |
2318 | 426 | continue; | 427 | continue; |
2319 | 427 | 428 | ||
2320 | @@ -438,7 +439,7 @@ | |||
2321 | 438 | if (provider == null) | 439 | if (provider == null) |
2322 | 439 | continue; | 440 | continue; |
2323 | 440 | 441 | ||
2325 | 441 | rect = position_manager.get_item_hover_region (provider); | 442 | rect = position_manager.get_hover_region_for_element (provider); |
2326 | 442 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) | 443 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) |
2327 | 443 | continue; | 444 | continue; |
2328 | 444 | 445 | ||
2329 | @@ -446,7 +447,7 @@ | |||
2330 | 446 | found_hovered_provider = true; | 447 | found_hovered_provider = true; |
2331 | 447 | 448 | ||
2332 | 448 | foreach (var element2 in provider.VisibleElements) { | 449 | foreach (var element2 in provider.VisibleElements) { |
2334 | 449 | rect = position_manager.get_item_hover_region (element2); | 450 | rect = position_manager.get_hover_region_for_element (element2); |
2335 | 450 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) | 451 | if (y < rect.y || y >= rect.y + rect.height || x < rect.x || x >= rect.x + rect.width) |
2336 | 451 | continue; | 452 | continue; |
2337 | 452 | 453 | ||
2338 | 453 | 454 | ||
2339 | === modified file 'lib/Widgets/PreferencesWindow.vala' | |||
2340 | --- lib/Widgets/PreferencesWindow.vala 2015-07-12 09:40:05 +0000 | |||
2341 | +++ lib/Widgets/PreferencesWindow.vala 2015-07-16 08:37:41 +0000 | |||
2342 | @@ -40,11 +40,13 @@ | |||
2343 | 40 | Gtk.SpinButton sp_hide_delay; | 40 | Gtk.SpinButton sp_hide_delay; |
2344 | 41 | Gtk.SpinButton sp_unhide_delay; | 41 | Gtk.SpinButton sp_unhide_delay; |
2345 | 42 | Gtk.Scale s_offset; | 42 | Gtk.Scale s_offset; |
2346 | 43 | Gtk.Scale s_zoom_percent; | ||
2347 | 43 | 44 | ||
2348 | 44 | Gtk.Adjustment adj_hide_delay; | 45 | Gtk.Adjustment adj_hide_delay; |
2349 | 45 | Gtk.Adjustment adj_unhide_delay; | 46 | Gtk.Adjustment adj_unhide_delay; |
2350 | 46 | Gtk.Adjustment adj_iconsize; | 47 | Gtk.Adjustment adj_iconsize; |
2351 | 47 | Gtk.Adjustment adj_offset; | 48 | Gtk.Adjustment adj_offset; |
2352 | 49 | Gtk.Adjustment adj_zoom_percent; | ||
2353 | 48 | 50 | ||
2354 | 49 | Gtk.Switch sw_hide; | 51 | Gtk.Switch sw_hide; |
2355 | 50 | Gtk.Switch sw_primary_display; | 52 | Gtk.Switch sw_primary_display; |
2356 | @@ -54,6 +56,7 @@ | |||
2357 | 54 | Gtk.Switch sw_auto_pinning; | 56 | Gtk.Switch sw_auto_pinning; |
2358 | 55 | Gtk.Switch sw_pressure_reveal; | 57 | Gtk.Switch sw_pressure_reveal; |
2359 | 56 | Gtk.Switch sw_show_dock_item; | 58 | Gtk.Switch sw_show_dock_item; |
2360 | 59 | Gtk.Switch sw_zoom_enabled; | ||
2361 | 57 | 60 | ||
2362 | 58 | public PreferencesWindow (DockPreferences prefs) | 61 | public PreferencesWindow (DockPreferences prefs) |
2363 | 59 | { | 62 | { |
2364 | @@ -105,7 +108,9 @@ | |||
2365 | 105 | adj_unhide_delay = builder.get_object ("adj_unhide_delay") as Gtk.Adjustment; | 108 | adj_unhide_delay = builder.get_object ("adj_unhide_delay") as Gtk.Adjustment; |
2366 | 106 | adj_iconsize = builder.get_object ("adj_iconsize") as Gtk.Adjustment; | 109 | adj_iconsize = builder.get_object ("adj_iconsize") as Gtk.Adjustment; |
2367 | 107 | adj_offset = builder.get_object ("adj_offset") as Gtk.Adjustment; | 110 | adj_offset = builder.get_object ("adj_offset") as Gtk.Adjustment; |
2368 | 111 | adj_zoom_percent = builder.get_object ("adj_zoom_percent") as Gtk.Adjustment; | ||
2369 | 108 | s_offset = builder.get_object ("s_offset") as Gtk.Scale; | 112 | s_offset = builder.get_object ("s_offset") as Gtk.Scale; |
2370 | 113 | s_zoom_percent = builder.get_object ("s_zoom_percent") as Gtk.Scale; | ||
2371 | 109 | sw_hide = builder.get_object ("sw_hide") as Gtk.Switch; | 114 | sw_hide = builder.get_object ("sw_hide") as Gtk.Switch; |
2372 | 110 | sw_primary_display = builder.get_object ("sw_primary_display") as Gtk.Switch; | 115 | sw_primary_display = builder.get_object ("sw_primary_display") as Gtk.Switch; |
2373 | 111 | sw_workspace_only = builder.get_object ("sw_workspace_only") as Gtk.Switch; | 116 | sw_workspace_only = builder.get_object ("sw_workspace_only") as Gtk.Switch; |
2374 | @@ -114,6 +119,7 @@ | |||
2375 | 114 | sw_auto_pinning = builder.get_object ("sw_auto_pinning") as Gtk.Switch; | 119 | sw_auto_pinning = builder.get_object ("sw_auto_pinning") as Gtk.Switch; |
2376 | 115 | sw_pressure_reveal = builder.get_object ("sw_pressure_reveal") as Gtk.Switch; | 120 | sw_pressure_reveal = builder.get_object ("sw_pressure_reveal") as Gtk.Switch; |
2377 | 116 | sw_show_dock_item = builder.get_object ("sw_show_dock_item") as Gtk.Switch; | 121 | sw_show_dock_item = builder.get_object ("sw_show_dock_item") as Gtk.Switch; |
2378 | 122 | sw_zoom_enabled = builder.get_object ("sw_zoom_enabled") as Gtk.Switch; | ||
2379 | 117 | cb_alignment = builder.get_object ("cb_alignment") as Gtk.ComboBoxText; | 123 | cb_alignment = builder.get_object ("cb_alignment") as Gtk.ComboBoxText; |
2380 | 118 | cb_items_alignment = builder.get_object ("cb_items_alignment") as Gtk.ComboBoxText; | 124 | cb_items_alignment = builder.get_object ("cb_items_alignment") as Gtk.ComboBoxText; |
2381 | 119 | 125 | ||
2382 | @@ -197,6 +203,12 @@ | |||
2383 | 197 | case "UnhideDelay": | 203 | case "UnhideDelay": |
2384 | 198 | adj_unhide_delay.value = prefs.UnhideDelay; | 204 | adj_unhide_delay.value = prefs.UnhideDelay; |
2385 | 199 | break; | 205 | break; |
2386 | 206 | case "ZoomEnabled": | ||
2387 | 207 | sw_zoom_enabled.set_active (prefs.ZoomEnabled); | ||
2388 | 208 | break; | ||
2389 | 209 | case "ZoomPercent": | ||
2390 | 210 | adj_zoom_percent.value = prefs.ZoomPercent; | ||
2391 | 211 | break; | ||
2392 | 200 | // Ignored settings | 212 | // Ignored settings |
2393 | 201 | case "DockItems": | 213 | case "DockItems": |
2394 | 202 | break; | 214 | break; |
2395 | @@ -292,6 +304,17 @@ | |||
2396 | 292 | prefs.ShowDockItem = ((Gtk.Switch) widget).get_active (); | 304 | prefs.ShowDockItem = ((Gtk.Switch) widget).get_active (); |
2397 | 293 | } | 305 | } |
2398 | 294 | 306 | ||
2399 | 307 | void zoom_enabled_toggled (GLib.Object widget, ParamSpec param) | ||
2400 | 308 | { | ||
2401 | 309 | if (((Gtk.Switch) widget).get_active ()) { | ||
2402 | 310 | prefs.ZoomEnabled = true; | ||
2403 | 311 | s_zoom_percent.sensitive = true; | ||
2404 | 312 | } else { | ||
2405 | 313 | prefs.ZoomEnabled = false; | ||
2406 | 314 | s_zoom_percent.sensitive = false; | ||
2407 | 315 | } | ||
2408 | 316 | } | ||
2409 | 317 | |||
2410 | 295 | void iconsize_changed (Gtk.Adjustment adj) | 318 | void iconsize_changed (Gtk.Adjustment adj) |
2411 | 296 | { | 319 | { |
2412 | 297 | prefs.IconSize = (int) adj.value; | 320 | prefs.IconSize = (int) adj.value; |
2413 | @@ -312,6 +335,11 @@ | |||
2414 | 312 | prefs.UnhideDelay = (int) adj.value; | 335 | prefs.UnhideDelay = (int) adj.value; |
2415 | 313 | } | 336 | } |
2416 | 314 | 337 | ||
2417 | 338 | void zoom_percent_changed (Gtk.Adjustment adj) | ||
2418 | 339 | { | ||
2419 | 340 | prefs.ZoomPercent = (int) adj.value; | ||
2420 | 341 | } | ||
2421 | 342 | |||
2422 | 315 | void monitor_changed (Gtk.ComboBox widget) | 343 | void monitor_changed (Gtk.ComboBox widget) |
2423 | 316 | { | 344 | { |
2424 | 317 | prefs.Monitor = ((Gtk.ComboBoxText) widget).get_active_text (); | 345 | prefs.Monitor = ((Gtk.ComboBoxText) widget).get_active_text (); |
2425 | @@ -329,6 +357,7 @@ | |||
2426 | 329 | cb_display_plug.changed.connect (monitor_changed); | 357 | cb_display_plug.changed.connect (monitor_changed); |
2427 | 330 | adj_iconsize.value_changed.connect (iconsize_changed); | 358 | adj_iconsize.value_changed.connect (iconsize_changed); |
2428 | 331 | adj_offset.value_changed.connect (offset_changed); | 359 | adj_offset.value_changed.connect (offset_changed); |
2429 | 360 | adj_zoom_percent.value_changed.connect (zoom_percent_changed); | ||
2430 | 332 | sw_hide.notify["active"].connect (hide_toggled); | 361 | sw_hide.notify["active"].connect (hide_toggled); |
2431 | 333 | sw_primary_display.notify["active"].connect (primary_display_toggled); | 362 | sw_primary_display.notify["active"].connect (primary_display_toggled); |
2432 | 334 | sw_workspace_only.notify["active"].connect (workspace_only_toggled); | 363 | sw_workspace_only.notify["active"].connect (workspace_only_toggled); |
2433 | @@ -337,6 +366,7 @@ | |||
2434 | 337 | sw_auto_pinning.notify["active"].connect (auto_pinning_toggled); | 366 | sw_auto_pinning.notify["active"].connect (auto_pinning_toggled); |
2435 | 338 | sw_pressure_reveal.notify["active"].connect (pressure_reveal_toggled); | 367 | sw_pressure_reveal.notify["active"].connect (pressure_reveal_toggled); |
2436 | 339 | sw_show_dock_item.notify["active"].connect (show_dock_item_toggled); | 368 | sw_show_dock_item.notify["active"].connect (show_dock_item_toggled); |
2437 | 369 | sw_zoom_enabled.notify["active"].connect (zoom_enabled_toggled); | ||
2438 | 340 | cb_alignment.changed.connect (cb_alignment_changed); | 370 | cb_alignment.changed.connect (cb_alignment_changed); |
2439 | 341 | cb_items_alignment.changed.connect (cb_items_alignment_changed); | 371 | cb_items_alignment.changed.connect (cb_items_alignment_changed); |
2440 | 342 | } | 372 | } |
2441 | @@ -373,7 +403,9 @@ | |||
2442 | 373 | 403 | ||
2443 | 374 | adj_iconsize.value = prefs.IconSize; | 404 | adj_iconsize.value = prefs.IconSize; |
2444 | 375 | adj_offset.value = prefs.Offset; | 405 | adj_offset.value = prefs.Offset; |
2445 | 406 | adj_zoom_percent.value = prefs.ZoomPercent; | ||
2446 | 376 | s_offset.sensitive = (prefs.Alignment == Gtk.Align.CENTER); | 407 | s_offset.sensitive = (prefs.Alignment == Gtk.Align.CENTER); |
2447 | 408 | s_zoom_percent.sensitive = prefs.ZoomEnabled; | ||
2448 | 377 | sw_hide.set_active (prefs.HideMode != HideType.NONE); | 409 | sw_hide.set_active (prefs.HideMode != HideType.NONE); |
2449 | 378 | sw_primary_display.set_active (prefs.Monitor == ""); | 410 | sw_primary_display.set_active (prefs.Monitor == ""); |
2450 | 379 | sw_workspace_only.set_active (prefs.CurrentWorkspaceOnly); | 411 | sw_workspace_only.set_active (prefs.CurrentWorkspaceOnly); |
2451 | @@ -382,6 +414,7 @@ | |||
2452 | 382 | sw_auto_pinning.set_active (prefs.AutoPinning); | 414 | sw_auto_pinning.set_active (prefs.AutoPinning); |
2453 | 383 | sw_pressure_reveal.set_active (prefs.PressureReveal); | 415 | sw_pressure_reveal.set_active (prefs.PressureReveal); |
2454 | 384 | sw_show_dock_item.set_active (prefs.ShowDockItem); | 416 | sw_show_dock_item.set_active (prefs.ShowDockItem); |
2455 | 417 | sw_zoom_enabled.set_active (prefs.ZoomEnabled); | ||
2456 | 385 | cb_alignment.active_id = ((int) prefs.Alignment).to_string (); | 418 | cb_alignment.active_id = ((int) prefs.Alignment).to_string (); |
2457 | 386 | cb_items_alignment.active_id = ((int) prefs.ItemsAlignment).to_string (); | 419 | cb_items_alignment.active_id = ((int) prefs.ItemsAlignment).to_string (); |
2458 | 387 | cb_items_alignment.sensitive = (prefs.Alignment == Gtk.Align.FILL); | 420 | cb_items_alignment.sensitive = (prefs.Alignment == Gtk.Align.FILL); |