0
|
1 #!/usr/bin/env python3
|
|
2 # Photo Crop - photo crop to size app to print in the most popular photo paper sizes
|
|
3 # author: Przemysław R. Pietraszczyk
|
|
4 # license: GPL v.2
|
|
5 # date 21-01-2022
|
|
6 # editor: Geany
|
|
7
|
|
8 import sys
|
|
9 import cairo
|
|
10 import gi, os
|
|
11 import time
|
|
12 gi.require_version("Gtk", "3.0")
|
|
13 from gi.repository import Gtk, GdkPixbuf, Gdk
|
|
14 from gi.repository.GdkPixbuf import Pixbuf
|
|
15
|
|
16 UI_INFO = """
|
|
17 <ui>
|
|
18 <menubar name='MenuBar'>
|
|
19 <menu action='FileMenu'>
|
|
20 <menuitem action='FileLoad' />
|
|
21 <menuitem action='FileSave' />
|
|
22 <menuitem action='FilePrint' />
|
|
23 <separator />
|
|
24 <menuitem action='FileQuit' />
|
|
25 </menu>
|
|
26 <menu action='EditMenu'>
|
|
27 <menuitem action='Rotate'/>
|
|
28 </menu>
|
|
29 <menu action='InfoMenu'>
|
|
30 <menuitem action='Help'/>
|
|
31 <menuitem action='About'/>
|
|
32 <separator />
|
|
33 <menuitem action='License'/>
|
|
34 </menu>
|
|
35 </menubar>
|
|
36
|
|
37 </ui>
|
|
38 """
|
|
39
|
|
40 """
|
|
41 # szkielet z podmenu
|
|
42 <ui>
|
|
43 <menubar name='MenuBar'>
|
|
44 <menu action='FileMenu'>
|
|
45 <menu action='FileLoad'>
|
|
46 <menuitem action='LoadImg' />
|
|
47 </menu>
|
|
48 <menuitem action='FilePrint' />
|
|
49 <separator />
|
|
50 <menuitem action='FileQuit' />
|
|
51 </menu>
|
|
52 <menu action='InfoMenu'>
|
|
53 <menuitem action='Help'/>
|
|
54 <menuitem action='About'/>
|
|
55 </menu>
|
|
56 </menubar>
|
|
57 </ui>
|
|
58 """
|
|
59
|
|
60 grid = Gtk.Grid()
|
|
61 rotate = False
|
|
62 file_img_selected = ""
|
|
63
|
|
64 def get_resource_path(rel_path):
|
|
65 dir_of_py_file = os.path.dirname(__file__)
|
|
66 rel_path_to_resource = os.path.join(dir_of_py_file, rel_path)
|
|
67 abs_path_to_resource = os.path.abspath(rel_path_to_resource)
|
|
68 return abs_path_to_resource
|
|
69
|
|
70 class FileChooserIMGLoad(Gtk.Window):
|
|
71 def __init__(self):
|
|
72 Gtk.Window.__init__(self, title="Selection of graphic files")
|
|
73 global file_img_selected
|
|
74
|
|
75 dialog = Gtk.FileChooserDialog(title="Selection of graphic files", parent=self, action=Gtk.FileChooserAction.OPEN)
|
|
76 dialog.add_buttons(
|
|
77 Gtk.STOCK_CANCEL,
|
|
78 Gtk.ResponseType.CANCEL,
|
|
79 Gtk.STOCK_OPEN,
|
|
80 Gtk.ResponseType.OK,
|
|
81 )
|
|
82
|
|
83 self.add_filters(dialog)
|
|
84
|
|
85 response = dialog.run()
|
|
86 if response == Gtk.ResponseType.OK:
|
|
87 print("Open clicked")
|
|
88 print("File selected: " + dialog.get_filename())
|
|
89 file_img_selected=dialog.get_filename()
|
|
90 elif response == Gtk.ResponseType.CANCEL:
|
|
91 print("Cancel clicked")
|
|
92
|
|
93 dialog.destroy()
|
|
94
|
|
95 def add_filters(self, dialog):
|
|
96
|
|
97 filter_jpeg = Gtk.FileFilter()
|
|
98 filter_jpeg.set_name("Files JPEG")
|
|
99 filter_jpeg.add_mime_type("image/jpeg")
|
|
100 dialog.add_filter(filter_jpeg)
|
|
101
|
|
102 filter_png = Gtk.FileFilter()
|
|
103 filter_png.set_name("Files PNG")
|
|
104 filter_png.add_mime_type("image/png")
|
|
105 dialog.add_filter(filter_png)
|
|
106 """
|
|
107 filter_png = Gtk.FileFilter()
|
|
108 filter_png.set_name("Files TIFF")
|
|
109 filter_png.add_mime_type("image/tiff")
|
|
110 dialog.add_filter(filter_png)
|
|
111 """
|
|
112
|
|
113 class FileChooserIMGSave(Gtk.Window):
|
|
114 def __init__(self):
|
|
115 Gtk.Window.__init__(self, title="Save the cropped photo")
|
|
116 global file_img_selected
|
|
117
|
|
118 dialog = Gtk.FileChooserDialog(title="Save the cropped photo", parent=self, action=Gtk.FileChooserAction.SAVE)
|
|
119 dialog.add_buttons(
|
|
120 Gtk.STOCK_CANCEL,
|
|
121 Gtk.ResponseType.CANCEL,
|
|
122 Gtk.STOCK_SAVE,
|
|
123 Gtk.ResponseType.OK,
|
|
124 )
|
|
125
|
|
126 self.add_filters(dialog)
|
|
127
|
|
128 response = dialog.run()
|
|
129 if response == Gtk.ResponseType.OK:
|
|
130 print("Open clicked")
|
|
131 print("File selected: " + dialog.get_filename())
|
|
132 file_img_selected=dialog.get_filename()
|
|
133 elif response == Gtk.ResponseType.CANCEL:
|
|
134 print("Cancel clicked")
|
|
135
|
|
136 dialog.destroy()
|
|
137
|
|
138 def add_filters(self, dialog):
|
|
139
|
|
140 filter_jpeg = Gtk.FileFilter()
|
|
141 filter_jpeg.set_name("Files JPEG")
|
|
142 filter_jpeg.add_mime_type("image/jpeg")
|
|
143 dialog.add_filter(filter_jpeg)
|
|
144
|
|
145 filter_png = Gtk.FileFilter()
|
|
146 filter_png.set_name("Files PNG")
|
|
147 filter_png.add_mime_type("image/png")
|
|
148 dialog.add_filter(filter_png)
|
|
149 """
|
|
150 filter_png = Gtk.FileFilter()
|
|
151 filter_png.set_name("Files TIFF")
|
|
152 filter_png.add_mime_type("image/tiff")
|
|
153 dialog.add_filter(filter_png)
|
|
154 """
|
|
155
|
|
156
|
|
157 class DialogWarning(Gtk.Dialog):
|
|
158 def __init__(self, parent):
|
|
159 Gtk.Dialog.__init__(self, title="Attention!", transient_for=parent, flags=0)
|
|
160 self.props.border_width = 20
|
|
161 self.add_buttons(
|
|
162 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
163 )
|
|
164 self.set_default_size(150, 100)
|
|
165 label1 = Gtk.Label(label="The frame is outside the canvas!\n")
|
|
166 box = self.get_content_area()
|
|
167 box.add(label1)
|
|
168 self.show_all()
|
|
169
|
|
170 class DialogCropWarning(Gtk.Dialog):
|
|
171 def __init__(self, parent):
|
|
172 Gtk.Dialog.__init__(self, title="Attention!", transient_for=parent, flags=0)
|
|
173 self.props.border_width = 20
|
|
174 self.add_buttons(
|
|
175 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
176 )
|
|
177 self.set_default_size(150, 100)
|
|
178 label1 = Gtk.Label(label="Crop the photo first!\n")
|
|
179 box = self.get_content_area()
|
|
180 box.add(label1)
|
|
181 self.show_all()
|
|
182
|
|
183 class DialogHelp(Gtk.Dialog):
|
|
184 def __init__(self, parent):
|
|
185 Gtk.Dialog.__init__(self, title="Help", transient_for=parent, flags=0)
|
|
186 self.props.border_width = 20
|
|
187 self.add_buttons(
|
|
188 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
189 )
|
|
190
|
|
191 self.set_default_size(150, 100)
|
|
192 label1 = Gtk.Label(label="An application for cropping photos to the most popular\nformats [13x18, 10x15, A4]\n\nScaling the size of the frame - mouse wheel with the CTRL key pressed\nMoving the frame - pressed LMB and moving the mouse\nin the desired direction.")
|
|
193 #label2 = Gtk.Label(lanel="")
|
|
194 box = self.get_content_area()
|
|
195 box.add(label1)
|
|
196 #box.add(label2)
|
|
197 self.show_all()
|
|
198
|
|
199 class DialogAbout(Gtk.Dialog):
|
|
200 def __init__(self, parent):
|
|
201 Gtk.Dialog.__init__(self, title="About", transient_for=parent, flags=0)
|
|
202 self.props.border_width = 20
|
|
203 self.add_buttons(
|
|
204 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
205 )
|
|
206
|
|
207 self.set_default_size(150, 100)
|
|
208
|
|
209 label = Gtk.Label(label="\tThe application is based on:")
|
|
210 box = self.get_content_area()
|
|
211 box.add(label)
|
|
212
|
|
213 button = Gtk.LinkButton("https://python-gtk-3-tutorial.readthedocs.io/", label="https://python-gtk-3-tutorial.readthedocs.io/")
|
|
214 box.add(button)
|
|
215
|
|
216 label2 = Gtk.Label(label="\n\tVersion: 0.230112-1~alpha\n\n\tPrzemysław R. Pietraszczyk\n\n\t\t January 2022\n\n\n")
|
|
217 box.add(label2)
|
|
218
|
|
219
|
|
220 button = Gtk.LinkButton("https://prymula.ct8.pl", label="Site")
|
|
221 box.add(button)
|
|
222
|
|
223 self.show_all()
|
|
224
|
|
225 class DialogLicense(Gtk.Dialog):
|
|
226 def __init__(self, parent):
|
|
227 Gtk.Dialog.__init__(self, title="License", transient_for=parent, flags=0)
|
|
228 self.props.border_width = 20
|
|
229 self.add_buttons(
|
|
230 Gtk.STOCK_OK, Gtk.ResponseType.OK
|
|
231 )
|
|
232
|
|
233 self.set_default_size(150, 100)
|
|
234
|
|
235 label = Gtk.Label(label="This program is distributed without any warranty. More information:\n")
|
|
236
|
|
237 box = self.get_content_area()
|
|
238 box.add(label)
|
|
239
|
|
240 button = Gtk.LinkButton("https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", label="GNU General License version => 2")
|
|
241 box.add(button)
|
|
242
|
|
243 self.show_all()
|
|
244
|
|
245 class Brush(object):
|
|
246
|
|
247 default_rgba_color = (0, 0, 0, 1)
|
|
248
|
|
249 def __init__(self, width=None, rgba_color=None):
|
|
250
|
|
251 if rgba_color is None:
|
|
252 rgba_color = self.default_rgba_color
|
|
253
|
|
254 if width is None:
|
|
255 width = 3
|
|
256
|
|
257 self.__width = width
|
|
258 self.__rgba_color = rgba_color
|
|
259 self.__stroke = []
|
|
260 self.__current_line = []
|
|
261
|
|
262 def _line_ended(self):
|
|
263 self.__stroke.append(self.__current_line.copy())
|
|
264 self.__current_line = []
|
|
265
|
|
266 def _add_point(self, point):
|
|
267 self.__current_line.append(point)
|
|
268
|
|
269 def _draw(self, cairo_context):
|
|
270
|
|
271 cairo_context.set_source_rgba(*self.__rgba_color)
|
|
272 cairo_context.set_line_width(self.__width)
|
|
273 cairo_context.set_line_cap(cairo.LINE_CAP_ROUND)
|
|
274
|
|
275 cairo_context.new_path()
|
|
276 for line in self.__stroke:
|
|
277 for x, y in line:
|
|
278 cairo_context.line_to(x, y)
|
|
279 cairo_context.new_sub_path()
|
|
280
|
|
281 for x, y in self.__current_line:
|
|
282 cairo_context.line_to(x, y)
|
|
283
|
|
284 cairo_context.stroke()
|
|
285
|
|
286
|
|
287 # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
|
|
288 # ~ Getters & Setters ~ #
|
|
289 # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
|
|
290
|
|
291 def _get_width(self):
|
|
292 return self.__width
|
|
293
|
|
294 def _set_width(self, width):
|
|
295 self.__width = width
|
|
296
|
|
297 def _get_rgba_color(self):
|
|
298 return self.__rgba_color
|
|
299
|
|
300 def _set_rgba_color(self, rgba_color):
|
|
301 self.__rgba_color = rgba_color
|
|
302
|
|
303 def _get_stroke(self):
|
|
304 return self.__stroke
|
|
305
|
|
306 def _get_current_line(self):
|
|
307 return self.__current_line
|
|
308
|
|
309 class MyWindow(Gtk.Window):
|
|
310
|
|
311 def __init__(self):
|
|
312 super().__init__()
|
|
313
|
|
314 self.init_ui()
|
|
315
|
|
316 def on_drawing_area_draw(self, drawable, cairo_context):
|
|
317 global rotate
|
|
318
|
|
319 start = time.time()
|
|
320 self.brush = Brush()
|
|
321
|
|
322 # DrawingArea size depends on Pixbuf size
|
|
323 #self.drawing_area.get_window().resize(self.displayed_pixbuf.get_width(),
|
|
324 # self.displayed_pixbuf .get_height())
|
|
325 #self.drawing_area.set_size_request(self.displayed_pixbuf.get_width(),
|
|
326 # self.displayed_pixbuf.get_height())
|
|
327
|
|
328
|
|
329 # (x, y) offsets
|
|
330 pixbuf_x = 0 #int(self.viewport.get_hadjustment().get_value())
|
|
331 pixbuf_y = 0 # int(self.viewport.get_vadjustment().get_value())
|
|
332
|
|
333 # Width and height of the image's clip
|
|
334 width = cairo_context.get_target().get_width()
|
|
335 height = cairo_context.get_target().get_height()
|
|
336
|
|
337 if width > 0 and height > 0:
|
|
338
|
|
339 # Draw created area of the Sample's Pixbuf
|
|
340 Gdk.cairo_set_source_pixbuf(cairo_context, self.pixbuf_view, pixbuf_x, pixbuf_y)
|
|
341
|
|
342 cairo_context.paint()
|
|
343
|
|
344 if self.border_visible == True:
|
|
345 # Draw brush strokes
|
|
346 self.brush._add_point((self.border_x, self.border_y))
|
|
347 self.brush._add_point((self.border_width, self.border_y))
|
|
348 self.brush._add_point((self.border_width, self.border_y+self.border_height))
|
|
349 self.brush._add_point((self.border_x, self.border_y+self.border_height))
|
|
350 self.brush._add_point((self.border_x, self.border_y)) # nie działa ?
|
|
351
|
|
352 self.brush._draw(cairo_context)
|
|
353
|
|
354 end = time.time()
|
|
355 #print(f"Runtime of the program is {end - start}")
|
|
356
|
|
357
|
|
358 def set_ratio_border_size(self):
|
|
359
|
|
360 self.border_x = 0
|
|
361 self.border_y = 0
|
|
362
|
|
363 if self.format_size == "10x15":
|
|
364 if self.horizontal == True and self.vertical == False:
|
|
365 single = self.picture_view_height*0.5
|
|
366 self.border_height = single
|
|
367 self.border_width = single*1.4
|
|
368 #self.look = "horizontal"
|
|
369 #self.border_type = "horizontal"
|
|
370 elif self.horizontal == False and self.vertical == True:
|
|
371 single = self.picture_view_width*0.5
|
|
372 self.border_width = single
|
|
373 self.border_height = single*1.4
|
|
374 #self.look = "vertical"
|
|
375 #self.border_type = "vertical"
|
|
376 elif self.horizontal == False and self.vertical == False:
|
|
377 self.border_height = self.picture_view_height
|
|
378 self.border_width = self.picture_view_width
|
|
379
|
|
380 elif self.format_size == "13x18":
|
|
381 if self.horizontal == True and self.vertical == False:
|
|
382 single = self.picture_view_height*0.5
|
|
383 self.border_height = single
|
|
384 self.border_width = single*1.42
|
|
385 elif self.horizontal == False and self.vertical == True:
|
|
386 single = self.picture_view_width*0.5
|
|
387 self.border_width = single
|
|
388 self.border_height = single*1.42
|
|
389 elif self.horizontal == False and self.vertical == False:
|
|
390 self.border_height = self.picture_view_height
|
|
391 self.border_width = self.picture_view_width
|
|
392
|
|
393 elif self.format_size == "A4":
|
|
394 if self.horizontal == True and self.vertical == False:
|
|
395 single = self.picture_view_height*0.5
|
|
396 self.border_height = single
|
|
397 self.border_width = single*1.4
|
|
398 elif self.horizontal == False and self.vertical == True:
|
|
399 single = self.picture_view_width*0.5
|
|
400 self.border_width = single
|
|
401 self.border_height = single*1.4
|
|
402 elif self.horizontal == False and self.vertical == False:
|
|
403 self.border_height = self.picture_view_height
|
|
404 self.border_width = self.picture_view_width
|
|
405
|
|
406
|
|
407
|
|
408 # ustaw proporcje dla obrazu w kontrolce
|
|
409 def set_ratio_picture_view(self):
|
|
410 self.picture_orig_width = float(self.pixbuf_orig.get_width())
|
|
411 self.picture_orig_height = float(self.pixbuf_orig.get_height())
|
|
412 #if self.format_size == "10x15":
|
|
413 #self.picture_orig_x = 0
|
|
414 #self.picture_orig_y = 0
|
|
415
|
|
416 if self.picture_orig_width > self.picture_orig_height:
|
|
417 self.picture_view_width = 586.66 #600
|
|
418 m = self.picture_orig_width / 586.66 #600
|
|
419 self.picture_view_height = self.picture_orig_height/m
|
|
420 if self.picture_orig_height > self.picture_orig_width:
|
|
421 self.picture_view_height = 586.66 #600
|
|
422 m = self.picture_orig_height / 586.66 #600
|
|
423 self.picture_view_width = self.picture_orig_width/m
|
|
424
|
|
425 # Zapamiętanie rozmiaru obrazka dla kontrolki
|
|
426 self.orig_ratio_width = self.picture_view_width
|
|
427 self.orig_ratio_height = self.picture_view_height
|
|
428
|
|
429
|
|
430
|
|
431 # ustaw proporcje dla obrazu w kontrolce ppo rotacji
|
|
432 def set_ratio_picture_view_after_rotation(self):
|
|
433
|
|
434 self.picture_tmp_width = self.border_width - self.border_x
|
|
435 self.picture_tmp_height = self.border_height - self.border_y
|
|
436
|
|
437 if self.border_x != 0 :
|
|
438 bx = self.picture_orig_width / self.border_x
|
|
439 crop_x = self.picture_tmp_width / bx
|
|
440 else:
|
|
441 crop_x = 0
|
|
442
|
|
443 if self.border_y != 0:
|
|
444 by = self.picture_orig_height / self.border_y
|
|
445 crop_y = self.picture_tmp_height / by
|
|
446 else:
|
|
447 crop_y = 0
|
|
448
|
|
449
|
|
450 self.picture_orig_x = crop_x
|
|
451 self.picture_orig_y = crop_y
|
|
452 """
|
|
453 W zależności jaka była pierwotnie orientacja zdjęcia, po obrocie
|
|
454 jest ono odpowiedio przycinane
|
|
455 """
|
|
456 print ("ORIG: "+self.look)
|
|
457 if self.look == "vertical":
|
|
458 if self.border_type == "horizontal":
|
|
459 bw = self.picture_orig_width / (self.border_width - self.border_x)
|
|
460 self.picture_tmp_width = self.picture_orig_width / bw - crop_x
|
|
461 # w tym wypadku 'y' bez odejmowania gdyż skróciło by to fotografie w pione
|
|
462 bh = self.picture_orig_height / self.border_height
|
|
463 self.picture_tmp_height = self.picture_orig_height / bh
|
|
464
|
|
465 elif self.border_type == "vertical":
|
|
466 bw = self.picture_orig_width / (self.border_width - self.border_x)
|
|
467 self.picture_tmp_width = self.picture_orig_width / bw - crop_x
|
|
468
|
|
469 bh = self.picture_orig_height / (self.border_height - self.border_y)
|
|
470 self.picture_tmp_height = self.picture_orig_height / bh
|
|
471
|
|
472 elif self.look == "horizontal":
|
|
473 if self.border_type == "horizontal":
|
|
474 bw = self.picture_orig_width / (self.border_width - self.border_x)
|
|
475 self.picture_tmp_width = self.picture_orig_width / bw - crop_x
|
|
476
|
|
477 bh = self.picture_orig_height / (self.border_height - self.border_y)
|
|
478 self.picture_tmp_height = self.picture_orig_height / bh
|
|
479
|
|
480 elif self.border_type == "vertical":
|
|
481 bw = self.picture_orig_width / (self.border_width - self.border_x)
|
|
482 self.picture_tmp_width = self.picture_orig_width / bw - crop_x
|
|
483
|
|
484 bh = self.picture_orig_height / (self.border_height - self.border_y)
|
|
485 self.picture_tmp_height = self.picture_orig_height / bh
|
|
486
|
|
487
|
|
488 if self.picture_tmp_width > self.picture_tmp_height:
|
|
489 self.picture_view_width = 586.66
|
|
490 m = self.picture_tmp_width / 586.66
|
|
491 self.picture_view_height = self.picture_tmp_height/m
|
|
492 if self.picture_tmp_height > self.picture_tmp_width:
|
|
493 self.picture_view_height = 586.66
|
|
494 m = self.picture_tmp_height / 586.66
|
|
495 self.picture_view_width = self.picture_tmp_width/m
|
|
496
|
|
497 # Zapamiętanie rozmiaru obrazka dla kontrolki
|
|
498 self.orig_ratio_width = self.picture_view_width
|
|
499 self.orig_ratio_height = self.picture_view_height
|
|
500
|
|
501 def on_menu_file_load_img_generic(self, widget):
|
|
502 global grid, file_img_selected
|
|
503
|
|
504 filename=FileChooserIMGLoad()
|
|
505
|
|
506 if len(file_img_selected) != 0:
|
|
507
|
|
508 self.pixbuf_orig = GdkPixbuf.Pixbuf.new_from_file(filename=file_img_selected)
|
|
509
|
|
510 self.set_ratio_picture_view()
|
|
511 self.pixbuf_view = self.pixbuf_orig.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
|
|
512
|
|
513 if self.picture_view_width > self.picture_view_height:
|
|
514 self.horizontal = True
|
|
515 self.vertical = False
|
|
516 self.resize(582.66,413.34)
|
|
517 self.look = "horizontal"
|
|
518 self.border_type = "horizontal"
|
|
519 elif self.picture_view_height > self.picture_view_width:
|
|
520 self.vertical = True
|
|
521 self.horizontal = False
|
|
522 self.resize(413.34,582.66)
|
|
523 self.look = "vertical"
|
|
524 self.border_type = "vertical"
|
|
525 else:
|
|
526 self.horizontal = False
|
|
527 self.vertical = False
|
|
528
|
|
529
|
|
530 self.set_ratio_border_size()
|
|
531
|
|
532
|
|
533
|
|
534 self.border_visible = True
|
|
535
|
|
536 # nie rysujemy na orginale ale na kopii z okna
|
|
537 self.drawing_area.set_size_request(self.pixbuf_view.get_width(), self.pixbuf_view.get_height())
|
|
538 self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
|
|
539
|
|
540 self.show_all()
|
|
541
|
|
542 def add_edit_menu_actions(self, action_group):
|
|
543 action_info_menu = Gtk.Action(name="EditMenu", label="Edit")
|
|
544 action_group.add_action(action_info_menu)
|
|
545
|
|
546 action_new = Gtk.Action(
|
|
547 name="Rotate",
|
|
548 label="Frame rotation",
|
|
549 tooltip="Rotate border",
|
|
550 )
|
|
551 action_new.connect("activate", self.on_menu_rotate)
|
|
552 action_group.add_action_with_accel(action_new, None)
|
|
553
|
|
554
|
|
555 def add_info_menu_actions(self, action_group):
|
|
556 action_info_menu = Gtk.Action(name="InfoMenu", label="Info")
|
|
557 action_group.add_action(action_info_menu)
|
|
558
|
|
559 action_new = Gtk.Action(
|
|
560 name="Help",
|
|
561 label="Help",
|
|
562 tooltip="Help",
|
|
563 )
|
|
564 action_new.connect("activate", self.on_menu_help)
|
|
565 action_group.add_action_with_accel(action_new, None)
|
|
566
|
|
567 action_new = Gtk.Action(
|
|
568 name="About",
|
|
569 label="About",
|
|
570 tooltip="About",
|
|
571 )
|
|
572 action_new.connect("activate", self.on_menu_about)
|
|
573 action_group.add_action_with_accel(action_new, None)
|
|
574
|
|
575 action_new = Gtk.Action(
|
|
576 name="License",
|
|
577 label="License",
|
|
578 tooltip="License",
|
|
579 )
|
|
580 action_new.connect("activate", self.on_menu_license)
|
|
581 action_group.add_action_with_accel(action_new, None)
|
|
582
|
|
583
|
|
584
|
|
585 def add_file_menu_actions(self, action_group):
|
|
586 action_filemenu = Gtk.Action(name="FileMenu", label="File")
|
|
587 action_group.add_action(action_filemenu)
|
|
588
|
|
589 """
|
|
590 # sposób dodawania podmenu
|
|
591 action_fileloadmenu = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_OPEN)
|
|
592 action_group.add_action(action_fileloadmenu)
|
|
593
|
|
594 action_new = Gtk.Action(
|
|
595 name="LoadImg",
|
|
596 label="Wczytaj Obrazek",
|
|
597 tooltip="Wczytuje obrazek",
|
|
598 )
|
|
599 action_new.connect("activate", self.on_menu_file_load_img_generic)
|
|
600 action_group.add_action_with_accel(action_new, None)
|
|
601 """
|
|
602
|
|
603 action_fileload = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_OPEN)
|
|
604 action_fileload.connect("activate", self.on_menu_file_load_img_generic)
|
|
605 action_group.add_action(action_fileload)
|
|
606
|
|
607 action_filesave = Gtk.Action(name="FileSave", stock_id=Gtk.STOCK_SAVE)
|
|
608 action_filesave.connect("activate", self.on_menu_file_save_img)
|
|
609 action_group.add_action(action_filesave)
|
|
610
|
|
611
|
|
612 action_print = Gtk.Action(name="FilePrint", stock_id=Gtk.STOCK_PRINT)
|
|
613 action_print.connect("activate", self.print_image)
|
|
614 action_group.add_action(action_print)
|
|
615
|
|
616
|
|
617 action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
|
|
618 action_filequit.connect("activate", self.on_menu_file_quit)
|
|
619 action_group.add_action(action_filequit)
|
|
620
|
|
621
|
|
622
|
|
623 # tworzy menu bar
|
|
624 def create_ui_manager(self):
|
|
625 uimanager = Gtk.UIManager()
|
|
626
|
|
627 # Throws exception if something went wrong
|
|
628 uimanager.add_ui_from_string(UI_INFO)
|
|
629
|
|
630 # Add the accelerator group to the toplevel window
|
|
631 accelgroup = uimanager.get_accel_group()
|
|
632 self.add_accel_group(accelgroup)
|
|
633 return uimanager
|
|
634
|
|
635 def on_menu_about(self, widget):
|
|
636 dialog = DialogAbout(self)
|
|
637 response = dialog.run()
|
|
638
|
|
639 dialog.destroy()
|
|
640
|
|
641 def on_menu_license(self, widget):
|
|
642 dialog = DialogLicense(self)
|
|
643 response = dialog.run()
|
|
644
|
|
645 dialog.destroy()
|
|
646
|
|
647
|
|
648 def on_menu_help(self, widget):
|
|
649 dialog = DialogHelp(self)
|
|
650 response = dialog.run()
|
|
651
|
|
652 dialog.destroy()
|
|
653
|
|
654 def on_menu_rotate(self, widget):
|
|
655 global rotate
|
|
656
|
|
657
|
|
658 if self.border_type == "horizontal":
|
|
659 self.border_type = "vertical"
|
|
660 self.horizontal = False
|
|
661 self.vertical = True
|
|
662
|
|
663 single = self.picture_view_width*0.3
|
|
664 self.border_width = single
|
|
665 self.border_height = single*1.4
|
|
666 self.border_x = 0
|
|
667 self.border_y = 0
|
|
668
|
|
669 rotate = True
|
|
670
|
|
671 elif self.border_type == "vertical":
|
|
672 self.border_type = "horizontal"
|
|
673 self.horizontal = True
|
|
674 self.vertical = False
|
|
675
|
|
676 single = self.picture_view_height*0.3
|
|
677 self.border_height = single
|
|
678 self.border_width = single*1.4
|
|
679 self.border_x = 0
|
|
680 self.border_y = 0
|
|
681
|
|
682 rotate = True
|
|
683 else:
|
|
684 pass
|
|
685
|
|
686 print ("ASPECT: "+self.border_type)
|
|
687 print ("BORDER-WIDTH :"+str(self.border_width))
|
|
688 print ("BORDER-HEIGHT:"+str(self.border_height))
|
|
689
|
|
690 self.drawing_area.queue_draw()
|
|
691
|
|
692 def on_menu_file_save_img(self, widget):
|
|
693 global file_img_selected
|
|
694
|
|
695 if self.pixbuf_tmp != None:
|
|
696 filename=FileChooserIMGSave()
|
|
697 if len(file_img_selected) != 0:
|
|
698 self.pixbuf_view.savev(file_img_selected, "jpeg", ["quality"], ["100"])
|
|
699 else:
|
|
700 dialog = DialogCropWarning(self)
|
|
701 response = dialog.run()
|
|
702
|
|
703 dialog.destroy()
|
|
704
|
|
705 def on_menu_file_quit(self, widget):
|
|
706 Gtk.main_quit()
|
|
707
|
|
708 def print_page(self, operation=None, context=None, page_nr=None):
|
|
709
|
|
710 ctx = context.get_cairo_context()
|
|
711
|
|
712 # make cairo ImageSurface from the png file
|
|
713 surface = cairo.ImageSurface.create_from_png('/tmp/photocrop.png')
|
|
714 #ctx.rectangle(50,50,100,100)
|
|
715 ctx.set_source_surface(surface)
|
|
716 ctx.paint ()
|
|
717 os.remove("/tmp/photocrop.png");
|
|
718
|
|
719
|
|
720 def print_image(self, widget):
|
|
721
|
|
722 if self.pixbuf_tmp == None:
|
|
723 self.pixbuf_tmp = self.pixbuf_orig
|
|
724
|
|
725
|
|
726 # źle obraca
|
|
727 #if self.border_type == "horizontal":
|
|
728 # self.pixbuf_tmp.rotate_simple(GdkPixbuf.PixbufRotation.COUNTERCLOCKWISE)
|
|
729 # #pixbuf2.rotate_simple(GdkPixbuf.PixbufRotation.CLOCKWISE)
|
|
730 # self.border_type = "vertical"
|
|
731
|
|
732 FACTOR_MM_TO_PIXEL = 2.834645669
|
|
733
|
|
734
|
|
735 if self.format_size == "10x15":
|
|
736 #if self.horizontal == True and self.vertical == False:
|
|
737 if self.border_type == "horizontal":
|
|
738 page_width = 148
|
|
739 page_height = 104.99
|
|
740
|
|
741 img_height =104.99 * FACTOR_MM_TO_PIXEL
|
|
742 img_width = 148 * FACTOR_MM_TO_PIXEL
|
|
743 #elif self.horizontal == False and self.vertical == True:
|
|
744 elif self.border_type == "vertical":
|
|
745
|
|
746 page_width = 104.99
|
|
747 page_height = 148
|
|
748
|
|
749 img_width =104.99 * FACTOR_MM_TO_PIXEL
|
|
750 img_height = 148 * FACTOR_MM_TO_PIXEL
|
|
751
|
|
752 size = "10x15"
|
|
753 elif self.format_size == "13x18":
|
|
754 #if self.horizontal == True and self.vertical == False:
|
|
755 if self.border_type == "horizontal":
|
|
756
|
|
757 page_width = 178
|
|
758 page_height = 127
|
|
759
|
|
760 img_height = 127 * FACTOR_MM_TO_PIXEL
|
|
761 img_width = 178 * FACTOR_MM_TO_PIXEL
|
|
762 #elif self.horizontal == False and self.vertical == True:
|
|
763 elif self.border_type == "vertical":
|
|
764
|
|
765 page_width = 127
|
|
766 page_height = 178
|
|
767
|
|
768 img_width = 127 * FACTOR_MM_TO_PIXEL
|
|
769 img_height = 178 * FACTOR_MM_TO_PIXEL
|
|
770 size = "5x7"
|
|
771 elif self.format_size == "A4":
|
|
772 #if self.horizontal == True and self.vertical == False:
|
|
773 if self.border_type == "horizontal":
|
|
774 page_width = 297
|
|
775 page_height = 207
|
|
776
|
|
777 img_height = 207 * FACTOR_MM_TO_PIXEL
|
|
778 img_width = 297 * FACTOR_MM_TO_PIXEL
|
|
779 #elif self.horizontal == False and self.vertical == True:
|
|
780 elif self.border_type == "vertical":
|
|
781
|
|
782 page_width = 207
|
|
783 page_height = 297
|
|
784
|
|
785 img_width = 207 * FACTOR_MM_TO_PIXEL
|
|
786 img_height = 297 * FACTOR_MM_TO_PIXEL
|
|
787
|
|
788 size = "A4"
|
|
789
|
|
790 dpi = 600
|
|
791
|
|
792 # z orginalnymi wielkościami nie chce drukowac
|
|
793 pixbuf2 = self.pixbuf_tmp.scale_simple(img_width, img_height, GdkPixbuf.InterpType.HYPER)
|
|
794
|
|
795 pixbuf2.savev("/tmp/photocrop.png","png", ["quailty"], ["100"])
|
|
796
|
|
797 #ps = Gtk.PaperSize.new_custom(size, size, self.pixbuf_tmp.get_width(), self.pixbuf_tmp.get_height(), Gtk.Unit.POINTS)
|
|
798 ps = Gtk.PaperSize.new_custom(size, size, page_width, page_height, Gtk.Unit.MM)
|
|
799
|
|
800 print_settings = Gtk.PrintSettings()
|
|
801 print_settings.set_resolution(dpi)
|
|
802
|
|
803 page_setup = Gtk.PageSetup()
|
|
804 page_setup.set_paper_size(ps)
|
|
805 page_setup.set_bottom_margin(0.0, Gtk.Unit.MM)
|
|
806 page_setup.set_left_margin(0.0, Gtk.Unit.MM)
|
|
807 page_setup.set_right_margin(0.0, Gtk.Unit.MM)
|
|
808 page_setup.set_top_margin(0.0, Gtk.Unit.MM)
|
|
809
|
|
810 #if self.border_type == "horizontal":
|
|
811 # page_setup.set_orientation(Gtk.PageOrientation.LANDSCAPE)
|
|
812 #elif self.border_type == "vertical":
|
|
813 # page_setup.set_orientation(Gtk.PageOrientation.PORTRAIT)
|
|
814
|
|
815
|
|
816 print_operation = Gtk.PrintOperation()
|
|
817 print_operation.set_unit(Gtk.Unit.POINTS)
|
|
818 print_operation.set_n_pages(1)
|
|
819 print_operation.set_default_page_setup(page_setup)
|
|
820 print_operation.set_print_settings(print_settings)
|
|
821 print_operation.connect("draw_page", self.print_page)
|
|
822 #print_operation.set_export_filename("example.pdf")
|
|
823
|
|
824 result = print_operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, None) # window zamisat None
|
|
825
|
|
826 #result = print_operation.run(Gtk.PrintOperationAction.PREVIEW, None)
|
|
827 print(result)
|
|
828
|
|
829 # przycinamy !
|
|
830 def photo_crop(self, button):
|
|
831
|
|
832 if self.border_x < 0:
|
|
833 dialog = DialogWarning(self)
|
|
834 response = dialog.run()
|
|
835 dialog.destroy()
|
|
836 return
|
|
837 if self.border_y < 0:
|
|
838 dialog = DialogWarning(self)
|
|
839 response = dialog.run()
|
|
840 dialog.destroy()
|
|
841 return
|
|
842 if self.border_width > self.picture_view_width:
|
|
843 dialog = DialogWarning(self)
|
|
844 response = dialog.run()
|
|
845 dialog.destroy()
|
|
846 return
|
|
847 # FIXME - w sumie to jest zastanawiające !?
|
|
848 if self.border_height + self.border_y > self.picture_view_height:
|
|
849 dialog = DialogWarning(self)
|
|
850 response = dialog.run()
|
|
851 dialog.destroy()
|
|
852 return
|
|
853
|
|
854
|
|
855 if self.border_x != 0 :
|
|
856 bx = self.picture_view_width / self.border_x
|
|
857 crop_x = self.picture_orig_width / bx
|
|
858 else:
|
|
859 crop_x = 0
|
|
860
|
|
861 if self.border_y != 0:
|
|
862 by = self.picture_view_height / self.border_y
|
|
863 crop_y = self.picture_orig_height / by
|
|
864 else:
|
|
865 crop_y = 0
|
|
866
|
|
867 bw = self.picture_view_width / self.border_width
|
|
868 crop_width = self.picture_orig_width / bw - crop_x
|
|
869
|
|
870 bh = self.picture_view_height / self.border_height
|
|
871 crop_height = self.picture_orig_height / bh
|
|
872
|
|
873
|
|
874 # False - kanał Alpha
|
|
875 self.pixbuf_tmp = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, crop_width, crop_height)
|
|
876
|
|
877 # zera na koncu to dest_x i dest_y
|
|
878 self.pixbuf_orig.copy_area(crop_x, crop_y, crop_width, crop_height, self.pixbuf_tmp, 0, 0)
|
|
879
|
|
880 if rotate == False:
|
|
881
|
|
882 self.picture_tmp_width = float(self.pixbuf_tmp.get_width())
|
|
883 self.picture_tmp_height = float(self.pixbuf_tmp.get_height())
|
|
884
|
|
885 # tym razem przeliczamy z uwzględnieniem bufora tymczasowego
|
|
886 if self.picture_tmp_width > self.picture_tmp_height:
|
|
887 self.picture_view_width = 586.66
|
|
888 m = self.picture_tmp_width / 586.66
|
|
889 self.picture_view_height = self.picture_tmp_height/m
|
|
890 if self.picture_tmp_height > self.picture_tmp_width:
|
|
891 self.picture_view_height = 586.66
|
|
892 m = self.picture_tmp_height / 586.66
|
|
893 self.picture_view_width = self.picture_tmp_width/m
|
|
894
|
|
895
|
|
896
|
|
897 else:
|
|
898 self.set_ratio_picture_view_after_rotation()
|
|
899
|
|
900 self.drawing_area.set_size_request(self.picture_view_width, self.picture_view_height)
|
|
901 self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
|
|
902
|
|
903 self.pixbuf_view = self.pixbuf_tmp.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
|
|
904
|
|
905 self.picture_view_x = 0
|
|
906 self.picture_view_y = 0
|
|
907
|
|
908 self.border_visible = False
|
|
909
|
|
910 self.drawing_area.queue_draw()
|
|
911
|
|
912 # przywracamy
|
|
913 def photo_restore(self, button):
|
|
914
|
|
915 self.border_visible = True
|
|
916
|
|
917 self.set_ratio_picture_view()
|
|
918 self.pixbuf_view = self.pixbuf_orig.scale_simple(self.orig_ratio_width, self.orig_ratio_height, GdkPixbuf.InterpType.BILINEAR)
|
|
919
|
|
920 self.drawing_area.set_size_request(self.orig_ratio_width, self.orig_ratio_height)
|
|
921 self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
|
|
922 self.pixbuf_tmp = None # uniemożliwiamy zapis
|
|
923 self.show_all()
|
|
924
|
|
925 self.drawing_area.queue_draw()
|
|
926
|
|
927
|
|
928 def on_format_combo_changed(self, combo):
|
|
929 tree_iter = combo.get_active_iter()
|
|
930 if tree_iter is not None:
|
|
931 model = combo.get_model()
|
|
932 self.format_size = model[tree_iter][0]
|
|
933 print("Selected: format=%s" % self.format_size)
|
|
934
|
|
935 self.set_ratio_border_size()
|
|
936
|
|
937 self.drawing_area.queue_draw()
|
|
938
|
|
939 def on_scroll(self, widget, event):
|
|
940 """ handles on scroll event"""
|
|
941 # Handles zoom in / zoom out on Ctrl+mouse wheel
|
|
942 accel_mask = Gtk.accelerator_get_default_mod_mask()
|
|
943 if event.state & accel_mask == Gdk.ModifierType.CONTROL_MASK:
|
|
944 direction = event.get_scroll_deltas()[2]
|
|
945
|
|
946 if direction > 0:
|
|
947 scrolling = "zoom_out"
|
|
948 else:
|
|
949 scrolling = "zoom_in"
|
|
950
|
|
951 self.border_height += self.border_properties[self.format_size][self.border_type][scrolling]["height"]
|
|
952 self.border_width += self.border_properties[self.format_size][self.border_type][scrolling]["width"]
|
|
953 """
|
|
954 # tu jest jakiś błąd
|
|
955 if self.border_width > self.picture_view_width:
|
|
956 self.border_width -= 1
|
|
957 if self.border_height+self.border_y > self.picture_view_height:
|
|
958 self.border_height -= 1
|
|
959 """
|
|
960 self.drawing_area.queue_draw()
|
|
961
|
|
962 def unclick_in_drawing_area (self, box, event):
|
|
963 self.button_press = False
|
|
964 print ("Przycisk myszki puszczony")
|
|
965
|
|
966
|
|
967 def onclick_in_drawing_area (self, box, event):
|
|
968 if event.button == 1:
|
|
969 self.button_press = True
|
|
970 print ("Lewy przyciski myszki naciśnięty")
|
|
971
|
|
972 def on_mouse_move_in_drawing_area(self, box, event):
|
|
973
|
|
974
|
|
975 if self.button_press == True:
|
|
976
|
|
977 if self.border_type == "vertical":
|
|
978
|
|
979 #print ("VERTICAL %%")
|
|
980
|
|
981 if self.last_x < event.x:
|
|
982 self.border_x += 1
|
|
983 self.border_width += 1
|
|
984 if event.x < self.last_x:
|
|
985 self.border_x -= 1
|
|
986 self.border_width -= 1
|
|
987 if self.last_y < event.y:
|
|
988 self.border_y += 1
|
|
989 self.border_height += 0.0
|
|
990 if event.y < self.last_y:
|
|
991 self.border_y -= 1
|
|
992 self.border_height -= 0.0
|
|
993
|
|
994 elif self.border_type == "horizontal":
|
|
995 #print ("Horizontal %%")
|
|
996 if self.last_x < event.x:
|
|
997 self.border_x += 1
|
|
998 self.border_width += 1
|
|
999 if event.x < self.last_x:
|
|
1000 self.border_x -= 1.
|
|
1001 self.border_width -= 1
|
|
1002 if self.last_y < event.y:
|
|
1003 self.border_y += 1
|
|
1004 self.border_height += 0.0
|
|
1005 if event.y < self.last_y:
|
|
1006 self.border_y -= 1
|
|
1007 self.border_height -= 0.0
|
|
1008
|
|
1009 self.last_y = event.y
|
|
1010 self.last_x = event.x
|
|
1011 """
|
|
1012 # jeśli będzie się napierać na skraj krawędzi wówczas powiększa ramkę
|
|
1013 if self.border_x < 0:
|
|
1014 self.border_x += 1
|
|
1015 self.border_width += 1
|
|
1016 if self.border_y < 0:
|
|
1017 self.border_y += 1
|
|
1018 self.border_height +=1
|
|
1019 # tu jest jakiś błąd
|
|
1020
|
|
1021 # powoduje błędne zachowanie ramki
|
|
1022 if self.border_type == "vertical":
|
|
1023 if self.border_width > self.picture_view_width:
|
|
1024 self.border_width -= 1
|
|
1025 self.border_x -= 1
|
|
1026 if self.border_height+self.border_y > self.picture_view_height:
|
|
1027 self.border_height -= 1
|
|
1028 self.border_y -= 1
|
|
1029 elif self.border_type == "horizontal":
|
|
1030 if self.border_height+self.border_y> self.picture_view_width:
|
|
1031 self.border_width -= 1
|
|
1032 self.border_x -= 1
|
|
1033 if self.border_width > self.picture_view_height:
|
|
1034 self.border_height -= 1
|
|
1035 self.border_y -= 1
|
|
1036 """
|
|
1037
|
|
1038 self.drawing_area.queue_draw()
|
|
1039
|
|
1040 def init_ui(self):
|
|
1041 # JPG akceptuje jedynie z GIMPa
|
|
1042 self.border_properties = { "10x15" : { "horizontal" : { "zoom_out" : {"width" : -1.48, "height" : -0.92}, "zoom_in" : {"width" : 1.48, "height" : 0.92}},
|
|
1043 "vertical" : { "zoom_out": { "width" : -0.92, "height" : -1.48}, "zoom_in": { "width" : 0.92, "height" : 1.48}},
|
|
1044 "square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}},
|
|
1045
|
|
1046 "13x18" : { "horizontal" : { "zoom_out" : {"width" : -1.82, "height" : -1.30}, "zoom_in" : {"width" : 1.82, "height" : 1.30}},
|
|
1047 "vertical" : { "zoom_out": { "width" : -1.30, "height" : -1.78}, "zoom_in": { "width" : 1.30, "height" : 1.78}},
|
|
1048 "square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}},
|
|
1049
|
|
1050 "A4" : { "horizontal" : { "zoom_out" : {"width" : -2.97, "height" : -1.84}, "zoom_in" : {"width" : 2.97, "height" : 1.84}},
|
|
1051 "vertical" : { "zoom_out": { "width" : -1.84, "height" : -2.97}, "zoom_in": { "width" : 1.84, "height" : 2.97}},
|
|
1052 "square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}}}
|
|
1053
|
|
1054
|
|
1055 #self.props.border_width = 20
|
|
1056 self.add(grid)
|
|
1057 self.pixbuf_tmp = None
|
|
1058 grid.set_row_spacing(10)
|
|
1059 grid.set_column_spacing(10)
|
|
1060 grid.set_column_homogeneous(True) # rozszerza kontrolki na resztę okna
|
|
1061
|
|
1062 action_group = Gtk.ActionGroup(name="my_actions")
|
|
1063
|
|
1064 self.add_file_menu_actions(action_group)
|
|
1065 self.add_edit_menu_actions(action_group)
|
|
1066 self.add_info_menu_actions(action_group)
|
|
1067
|
|
1068 uimanager = self.create_ui_manager()
|
|
1069 uimanager.insert_action_group(action_group)
|
|
1070
|
|
1071 menubar = uimanager.get_widget("/MenuBar")
|
|
1072 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
1073 box.pack_start(menubar, False, False, 0)
|
|
1074
|
|
1075 grid.attach(box, 0, 0, 3, 1)
|
|
1076
|
|
1077
|
|
1078 file_img_selected=get_resource_path("/usr/share/photocrop/IMG_6854.JPG") #img/blank.png
|
|
1079 self.pixbuf_orig = GdkPixbuf.Pixbuf.new_from_file(filename=file_img_selected)
|
|
1080
|
|
1081 self.format_size = "10x15"
|
|
1082 self.set_ratio_picture_view()
|
|
1083 self.pixbuf_view = self.pixbuf_orig.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
|
|
1084
|
|
1085 self.border_visible = True
|
|
1086
|
|
1087 if self.picture_view_width > self.picture_view_height:
|
|
1088 self.horizontal = True
|
|
1089 self.vertical = False
|
|
1090 self.look = "horizontal"
|
|
1091 self.border_type = "horizontal"
|
|
1092 elif self.picture_view_height > self.picture_view_width:
|
|
1093 self.vertical = True
|
|
1094 self.horizontal = False
|
|
1095 self.look = "vertical"
|
|
1096 self.border_type = "vertical"
|
|
1097 else:
|
|
1098 self.horizontal = False
|
|
1099 self.vertical = False
|
|
1100 self.look = "square"
|
|
1101
|
|
1102 self.drawing_area = Gtk.DrawingArea()
|
|
1103
|
|
1104 self.drawing_area.set_size_request(self.pixbuf_view.get_width(), self.pixbuf_view.get_height())
|
|
1105 self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
|
|
1106
|
|
1107 self.drawing_area.connect("draw", self.on_drawing_area_draw)
|
|
1108
|
|
1109 frame = Gtk.Frame()
|
|
1110 event_box = Gtk.EventBox ()
|
|
1111 self.last_x = 1
|
|
1112 self.last_y = 1
|
|
1113 self.border_x = 0
|
|
1114 self.border_y = 0
|
|
1115 self.button_press = False
|
|
1116 self.pixbuf_tmp = None
|
|
1117 event_box.connect ('button-press-event', self.onclick_in_drawing_area)
|
|
1118 event_box.connect ('button-release-event', self.unclick_in_drawing_area)
|
|
1119 event_box.connect("motion-notify-event", self.on_mouse_move_in_drawing_area)
|
|
1120 event_box.add_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
|
|
1121
|
|
1122 event_box.add(self.drawing_area)
|
|
1123 frame.add(event_box)
|
|
1124 grid.attach(frame,0,1,3,1)
|
|
1125
|
|
1126 button1 = Gtk.Button.new_with_label("Crop")
|
|
1127 button1.connect("clicked", self.photo_crop)
|
|
1128 grid.attach(button1,0,4,1,1)
|
|
1129
|
|
1130 button2 = Gtk.Button.new_with_label("Restore")
|
|
1131 button2.connect("clicked", self.photo_restore)
|
|
1132 grid.attach(button2,1,4,1,1)
|
|
1133
|
|
1134 format_store = Gtk.ListStore(str)
|
|
1135 format_photo = [
|
|
1136 "10x15",
|
|
1137 "13x18",
|
|
1138 "A4",
|
|
1139 ]
|
|
1140 for fp in format_photo:
|
|
1141 format_store.append([fp])
|
|
1142
|
|
1143 format_combo = Gtk.ComboBox.new_with_model(format_store)
|
|
1144 format_combo.connect("changed", self.on_format_combo_changed)
|
|
1145 renderer_text = Gtk.CellRendererText()
|
|
1146 format_combo.pack_start(renderer_text, True)
|
|
1147 format_combo.add_attribute(renderer_text, "text", 0)
|
|
1148 format_combo.set_active(0)
|
|
1149 grid.attach(format_combo,2,4,1,1)
|
|
1150
|
|
1151 self.drawing_area.connect('scroll-event', self.on_scroll)
|
|
1152
|
|
1153 self.set_border_width(10)
|
|
1154 self.set_title("Photo Crop (alpha)")
|
|
1155 #self.set_default_size(700, 600)
|
|
1156 #self.resize(700, 600)
|
|
1157 self.set_resizable(False)
|
|
1158 self.connect("destroy", Gtk.main_quit)
|
|
1159
|
|
1160
|
|
1161
|
|
1162 win = MyWindow()
|
|
1163 win.show_all()
|
|
1164 Gtk.main()
|