source: lliurex-store/trunk/fuentes/lliurex-store-gui/MainWindow.py @ 4099

Last change on this file since 4099 was 4099, checked in by hectorgh, 4 years ago

wip

File size: 11.9 KB
Line 
1import gi
2gi.require_version('Gtk', '3.0')
3from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject,GLib
4
5import Core
6import Package
7
8import threading
9import multiprocessing
10import gettext
11import signal
12import time
13
14signal.signal(signal.SIGINT, signal.SIG_DFL)
15_=gettext.gettext
16
17
18
19class MainWindow:
20       
21        def __init__(self):
22               
23                self.core=Core.Core.get_core()
24                self.load_thread=threading.Thread()
25                self.search_process=multiprocessing.Process()
26                self.thread_aborted=False
27                self.search_aborted=False
28                self.last_search=""
29                self.path_followed=["main"]
30                self.load_gui()
31               
32        #def init
33       
34
35       
36        # ### MAIN UI FUNCTIONS # ####################
37       
38        def load_gui(self):
39               
40                builder=Gtk.Builder()
41                ui_path=self.core.ui_path
42                builder.add_from_file(ui_path)
43               
44                self.window=builder.get_object("window1")
45                self.menu_button=builder.get_object("menu_button")
46               
47                self.main_scroll=builder.get_object("main_scrolledwindow")
48                self.location_label=builder.get_object("location_label")
49                self.search_entry=builder.get_object("search_entry")
50                self.main_box=builder.get_object("main_box")
51                self.header_box=builder.get_object("header_box")
52                self.go_back_button=builder.get_object("go_back_button")
53                self.menu_image=builder.get_object("menu_image")
54               
55               
56                self.main_menu=self.core.main_menu
57                self.loading_box=self.core.loading_box
58                self.details_box=self.core.details_box
59                self.popup_menu=self.core.popup_menu
60                self.screenshot_viewer=self.core.screenshot_viewer
61                self.search_box=self.core.search_box
62               
63                self.stack=Gtk.Stack()
64                self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
65                self.stack.set_transition_duration(500)
66               
67                self.stack.add_titled(self.loading_box,"loading","Loading")
68                self.stack.add_titled(self.main_menu,"main","Main")
69                self.stack.add_titled(self.details_box,"details","Details")
70                self.stack.add_titled(self.search_box,"search","Search")
71                self.main_scroll.add(self.stack)
72       
73                self.overlay=Gtk.Overlay()
74                self.main_eb=Gtk.EventBox()
75                self.main_eb.add(self.main_box)
76               
77                self.main_eb.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
78                self.main_eb.connect("button-press-event",self.main_eb_clicked)
79               
80                self.overlay.add(self.main_eb)
81                self.overlay.show_all()
82               
83                self.fade_box_revealer=Gtk.Revealer()
84                self.fade_box_revealer.set_valign(Gtk.Align.END)
85                self.fade_box_revealer.set_halign(Gtk.Align.END)
86               
87                self.fade_box=Gtk.HBox()
88                self.fade_eb=Gtk.EventBox()
89                self.fade_eb.add(self.fade_box)
90                self.fade_eb.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
91                self.fade_eb.connect("button-press-event",self.main_eb_clicked)
92               
93                self.fade_box_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP)
94                self.fade_box_revealer.set_transition_duration(self.popup_menu.revealer.get_transition_duration())
95                self.fade_box_revealer.add(self.fade_eb)
96                self.fade_box_revealer.show_all()
97               
98               
99                self.overlay.add_overlay(self.fade_box_revealer)
100                self.overlay.add_overlay(self.popup_menu)
101                self.overlay.add_overlay(self.screenshot_viewer)
102
103                self.window.add(self.overlay)
104               
105                self.connect_signals()
106                self.set_css_info()
107                self.build_home()
108               
109                self.window.show_all()
110                #self.location_label.hide()
111               
112        #def load_gui
113
114       
115        def set_css_info(self):
116               
117                self.style_provider=Gtk.CssProvider()
118                f=Gio.File.new_for_path("lliurex-store.css")
119                self.style_provider.load_from_file(f)
120                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
121               
122                self.window.set_name("MAIN_BOX")
123                self.header_box.set_name("HEADER_MENU")
124                self.menu_button.set_name("MENU_BUTTON")
125                self.location_label.set_name("RELATED_LABEL")
126                self.fade_box.set_name("FADE_BOX")
127               
128                self.go_back_button.set_name("BACK_BUTTON")
129                self.menu_image.set_name("MENU_IMAGE")
130               
131        #def set-css_info       
132
133       
134        def connect_signals(self):
135               
136                self.window.connect("size-allocate",self.window_size_changed)
137                self.window.connect("destroy",Gtk.main_quit)
138                self.menu_button.connect("clicked",self.menu_button_clicked)
139                self.search_entry.connect("changed",self.search_entry_changed)
140                self.search_entry.connect("activate",self.entries_press_event)
141                self.go_back_button.connect("clicked",self.go_back)
142               
143        #def connect_signals
144       
145       
146        def start_gui(self):
147               
148                GObject.threads_init()
149                Gtk.main()
150               
151        #def start_gui
152
153        # #################################################### ##
154
155
156
157        # #### STACK FAST ACCESS FUNCTIONS # #################
158       
159        def go_back(self,widget=None):
160               
161                if len(self.path_followed)>1:
162                       
163                       
164                        current_txt=self.location_label.get_text().split(" > ")
165                        current_txt=" > ".join(current_txt[0:-1])
166                        self.location_label.set_text(current_txt)
167                        dest=self.path_followed[-2]
168                        self.stack.set_visible_child_name(dest)
169                        self.path_followed.pop(-1)
170                       
171                        if dest=="main":
172                                self.search_entry.set_text("")
173                       
174                       
175               
176        #def go_back
177       
178        def show_loading(self):
179               
180                self.stack.set_visible_child_name("loading")
181               
182        #def kk
183
184
185        def show_details_box(self):
186               
187                self.thread_aborted=True
188                self.search_aborted=True
189                current_txt=self.location_label.get_text()
190                self.location_label.set_text(current_txt + " > " + "Details")
191                self.path_followed.append("details")
192                self.stack.set_visible_child_name("details")
193               
194        #def show_details_box
195
196
197        def show_home(self):
198               
199                self.thread_aborted=True
200                self.search_aborted=True
201               
202                self.location_label.set_text("Home")
203                self.path_followed=["main"]
204                self.stack.set_visible_child_name("main")
205               
206        #def show_details_box
207       
208        def show_search_results(self):
209               
210                current_txt=self.location_label.get_text()
211                if self.path_followed[-1]!="search":
212                        self.location_label.set_text(current_txt + " > " + "Search")
213                        self.path_followed.append("search")
214                self.stack.set_visible_child_name("search")
215               
216        #def show_search_results
217       
218        # ############################################
219
220
221
222        # ### HOME LOADING FUNCTIONS # ##############
223       
224        def build_home(self):
225               
226                self.load_thread=threading.Thread(target=self.download_home_info_thread)
227                self.load_thread.daemon=True
228                self.load_thread.start()
229               
230                GLib.timeout_add(500,self.build_home_listener)
231               
232        #def build_home
233
234
235        def build_home_listener(self):
236               
237                if self.thread_aborted:
238                        self.thread_aborted=False
239                        return False
240               
241               
242                if self.load_thread.is_alive():
243                        return True
244               
245               
246                self.main_menu.build_banners()
247                self.show_home()
248                return False
249               
250        #def load_home
251
252       
253        def download_home_info_thread(self):
254               
255                self.main_menu.download_home_info()
256               
257                #time.sleep(2)
258
259        #def load_home_thread
260       
261        # #################################
262
263       
264       
265        # ### LOAD PKG FUNCTIONS # ##################
266       
267       
268        def set_pkg_data(self,pkg):
269               
270                self.current_pkg=Package.Package(pkg)
271                self.details_box.set_package_info(self.current_pkg)
272                self.show_details_box()
273                #self.stack.set_visible_child_name("details")
274               
275        #def set_data
276       
277        def load_pkg_data(self,pkg_id,pkg_data=None):
278               
279                self.current_pkg=None
280                self.thread_aborted=False
281                self.load_thread=threading.Thread(target=self.load_pkg_data_thread,args=(pkg_id,))
282                self.load_thread.daemon=True
283                self.load_thread.start()
284                self.show_loading()
285                GLib.timeout_add(500,self.load_pkg_listener)
286               
287        #def load_pkg_data
288       
289        def load_pkg_data_thread(self,pkg_id):
290               
291                #self.current_pkg=Package.Package.get_demo_package(pkg_id)
292                self.current_pkg=self.core.store.get_info(pkg_id)
293                #time.sleep(2)
294               
295        #def load_pkg_data_thread
296       
297        def load_pkg_listener(self):
298               
299                if self.thread_aborted:
300                        self.thread_aborted=False
301                        return False
302               
303                if self.load_thread.is_alive():
304                        return True
305                       
306                if self.current_pkg!=None:
307                        self.details_box.set_package_info(self.current_pkg)
308                        self.show_details_box()
309                        #self.stack.set_visible_child_name("details")
310               
311                return False
312               
313        #def load_pkg_listener
314       
315        # #################################
316
317
318        # ## SEARCH FUNCTIONS ######################
319       
320       
321        def entries_press_event(self,widget):
322               
323                self.last_search=None
324                self.search_entry_changed(None)
325               
326        #def entries_press_event
327       
328        def search_entry_changed(self,widget):
329               
330                txt=self.search_entry.get_text()
331                current_stack=self.stack.get_visible_child_name()
332                txt=txt.strip(" ")
333               
334                if self.last_search!=txt:
335                        self.last_search=txt
336                else:
337                        return
338               
339                if len(txt)==0:
340                        self.show_home()
341                        return
342                       
343                if len(txt)>2:
344                        self.search_aborted=False
345                        self.show_loading()
346                        self.search_package(txt)
347               
348        #def search_entry_changed
349       
350        def search_package(self,pkg_id):
351               
352                if self.search_process.is_alive():
353                        self.search_process.terminate()
354               
355                self.current_search_id=self.core.get_random_id()
356                self.counter=0
357                self.search_queue=multiprocessing.Queue()
358                self.search_process=multiprocessing.Process(target=self.search_package_thread,args=(pkg_id,self.search_queue,))
359                #self.search_process=threading.Thread(target=self.search_package_thread,args=(pkg_id,self.search_queue,))
360               
361                self.search_process.daemon=True
362                self.search_process.start()
363               
364                GLib.timeout_add(500, self.search_listener,self.current_search_id)
365               
366        #def search_package
367       
368        def search_package_thread(self,pkg_id,search_queue):
369               
370                ret=self.core.store.search_package(pkg_id)
371                self.core.dprint("Search complete")
372                '''
373                for p in ret:
374                        pkg["icon_url"]=self.core.resources.get_icon(p.dic)
375                        pkg["name"]=p.dic["name"]
376                        pkg["package"]=pkg_id
377                        pkg["short_description"]="Package that does a lot of things very well done askdjlaskl jdaklsdjkl asjkl dasjkl djkl asdjkl asdjkl asdjkl asdjkl asdjkl asdjkl asd"
378                        ret.append(pkg)
379                '''
380               
381                search_queue.put(ret)
382               
383
384               
385        #def search_package_thread
386       
387        def search_listener(self,search_id):
388               
389                if self.current_search_id!=search_id:
390                        return False
391               
392                if self.search_aborted:
393                        self.core.dprint("Search aborted [!]")
394                        self.thread_aborted=False
395                        return False
396               
397                if self.search_process.is_alive():
398                        self.counter+=1
399                       
400                        if self.search_queue.empty():
401                                return True
402                       
403                search_result=self.search_queue.get()
404               
405               
406                if search_result!=None:
407                        self.core.search_box.populate_search_results(search_result)
408                        self.show_search_results()
409               
410                return False
411               
412        #def search_listener
413       
414
415        # ########################################
416       
417
418        # ## SCREENSHOTVIEWER FUNCTIONS ## ##############
419       
420        def window_size_changed(self,widget,allocation):
421               
422                x,y=self.window.get_size()
423                self.popup_menu.popup_menu.set_size_request(400,y)
424                self.screenshot_viewer.content_box.set_size_request(x,y)
425                self.screenshot_viewer.sw.set_size_request(x-20,150)
426                self.fade_box.set_size_request(x,y)
427               
428        #def window_size_allocation
429
430
431        def screenshot_clicked(self,widget):
432
433                if widget.get_children()[0].get_visible_child_name()=="image":
434                       
435                        if self.popup_menu.revealer.get_reveal_child():
436                                self.popup_menu.revealer.set_reveal_child(False)
437                                return
438                       
439                        if widget.get_children()[0].image_info["video_url"]==None:
440                                self.screenshot_viewer.set_screenshot(widget.get_children()[0].image_info["image_id"],self.details_box.screenshots_box)
441                        else:
442                                self.screenshot_viewer.set_screenshot(widget.get_children()[0].image_info["video_url"],self.details_box.screenshots_box,True)
443                               
444                        self.screenshot_viewer.revealer.set_reveal_child(True)
445                       
446                       
447        #def screenshot_clicked
448       
449        # ####################################### #
450
451
452
453        # ## POPUP MENU FUNCTIONS # #####################
454
455        def main_eb_clicked(self,widget,event):
456               
457                if self.popup_menu.revealer.get_reveal_child():
458                        self.popup_menu.revealer.set_reveal_child(False)
459                       
460                if self.fade_box_revealer.get_reveal_child():
461                        self.fade_box_revealer.set_transition_type(Gtk.RevealerTransitionType.CROSSFADE)
462                        GLib.timeout_add(30,self.check_fade_out)
463                        self.fade_box_revealer.set_reveal_child(False)
464                       
465        #def main_eb_clicked
466
467       
468        def menu_button_clicked(self,widget):
469               
470                self.fade_box_revealer.set_transition_type(Gtk.RevealerTransitionType.CROSSFADE)
471                self.popup_menu.revealer.set_reveal_child(not self.popup_menu.revealer.get_reveal_child())
472                self.fade_box_revealer.set_reveal_child(True)
473               
474        #def menu_button_clicked
475
476
477        def check_fade_out(self):
478               
479                if self.fade_box_revealer.get_child_revealed():
480                        return True
481                       
482                self.fade_box_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP)
483               
484        #def check_fade_out
485       
486        # ########################################## #
487       
488
489
490       
491       
492       
493#class LliurexStore
494
495if __name__=="__main__":
496       
497        llx_store=LliurexStore()
Note: See TracBrowser for help on using the repository browser.