Merge lp:~donadigo/screenshot-tool/box-selection into lp:~elementary-apps/screenshot-tool/trunk
- box-selection
- Merge into trunk
Proposed by
Adam Bieńkowski
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Felipe Escoto | ||||||||
Approved revision: | 223 | ||||||||
Merged at revision: | 219 | ||||||||
Proposed branch: | lp:~donadigo/screenshot-tool/box-selection | ||||||||
Merge into: | lp:~elementary-apps/screenshot-tool/trunk | ||||||||
Diff against target: |
599 lines (+203/-231) 4 files modified
src/Screenshot.vala (+1/-7) src/ScreenshotWindow.vala (+87/-121) src/Widgets/SaveDialog.vala (+0/-1) src/Widgets/SelectionArea.vala (+115/-102) |
||||||||
To merge this branch: | bzr merge lp:~donadigo/screenshot-tool/box-selection | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
elementary Apps team | Pending | ||
Review via email: mp+304854@code.launchpad.net |
Commit message
* Use box selection for area selection
* Ignore window struts
Description of the change
This branch changes the current behaviour of area selection to be a selection box rather than a static window which can be moved / resized.
It also fixes the issue with window struts which are now ignored by setting the window type to POPUP.
Previous iterations of this code were using "begin_resize_drag" which didn't really fit the purpose of box selection, so I changed it to manual handling of events much of how it is in the gnome-screenshot.
The diff also features a little bit of codestyle (and logic) fixes.
To post a comment you must log in.
- 221. By Adam Bieńkowski
-
Fix area command line argument
- 222. By Adam Bieńkowski
-
Public back to private
- 223. By Adam Bieńkowski
-
Actually close on escape from area selection
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/Screenshot.vala' |
2 | --- src/Screenshot.vala 2016-06-24 09:19:54 +0000 |
3 | +++ src/Screenshot.vala 2016-09-03 19:11:26 +0000 |
4 | @@ -142,13 +142,7 @@ |
5 | } else { |
6 | window = new ScreenshotWindow.from_cmd (action, delay, grab_pointer, redact); |
7 | window.set_application (this); |
8 | - window.show_all (); |
9 | - |
10 | - if (action != 3) { |
11 | - window.take_clicked (); |
12 | - } else { |
13 | - window.present (); |
14 | - } |
15 | + window.take_clicked (); |
16 | } |
17 | |
18 | return 0; |
19 | |
20 | === modified file 'src/ScreenshotWindow.vala' |
21 | --- src/ScreenshotWindow.vala 2016-05-08 03:12:21 +0000 |
22 | +++ src/ScreenshotWindow.vala 2016-09-03 19:11:26 +0000 |
23 | @@ -47,9 +47,6 @@ |
24 | private bool redact; |
25 | private int delay; |
26 | |
27 | - private Screenshot.Widgets.SelectionArea selection_area; |
28 | - private Screenshot.Widgets.SaveDialog save_dialog; |
29 | - |
30 | /** |
31 | * ScreenshotWindow Constructor |
32 | */ |
33 | @@ -189,33 +186,15 @@ |
34 | */ |
35 | all.toggled.connect (() => { |
36 | capture_mode = CaptureType.SCREEN; |
37 | - |
38 | - if (selection_area != null) { |
39 | - selection_area.destroy (); |
40 | - selection_area = null; |
41 | - } |
42 | }); |
43 | |
44 | curr_window.toggled.connect (() => { |
45 | capture_mode = CaptureType.CURRENT_WINDOW; |
46 | - |
47 | - if (selection_area != null) { |
48 | - selection_area.destroy (); |
49 | - selection_area = null; |
50 | - } |
51 | }); |
52 | |
53 | selection.toggled.connect (() => { |
54 | capture_mode = CaptureType.AREA; |
55 | - |
56 | - if (selection_area == null) { |
57 | - selection_area = new Screenshot.Widgets.SelectionArea (); |
58 | - selection_area.show_all (); |
59 | - } else |
60 | - selection_area.present (); |
61 | - |
62 | - set_transient_for (selection_area); |
63 | - present(); |
64 | + present (); |
65 | }); |
66 | |
67 | pointer_switch.notify["active"].connect (() => { |
68 | @@ -241,84 +220,69 @@ |
69 | take_btn.clicked.connect (take_clicked); |
70 | cancel_btn.clicked.connect (cancel_clicked); |
71 | |
72 | - focus_in_event.connect (() => { |
73 | - if (selection_area != null && selection_area.is_visible ()) { |
74 | - selection_area.present (); |
75 | - this.present (); |
76 | - } else { |
77 | - this.present (); |
78 | - } |
79 | - |
80 | - return false; |
81 | - }); |
82 | - |
83 | // Pack the main grid into the window |
84 | Gtk.Box content = get_content_area () as Gtk.Box; |
85 | content.add (grid); |
86 | } |
87 | |
88 | - private bool grab_save (Gdk.Window win, bool extra_time) { |
89 | + private bool grab_save (Gdk.Window? win, bool extra_time) { |
90 | if (extra_time) { |
91 | redact_text (true); |
92 | - Timeout.add (1000, () => { |
93 | - grab_save (win, false); |
94 | - return false; |
95 | + Timeout.add_seconds (1, () => { |
96 | + return grab_save (win, false); |
97 | }); |
98 | |
99 | return false; |
100 | } |
101 | |
102 | - Timeout.add (250, () => { |
103 | - selection_area.set_opacity (1); |
104 | - this.set_opacity (1); |
105 | - return false; |
106 | - }); |
107 | - |
108 | - Gdk.Pixbuf screenshot; |
109 | - Gdk.Rectangle win_rect; |
110 | - int width, height; |
111 | - |
112 | - win_rect = Gdk.Rectangle (); |
113 | - |
114 | - width = win.get_width (); |
115 | - height = win.get_height (); |
116 | - |
117 | - screenshot = Gdk.pixbuf_get_from_window (win, 0, 0, width, height); |
118 | - |
119 | - win_rect.x = 0; |
120 | - win_rect.y = 0; |
121 | - win_rect.width = width; |
122 | - win_rect.height = height; |
123 | - |
124 | + var win_rect = Gdk.Rectangle (); |
125 | + var root = Gdk.get_default_root_window (); |
126 | + |
127 | + if (win == null) { |
128 | + win = root; |
129 | + } |
130 | + |
131 | + Gdk.Pixbuf? screenshot; |
132 | if (capture_mode == CaptureType.AREA) { |
133 | - |
134 | - screenshot = new Gdk.Pixbuf.subpixbuf (screenshot, selection_area.x, selection_area.y, selection_area.w, selection_area.h); |
135 | - |
136 | - win_rect.x = selection_area.x; |
137 | - win_rect.y = selection_area.y; |
138 | - win_rect.width = selection_area.w; |
139 | - win_rect.height = selection_area.h; |
140 | + Gdk.Rectangle selection_rect; |
141 | + win.get_frame_extents (out selection_rect); |
142 | + |
143 | + screenshot = new Gdk.Pixbuf.subpixbuf (Gdk.pixbuf_get_from_window (root, 0, 0, root.get_width (), root.get_height ()), |
144 | + selection_rect.x, selection_rect.y, selection_rect.width, selection_rect.height); |
145 | + |
146 | + win_rect.x = selection_rect.x; |
147 | + win_rect.y = selection_rect.y; |
148 | + win_rect.width = selection_rect.width; |
149 | + win_rect.height = selection_rect.height; |
150 | + } else { |
151 | + int width = win.get_width (); |
152 | + int height = win.get_height (); |
153 | + |
154 | + screenshot = Gdk.pixbuf_get_from_window (win, 0, 0, width, height); |
155 | + |
156 | + win_rect.x = 0; |
157 | + win_rect.y = 0; |
158 | + win_rect.width = width; |
159 | + win_rect.height = height; |
160 | + } |
161 | + |
162 | + if (screenshot == null) { |
163 | + show_error_dialog (); |
164 | + return false; |
165 | } |
166 | |
167 | if (mouse_pointer) { |
168 | - |
169 | - Gdk.Cursor cursor; |
170 | - Gdk.Pixbuf cursor_pixbuf; |
171 | - |
172 | - cursor = new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.LEFT_PTR); |
173 | - cursor_pixbuf = cursor.get_image (); |
174 | + var cursor = new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.LEFT_PTR); |
175 | + var cursor_pixbuf = cursor.get_image (); |
176 | |
177 | if (cursor_pixbuf != null) { |
178 | - |
179 | - Gdk.DeviceManager manager; |
180 | - Gdk.Device device; |
181 | - Gdk.Rectangle cursor_rect; |
182 | - int cx, cy; |
183 | - |
184 | - manager = Gdk.Display.get_default ().get_device_manager (); |
185 | - device = manager.get_client_pointer (); |
186 | + var manager = Gdk.Display.get_default ().get_device_manager (); |
187 | + var device = manager.get_client_pointer (); |
188 | + |
189 | + int cx, cy; |
190 | win.get_device_position (device, out cx, out cy, null); |
191 | - cursor_rect = Gdk.Rectangle (); |
192 | + |
193 | + var cursor_rect = Gdk.Rectangle (); |
194 | |
195 | cursor_rect.x = cx + win_rect.x; |
196 | cursor_rect.y = cy + win_rect.y; |
197 | @@ -335,12 +299,11 @@ |
198 | redact_text (false); |
199 | } |
200 | |
201 | - save_dialog = new Screenshot.Widgets.SaveDialog (screenshot, settings, this); |
202 | - |
203 | + var save_dialog = new Screenshot.Widgets.SaveDialog (screenshot, settings, this); |
204 | save_dialog.save_response.connect ((response, folder_dir, output_name, format) => { |
205 | save_dialog.destroy (); |
206 | |
207 | - if (response == true) { |
208 | + if (response) { |
209 | string[] formats = {".png", ".jpg", ".jpeg",".bmp", ".tiff"}; |
210 | string output = output_name; |
211 | |
212 | @@ -353,16 +316,11 @@ |
213 | try { |
214 | screenshot.save (file_name, format); |
215 | |
216 | - if (close_on_save == true) { |
217 | + if (close_on_save) { |
218 | this.destroy (); |
219 | } |
220 | } catch (GLib.Error e) { |
221 | - Gtk.MessageDialog dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, |
222 | - Gtk.ButtonsType.CLOSE, _("Could not capture screenshot")); |
223 | - dialog.secondary_text = _("Image not saved"); |
224 | - dialog.deletable = false; |
225 | - dialog.run (); |
226 | - dialog.destroy (); |
227 | + show_error_dialog (); |
228 | debug (e.message); |
229 | } |
230 | } |
231 | @@ -376,6 +334,8 @@ |
232 | this.destroy (); |
233 | }); |
234 | |
235 | + save_dialog.show_all (); |
236 | + |
237 | return false; |
238 | } |
239 | |
240 | @@ -394,18 +354,12 @@ |
241 | } |
242 | |
243 | private void capture_screen () { |
244 | - Gdk.Window win = null; |
245 | - |
246 | - win = Gdk.get_default_root_window(); |
247 | - |
248 | - this.set_opacity (0); |
249 | this.hide (); |
250 | - Timeout.add (delay * 1000 - (redact? 1000 : 0), () => { |
251 | + |
252 | + Timeout.add_seconds (delay - (redact ? 1 : 0), () => { |
253 | this.present (); |
254 | - grab_save (win, redact); |
255 | - return false; |
256 | + return grab_save (null, redact); |
257 | }); |
258 | - |
259 | } |
260 | |
261 | private void capture_window () { |
262 | @@ -415,9 +369,8 @@ |
263 | |
264 | screen = Gdk.Screen.get_default (); |
265 | |
266 | - this.set_opacity (0); |
267 | this.hide (); |
268 | - Timeout.add (delay * 1000 - (redact? 1000 : 0), () => { |
269 | + Timeout.add_seconds (delay - (redact ? 1 : 0), () => { |
270 | list = screen.get_window_stack (); |
271 | foreach (Gdk.Window item in list) { |
272 | if (screen.get_active_window () == item) { |
273 | @@ -427,17 +380,15 @@ |
274 | |
275 | this.present (); |
276 | |
277 | - if (win != null) |
278 | + if (win != null) { |
279 | grab_save (win, redact); |
280 | - else { |
281 | + } else { |
282 | Gtk.MessageDialog dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, |
283 | - Gtk.ButtonsType.CLOSE, _("Could not capture screenshot")); |
284 | + Gtk.ButtonsType.CLOSE, _("Could not capture screenshot")); |
285 | dialog.secondary_text = _("Couldn't find an active window"); |
286 | dialog.deletable = false; |
287 | dialog.run (); |
288 | dialog.destroy (); |
289 | - |
290 | - this.set_opacity (1); |
291 | } |
292 | |
293 | return false; |
294 | @@ -445,22 +396,37 @@ |
295 | } |
296 | |
297 | private void capture_area () { |
298 | - Gdk.Window win = null; |
299 | - |
300 | - win = Gdk.get_default_root_window(); |
301 | - |
302 | - selection_area.set_opacity (0); |
303 | - selection_area.hide (); |
304 | - this.set_opacity (0); |
305 | + var selection_area = new Screenshot.Widgets.SelectionArea (); |
306 | + selection_area.show_all (); |
307 | this.hide (); |
308 | |
309 | - Timeout.add (delay * 1000 - (redact? 1000 : 0), () => { |
310 | - this.present (); |
311 | - selection_area.present (); |
312 | - grab_save (win, redact); |
313 | - |
314 | - return false; |
315 | - }); |
316 | + selection_area.cancelled.connect (() => { |
317 | + selection_area.close (); |
318 | + if (close_on_save) { |
319 | + this.destroy (); |
320 | + } else { |
321 | + this.present (); |
322 | + } |
323 | + }); |
324 | + |
325 | + var win = selection_area.get_window (); |
326 | + |
327 | + selection_area.captured.connect (() => { |
328 | + selection_area.close (); |
329 | + Timeout.add_seconds (delay - (redact ? 1 : 0), () => { |
330 | + this.present (); |
331 | + return grab_save (win, redact); |
332 | + }); |
333 | + }); |
334 | + } |
335 | + |
336 | + private void show_error_dialog () { |
337 | + var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, |
338 | + Gtk.ButtonsType.CLOSE, _("Could not capture screenshot")); |
339 | + dialog.secondary_text = _("Image not saved"); |
340 | + dialog.deletable = false; |
341 | + dialog.run (); |
342 | + dialog.destroy (); |
343 | } |
344 | |
345 | private void redact_text (bool redact) { |
346 | |
347 | === modified file 'src/Widgets/SaveDialog.vala' |
348 | --- src/Widgets/SaveDialog.vala 2016-07-29 23:27:41 +0000 |
349 | +++ src/Widgets/SaveDialog.vala 2016-09-03 19:11:26 +0000 |
350 | @@ -50,7 +50,6 @@ |
351 | folder_dir = settings.get_string ("folder-dir"); |
352 | |
353 | build (pixbuf, settings, parent); |
354 | - show_all (); |
355 | name_entry.grab_focus (); |
356 | } |
357 | |
358 | |
359 | === modified file 'src/Widgets/SelectionArea.vala' |
360 | --- src/Widgets/SelectionArea.vala 2016-03-09 14:14:00 +0000 |
361 | +++ src/Widgets/SelectionArea.vala 2016-09-03 19:11:26 +0000 |
362 | @@ -17,122 +17,135 @@ |
363 | ***/ |
364 | |
365 | namespace Screenshot.Widgets { |
366 | - |
367 | - /** |
368 | - * Code stolen from Eidete program with some adjustments. |
369 | - */ |
370 | public class SelectionArea : Granite.Widgets.CompositedWindow { |
371 | - |
372 | - private int[,] pos; |
373 | - |
374 | - public int x; |
375 | - public int y; |
376 | - public int w; |
377 | - public int h; |
378 | + public signal void captured (); |
379 | + public signal void cancelled (); |
380 | + |
381 | + private Gdk.Point start_point; |
382 | + |
383 | + private bool dragging = false; |
384 | + |
385 | + construct { |
386 | + type = Gtk.WindowType.POPUP; |
387 | + } |
388 | |
389 | public SelectionArea () { |
390 | - |
391 | stick (); |
392 | set_resizable (true); |
393 | set_deletable (false); |
394 | set_has_resize_grip (false); |
395 | - set_default_geometry (640, 480); |
396 | - set_type_hint (Gdk.WindowTypeHint.DIALOG); |
397 | - events = Gdk.EventMask.BUTTON_MOTION_MASK | Gdk.EventMask.BUTTON1_MOTION_MASK | |
398 | - Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK ; |
399 | set_skip_taskbar_hint (true); |
400 | set_skip_pager_hint (true); |
401 | - |
402 | - button_press_event.connect ((e) => { |
403 | - Gdk.WindowEdge [] dir = {Gdk.WindowEdge.NORTH_WEST, |
404 | - Gdk.WindowEdge.NORTH,Gdk.WindowEdge.NORTH_EAST, |
405 | - Gdk.WindowEdge.EAST,Gdk.WindowEdge.SOUTH_EAST,Gdk.WindowEdge.SOUTH, |
406 | - Gdk.WindowEdge.SOUTH_WEST,Gdk.WindowEdge.WEST}; |
407 | - |
408 | - for (var i=0;i<8;i++){ |
409 | - if (in_quad (pos[i,0]-12, pos[i,1]-10, 24, 24, (int) e.x, (int) e.y)){ |
410 | - begin_resize_drag (dir[i], (int) e.button, (int) e.x_root, (int) e.y_root, e.time); |
411 | - |
412 | - return false; |
413 | - } |
414 | - } |
415 | - begin_move_drag ((int) e.button, (int) e.x_root, (int) e.y_root, e.time); |
416 | - |
417 | - return false; |
418 | - }); |
419 | - |
420 | - configure_event.connect ((e) => { |
421 | - |
422 | - /** |
423 | - * Check if coordinates are out of the screen and check |
424 | - * if coordinate + width/height is out of the screen, then |
425 | - * adjust coordinates to keep width and height (and aspect |
426 | - * ratio) intact. |
427 | - */ |
428 | - if(e.x < 0 || e.x > e.window.get_screen().get_width()) { |
429 | - x = 0; |
430 | - } else if (e.x + e.width > e.window.get_screen().get_width() && e.width < e.window.get_screen().get_width()) { |
431 | - x = e.window.get_screen().get_width() - e.width; |
432 | - } else { |
433 | - x = e.x; |
434 | - } |
435 | - |
436 | - if(e.y < 0) { |
437 | - y = 0; |
438 | - } else if (e.y + e.height >= e.window.get_screen().get_height() && e.height < e.window.get_screen().get_height()) { |
439 | - y = e.window.get_screen().get_height() - e.height - 1; |
440 | - } else { |
441 | - y = e.y; |
442 | - } |
443 | - |
444 | - /** |
445 | - * Just in case an edge is still outside of the screen |
446 | - * we'll modify the width/height if thats the case. |
447 | - */ |
448 | - if (x + e.width > e.window.get_screen().get_width()) { |
449 | - w = e.window.get_screen ().get_width() - x; |
450 | - } else { |
451 | - w = e.width; |
452 | - } |
453 | - |
454 | - if(y + e.height > e.window.get_screen().get_height()) { |
455 | - h = e.window.get_screen().get_height() - y; |
456 | - } else { |
457 | - h = e.height; |
458 | - } |
459 | - |
460 | - return false; |
461 | - }); |
462 | - } |
463 | - |
464 | - private bool in_quad (int qx, int qy, int qh, int qw, int x, int y){ |
465 | - return ((x>qx) && (x<(qx+qw)) && (y>qy) && (y<qy+qh)); |
466 | - } |
467 | - |
468 | - public override bool draw (Cairo.Context ctx){ |
469 | - |
470 | - int w = this.get_allocated_width (); |
471 | - int h = this.get_allocated_height (); |
472 | - int r = 12; |
473 | - |
474 | - pos = {{1, 1}, // upper left |
475 | - {w/2, 1}, // upper midpoint |
476 | - {w-1, 1}, // upper right |
477 | - {w-1, h/2}, // right midpoint |
478 | - {w-1, h-1}, // lower right |
479 | - {w/2, h-1}, // lower midpoint |
480 | - {1, h-1}, // lower left |
481 | - {1, h/2}}; // left midpoint |
482 | + set_keep_above (true); |
483 | + |
484 | + var screen = get_screen (); |
485 | + set_default_size (screen.get_width (), screen.get_height ()); |
486 | + } |
487 | + |
488 | + public override bool button_press_event (Gdk.EventButton e) { |
489 | + if (dragging || e.button != 1) { |
490 | + return true; |
491 | + } |
492 | + |
493 | + dragging = true; |
494 | + |
495 | + start_point.x = (int)e.x_root; |
496 | + start_point.y = (int)e.y_root; |
497 | + |
498 | + return true; |
499 | + } |
500 | + |
501 | + public override bool button_release_event (Gdk.EventButton e) { |
502 | + if (!dragging || e.button != 1) { |
503 | + return true; |
504 | + } |
505 | + |
506 | + dragging = false; |
507 | + captured (); |
508 | + |
509 | + return true; |
510 | + } |
511 | + |
512 | + public override bool motion_notify_event (Gdk.EventMotion e) { |
513 | + if (!dragging) { |
514 | + return true; |
515 | + } |
516 | + |
517 | + int x = start_point.x; |
518 | + int y = start_point.y; |
519 | + |
520 | + int width = (x - (int)e.x_root).abs (); |
521 | + int height = (y - (int)e.y_root).abs (); |
522 | + if (width < 1 || height < 1) { |
523 | + return true; |
524 | + } |
525 | + |
526 | + x = int.min (x, (int)e.x_root); |
527 | + y = int.min (y, (int)e.y_root); |
528 | + |
529 | + move (x, y); |
530 | + resize (width, height); |
531 | + |
532 | + return true; |
533 | + } |
534 | + |
535 | + public override bool key_press_event (Gdk.EventKey e) { |
536 | + if (e.keyval == Gdk.Key.Escape) { |
537 | + cancelled (); |
538 | + } |
539 | + |
540 | + return true; |
541 | + } |
542 | + |
543 | + public override void show_all () { |
544 | + base.show_all (); |
545 | + var manager = Gdk.Display.get_default ().get_device_manager (); |
546 | + var pointer = manager.get_client_pointer (); |
547 | + var keyboard = pointer.get_associated_device (); |
548 | + var window = get_window (); |
549 | + |
550 | + var status = pointer.grab (window, |
551 | + Gdk.GrabOwnership.NONE, |
552 | + false, |
553 | + Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK, |
554 | + new Gdk.Cursor.for_display (window.get_display (), Gdk.CursorType.CROSSHAIR), |
555 | + Gtk.get_current_event_time ()); |
556 | + |
557 | + if (status != Gdk.GrabStatus.SUCCESS) { |
558 | + pointer.ungrab (Gtk.get_current_event_time ()); |
559 | + } |
560 | + |
561 | + if (keyboard != null) { |
562 | + status = keyboard.grab (window, |
563 | + Gdk.GrabOwnership.NONE, |
564 | + false, |
565 | + Gdk.EventMask.KEY_PRESS_MASK, |
566 | + null, |
567 | + Gtk.get_current_event_time ()); |
568 | + |
569 | + if (status != Gdk.GrabStatus.SUCCESS) { |
570 | + keyboard.ungrab (Gtk.get_current_event_time ()); |
571 | + } |
572 | + } |
573 | + } |
574 | + |
575 | + public new void close () { |
576 | + get_window ().set_cursor (null); |
577 | + base.close (); |
578 | + } |
579 | + |
580 | + public override bool draw (Cairo.Context ctx) { |
581 | + if (!dragging) { |
582 | + return true; |
583 | + } |
584 | + |
585 | + int w = get_allocated_width (); |
586 | + int h = get_allocated_height (); |
587 | |
588 | ctx.rectangle (0, 0, w, h); |
589 | ctx.set_source_rgba (0.1, 0.1, 0.1, 0.2); |
590 | ctx.fill (); |
591 | |
592 | - for (var i=0;i<8;i++){ |
593 | - ctx.arc (pos[i,0], pos[i,1], r, 0.0, 2*3.14); |
594 | - ctx.set_source_rgb (0.7, 0.7, 0.7); |
595 | - ctx.fill (); |
596 | - } |
597 | ctx.rectangle (0, 0, w, h); |
598 | ctx.set_source_rgb (0.7, 0.7, 0.7); |
599 | ctx.set_line_width (1.0); |