#!/usr/bin/newlisp # # A simple but effective Comic book viewer. # # ---------------------------- # REQUIREMENTS # ---------------------------- # -newLisp 10 or newer # -GTK-server 2.3.1 or newer # ---------------------------- # # Should run on Unix/BSD/Linux and Win32 # # Additional files required for Win32: # unzip.exe (public domain): http://gnuwin32.sourceforge.net/packages/unzip.htm # unrar.exe (freeware): http://unxutils.sourceforge.net/ # # (c) Peter van Eerten, december 2007, december 2008 - GPL. # # Some free comics here: http://www.flashbackuniverse.com/ # http://www.freecomicbooks.org/ # # 1.0: -initial release # 1.1: -when changing pages always scroll up # 1.2: -dragging of picture while mousebutton is pressed # -mouse scrollbutton to turn pages # -some code cleaning because of fixed bugs in newLisp interpreter # -escape key now exits program # -fixed wrapping around the last page # -cursor up/down: scroll page up/down # -added HELP dialog with keybinding explanation # -improved embedded GTK routines # 1.3: -now also recognizes 'ZIP' extension # 1.4: -also scroll left when turning pages # -set icon in window bars # -ability to tearoff popup menu # 1.5: -fixed detection of mouse button when special key was active # 1.6: -fixed crash when none of the pages were in a correct format # -code improvements # 1.7: -compliant with newLisp 10, also requirement now (december 2008) # -improved dynamic symbol creation to prevent overwriting existing symbols (december 2008) # -corrected GTK version detection for tooltips (december 2008) # -resized file selector (december 2008) # -solved bug with scroll events (december 2008) # #------------------------------------------------------- GTK stuff # Import GTK-server and create global symbols for GTK function names (case ostype ("Win32" (import "gtk-server.dll" "gtk")) ("OSX" (import "libgtk-server.dylib" "gtk")) (true (import "libgtk-server.so" "gtk"))) # Now try to find GTK-server configfile (set 'cfgfile (open "gtk-server.cfg" "read")) (when (not cfgfile) (set 'cfgfile (open "/usr/local/etc/gtk-server.cfg" "read")) (when (not cfgfile) (set 'cfgfile (open "/etc/gtk-server.cfg" "read")))) # No configfile? Exit (when (not cfgfile)(println "No GTK-server configfile found! Exiting...")(exit)) # Create global GTK symbols (while (read-line cfgfile) (when (and (starts-with (current-line) "FUNCTION_NAME") (regex "gtk_+|gdk_+|g_+" (current-line))) (set 'func (chop ((parse (current-line) " ") 2))) (set 'lb (append {(lambda()(setq s "} func {")(dolist (x (args))(setq s (string s " " x)))(get-string (gtk s)))})) (constant (global (sym func)) (eval-string lb)))) (close cfgfile) (constant (global 'NULL) "NULL") #------------------------------------------------------- (define (show_comic_forward) (if (= (gtk_check_menu_item_get_active page_menu) "1") (begin # Resize with GDK_PIXBUF function (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) (/ screen_width 2) screen_height 1 NULL)) # Problem with picture? (if (= tmp_pix "0") (begin (gtk_widget_hide image1) (gtk_widget_hide image2) (gtk_widget_show error_dialog) (set 'offset 1) ) (begin # Check if image can be put in one page (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (if (< pix_height pix_width) # Picture 1 is big size (begin (g_object_unref tmp_pix) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) screen_width screen_height 1 NULL)) (gtk_image_set_from_pixbuf image1 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image1) (gtk_widget_hide image2) (set 'offset 1) ) # Picture 1 is normal size (begin (gtk_image_set_from_pixbuf image1 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image1) (if (>= page_nr (- (length all_pages) 1)) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages 0) {"}) (/ screen_width 2) screen_height 1 NULL)) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages (+ page_nr 1)) {"}) (/ screen_width 2) screen_height 1 NULL)) ) # Problem with picture? (if (= tmp_pix "0") (begin (gtk_widget_hide image2) (gtk_widget_show error_dialog) (set 'offset 2) ) (begin (gtk_image_set_from_pixbuf image2 tmp_pix) (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (g_object_unref tmp_pix) (if (< pix_height pix_width) # Picture 2 is big size (begin (gtk_widget_hide image2) (set 'offset 1) ) # Picture 2 is normal size (begin (gtk_widget_show image2) (set 'offset 2) ) ) ) ) ) ) ) ) ) # Show one page at a time (begin (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) screen_width -1 1 NULL)) (if (= tmp_pix "0") # Problem with picture? (begin (gtk_widget_hide image1) (gtk_widget_hide image2) (gtk_widget_show error_dialog) (set 'offset 1) ) (begin (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (when (< pix_height pix_width) (g_object_unref tmp_pix) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) (* screen_width 2) (* screen_height 2) 1 NULL)) ) (gtk_image_set_from_pixbuf image1 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image1) (gtk_widget_hide image2) (set 'offset 1) ) ) ) ) # Scroll up (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (gtk_adjustment_set_value v_adj 0) # Scroll left (set 'h_adj (gtk_scrolled_window_get_hadjustment scrolled_win)) (gtk_adjustment_set_value h_adj 0) ) (define (show_comic_backward) # Decrease page (dec page_nr) (if (< page_nr 0) (set 'page_nr (- (length all_pages) 1))) # 2 pages or 1? (if (= (gtk_check_menu_item_get_active page_menu) "1") (begin # Resize with GDK_PIXBUF function (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) (/ screen_width 2) screen_height 1 NULL)) (if (= tmp_pix "0") (begin (gtk_widget_hide image1) (gtk_widget_hide image2) (gtk_widget_show error_dialog) (set 'offset 1) ) (begin # Check if image can be put in one page (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (if (< pix_height pix_width) # Picture 1 is big size (begin (g_object_unref tmp_pix) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) screen_width screen_height 1 NULL)) (gtk_image_set_from_pixbuf image2 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image2) (gtk_widget_hide image1) (set 'offset 1) ) # Picture 1 is normal size (begin (gtk_image_set_from_pixbuf image2 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image2) (dec page_nr) (if (< page_nr 0) (set 'page_nr (- (length all_pages) 1))) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) (/ screen_width 2) screen_height 1 NULL)) (if (= tmp_pix "0") (begin (gtk_widget_hide image1) (gtk_widget_show error_dialog) (set 'offset 2) ) (begin (gtk_image_set_from_pixbuf image1 tmp_pix) (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (g_object_unref tmp_pix) (if (< pix_height pix_width) # Picture 2 is big size (begin (gtk_widget_hide image1) (set 'offset 1) ) # Picture 2 is normal size (begin (gtk_widget_show image1) (set 'offset 2) ) ) ) ) ) ) ) ) ) # Show one page at a time (begin (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) screen_width -1 1 NULL)) (if (= tmp_pix "0") # Problem with picture? (begin (gtk_widget_hide image1) (gtk_widget_hide image2) (gtk_widget_show error_dialog) (set 'offset 1) ) (begin (set 'pix_height (int (gdk_pixbuf_get_height tmp_pix))) (set 'pix_width (int (gdk_pixbuf_get_width tmp_pix))) (when (< pix_height pix_width) (g_object_unref tmp_pix) (set 'tmp_pix (gdk_pixbuf_new_from_file_at_scale (append {"} temp_dir "/" (all_pages page_nr) {"}) (* screen_width 2) (* screen_height 2) 1 NULL)) ) (gtk_image_set_from_pixbuf image2 tmp_pix) (g_object_unref tmp_pix) (gtk_widget_show image2) (gtk_widget_hide image1) (set 'offset 1) ) ) ) ) # Scroll up (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (gtk_adjustment_set_value v_adj 0) # Scroll left (set 'h_adj (gtk_scrolled_window_get_hadjustment scrolled_win)) (gtk_adjustment_set_value h_adj 0) ) # Load comic (define (load_comic) # Get selected dirname (set 'curname (gtk_file_chooser_get_filename file_sel)) # Hide fileselection (gtk_widget_hide file_dialog) (if (and (not (directory? curname)) (ends-with curname "cbz|cbr|rar|zip" 1)) (begin (if (= ostype "Win32") (begin (set 'temp_dir (append (env "TEMP") "/comic")) (replace "\\" temp_dir "/") # Set title (gtk_window_set_title win (append {"} "Peter's Comic Book Reader - " (last (parse curname "\\")) {"})) ) (begin (set 'temp_dir "/tmp/comic") # Set title (gtk_window_set_title win (append {"} "Peter's Comic Book Reader - " (last (parse curname "/")) {"})) ) ) # Inform user (gtk_widget_show_all info_dialog) # Give GTK some time to update all events, then update our GUI (sleep 200) (while (= (gtk_events_pending) "1")(gtk_main_iteration)) # Create temp dir and empty (make-dir temp_dir) # Make sure directory is empty (dolist (x (directory temp_dir)) (delete-file (append temp_dir "/" x))) # Now unpack the comic file (if (ends-with curname "cbz|zip" 1) (set 'result (exec (append "unzip -j \"" curname "\" -d " temp_dir)))) (if (ends-with curname "cbr|rar" 1) (set 'result (exec (append "unrar e \"" curname "\" " temp_dir)))) # Hide information user (gtk_widget_hide info_dialog) (if (> (length result) 0) (begin # Get list of all files (set 'all_pages (sort (directory temp_dir ".jpg$|.gif$|.png$" 1) )) # Set pagenumber to 1 (set 'page_nr 0) # Show the first pages (if (and (!= all_pages nil) (> (length all_pages) 0)) (show_comic_forward) (gtk_widget_show error_dialog) ) ) (begin # Could not execute unzip or unrar (set 'all_pages nil) (gtk_widget_show_all warning_dialog) ) ) ) ) ) # Show next page (define (show_next) (if (!= all_pages nil) (begin (set 'page_nr (+ page_nr offset)) (if (> page_nr (- (length all_pages) 1)) (set 'page_nr (- page_nr (length all_pages) ))) (show_comic_forward) ) (set 'page_nr 0) ) ) # Show previous page (define (show_previous) (if (!= all_pages nil) (show_comic_backward)) ) # Check GTK version #(gtk_server_cfg "-log=/tmp/comic.lsp.log") (when (> (length (gtk_check_version 2 6 0)) 0) (println "Your GTK installation is too old!") (println "GTK version 2.6.0 or higher is required. Exiting...") (exit)) # Window (gtk_init NULL NULL) (set 'win (gtk_window_new 0)) (gtk_widget_set_size_request win 400 350) (gtk_window_set_position win 1) (gtk_window_set_title win {"Peter's Comic Book Reader 1.7"}) (gtk_window_set_icon_name win "eclipse") # Connect key-press event to window (gtk_server_connect win "key-press-event key-press-event") # Create tooltips (if (> (length (gtk_check_version 2 12 0)) 0) (begin (set 'win_tips (gtk_tooltips_new)) (gtk_tooltips_set_tip win_tips win {"Press right mousebutton for menu"} "''") ) (gtk_widget_set_tooltip_text win {"Press right mousebutton for menu"}) ) # Create widget to display image (set 'image1 (gtk_image_new)) (set 'image2 (gtk_image_new)) # Create eventbox to catch mouseclick (set 'ebox1 (gtk_event_box_new)) (set 'ebox2 (gtk_event_box_new)) (gtk_container_add ebox1 image1) (gtk_container_add ebox2 image2) (set 'hbox_image (gtk_hbox_new 0 0)) (gtk_box_pack_start hbox_image ebox1 1 1 1) (gtk_box_pack_start hbox_image ebox2 1 1 1) # Put eventbox to scrolled window (set 'scrolled_win (gtk_scrolled_window_new NULL NULL)) (gtk_scrolled_window_set_shadow_type scrolled_win 0) (gtk_scrolled_window_add_with_viewport scrolled_win hbox_image) (gtk_scrolled_window_set_policy scrolled_win 1 1) (gtk_container_add win scrolled_win) # Create contextmenu (set 'menu (gtk_menu_new)) (set 'tear_menu (gtk_tearoff_menu_item_new)) (set 'open_menu (gtk_menu_item_new_with_label {"Open comic"})) (set 'sep1 (gtk_separator_menu_item_new)) (set 'next_menu (gtk_menu_item_new_with_label {"Next page"})) (set 'prev_menu (gtk_menu_item_new_with_label {"Previous page"})) (set 'sep2 (gtk_separator_menu_item_new)) (set 'first_menu (gtk_menu_item_new_with_label {"Goto first page"})) (set 'sep3 (gtk_separator_menu_item_new)) (set 'page_menu (gtk_check_menu_item_new_with_label {"Toggle 2-page"})) (set 'sep4 (gtk_separator_menu_item_new)) (set 'full_menu (gtk_check_menu_item_new_with_label {"Toggle fullscreen"})) (set 'sep5 (gtk_separator_menu_item_new)) (set 'help_menu (gtk_menu_item_new_with_label {"Help"})) (set 'about_menu (gtk_menu_item_new_with_label {"About"})) (set 'sep6 (gtk_separator_menu_item_new)) (set 'exit_menu (gtk_menu_item_new_with_label "Exit")) (gtk_menu_shell_append menu tear_menu) (gtk_menu_shell_append menu open_menu) (gtk_menu_shell_append menu sep1) (gtk_menu_shell_append menu next_menu) (gtk_menu_shell_append menu prev_menu) (gtk_menu_shell_append menu sep2) (gtk_menu_shell_append menu first_menu) (gtk_menu_shell_append menu sep3) (gtk_menu_shell_append menu page_menu) (gtk_menu_shell_append menu sep4) (gtk_menu_shell_append menu full_menu) (gtk_menu_shell_append menu sep5) (gtk_menu_shell_append menu help_menu) (gtk_menu_shell_append menu about_menu) (gtk_menu_shell_append menu sep6) (gtk_menu_shell_append menu exit_menu) (gtk_check_menu_item_set_active page_menu 1) (gtk_menu_set_title menu "Actions") (gtk_widget_show_all menu) # Connect mouse button signals (gtk_server_connect ebox1 "button-press-event" "popup") (gtk_server_connect ebox2 "button-press-event" "popup") (gtk_server_connect ebox1 "button-release-event" "release") (gtk_server_connect ebox2 "button-release-event" "release") (gtk_server_connect ebox1 "motion-notify-event" "motion") (gtk_server_connect ebox2 "motion-notify-event" "motion") (gtk_server_connect_after ebox1 "scroll-event" "scroll-event" 1) (gtk_server_connect_after ebox2 "scroll-event" "scroll-event" 1) # Create fileselector (set 'file_dialog (gtk_window_new 0)) (gtk_window_set_title file_dialog {"Browse directory"}) (gtk_window_set_transient_for file_dialog win) (gtk_window_set_position file_dialog 4) (gtk_window_set_icon_name file_dialog "eclipse") (gtk_window_set_default_size file_dialog 750 600) (set 'file_sel (gtk_file_chooser_widget_new 0)) (gtk_file_chooser_set_local_only file_sel 1) (set 'filter_comic (gtk_file_filter_new)) (gtk_file_filter_set_name filter_comic {"Comics (*.cbr; *.cbz; *.rar; *.zip)"}) (gtk_file_filter_add_pattern filter_comic "*.cbr") (gtk_file_filter_add_pattern filter_comic "*.cbz") (gtk_file_filter_add_pattern filter_comic "*.rar") (gtk_file_filter_add_pattern filter_comic "*.zip") (set 'filter_all (gtk_file_filter_new)) (gtk_file_filter_set_name filter_all {"All files (*.*)"}) (gtk_file_filter_add_pattern filter_all "*") (gtk_file_chooser_add_filter file_sel filter_comic) (gtk_file_chooser_add_filter file_sel filter_all) (set 'file_ok (gtk_button_new_from_stock "gtk-open")) (gtk_widget_set_size_request file_ok 100 30) (set 'file_cancel (gtk_button_new_from_stock "gtk-cancel")) (gtk_widget_set_size_request file_cancel 100 30) # Arrange widgets on window (set 'file_vbox (gtk_vbox_new 0 0)) (set 'file_hbox (gtk_hbox_new 0 0)) (gtk_box_pack_end file_hbox file_ok 0 0 1) (gtk_box_pack_end file_hbox file_cancel 0 0 1) (gtk_box_pack_start file_vbox file_sel 1 1 1) (gtk_box_pack_start file_vbox file_hbox 0 0 1) (gtk_container_add file_dialog file_vbox) # Create ABOUT box (set 'about_dialog (gtk_message_dialog_new_with_markup win 0 0 2 (append "\"*** Comic Book reader written in newLisp ***\\\r\\\rUsing newLisp " (string (sys-info -2)) " with GTK-server " (gtk_server_version) ".\\\r\\\rVisit http://www.gtk-server.org/ for more info!\"") "''")) (gtk_window_set_title about_dialog {"About Peter's Comic Book Reader"}) (gtk_window_set_icon_name about_dialog "eclipse") # Create INFO box (set 'info_dialog (gtk_message_dialog_new_with_markup win 0 0 3 {"Caching files, please wait..."} "''")) (gtk_window_set_title info_dialog {"Progress information"}) (gtk_window_set_icon_name info_dialog "eclipse") # Create ERROR box (set 'error_dialog (gtk_message_dialog_new_with_markup win 0 1 2 {"Error in format!\r\rThis page cannot be displayed."} "''")) (gtk_window_set_title error_dialog {"Error!"}) (gtk_window_set_icon_name error_dialog "eclipse") # Create WARNING box (set 'warning_dialog (gtk_message_dialog_new_with_markup win 0 1 2 {"Could not unpack files!\r\rMake sure 'unrar' and 'unzip' are installed."} "''")) (gtk_window_set_title warning_dialog {"Warning!"}) (gtk_window_set_icon_name warning_dialog "eclipse") # Create HELP (set 'help_dialog (gtk_message_dialog_new_with_markup win 0 0 2 (append "\"\t*** Key Bindings ***\\\r\\\r[cursor up/down]\tScroll up/down\\\r[cursor left/right]\tPrevious/next page\\\r[space]\t\t\tNext page\\\r[f]\t\t\t\tToggle fullscreen\\\r[escape]\t\t\tExit program\"") "''")) (gtk_window_set_title help_dialog {"Help instructions"}) (gtk_window_set_icon_name help_dialog "eclipse") # Create mousecursors (set 'grab_cursor (gdk_cursor_new 60)) (set 'def_cursor (gdk_cursor_new 68)) # Show all widgets (gtk_widget_show_all win) # Get some constants (constant 'gdk_screen (gdk_screen_get_default)) (constant 'screen_width (- (int (gdk_screen_get_width gdk_screen)) 8)) (constant 'screen_height (- (int (gdk_screen_get_height gdk_screen)) 8)) # Redefine the g_object_get call (gtk_server_redefine "g_object_get NONE NONE 4 WIDGET STRING PTR_DOUBLE NULL") # Temp dir is empty (set 'temp_dir "") # Pagenr = 1 (set 'page_nr 0) # Step per offset pages (set 'offset 2) # Flush pending events (while (= (gtk_events_pending) "1")(gtk_main_iteration)) # Mainloop. Exit when menu, window or escape key is pressed (do-until (or (= event exit_menu) (= event win) (= key 65307)) # Get event (set 'event (gtk_server_callback "wait")) # Check scrolling (when (= event "scroll-event") (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (set 'v_val (int (gtk_adjustment_get_value v_adj))) (set 'upper (- (int (g_object_get v_adj "upper" 0 0)) (int (g_object_get v_adj "page-size" 0 0)) )) (if (= (gtk_server_mouse 3) "1") (if (>= v_val upper) (show_next)) ) (if (= (gtk_server_mouse 3) "0") (if (<= v_val 0) (show_previous)) ) ) # Check if mouse was pressed (when (= event "popup") (if (= (gtk_server_mouse 2) "3") (gtk_menu_popup menu NULL NULL NULL NULL 3 0)) (when (= (gtk_server_mouse 2) "1") (set 'gdk_win (gtk_widget_get_parent_window scrolled_win)) (gdk_window_set_cursor gdk_win grab_cursor) (set 'mouse_x (int (gtk_server_mouse 0))) (set 'mouse_y (int (gtk_server_mouse 1))) ) ) # Check if mouse is released -> change cursor back to default (when (= event "release") (set 'gdk_win (gtk_widget_get_parent_window scrolled_win)) (gdk_window_set_cursor gdk_win def_cursor) ) # Check if mouse is moved, if so scroll image (when (= event "motion") (set 'h_adj (gtk_scrolled_window_get_hadjustment scrolled_win)) (set 'h_val (int (gtk_adjustment_get_value h_adj))) (set 'upper (- (int (g_object_get h_adj "upper" 0 0)) (int (g_object_get h_adj "page-size" 0 0)) )) (set 'tmp_x (int (gtk_server_mouse 0))) (if (< (- h_val (- tmp_x mouse_x)) upper) (gtk_adjustment_set_value h_adj (- h_val (- tmp_x mouse_x))) (gtk_adjustment_set_value h_adj upper) ) (set 'mouse_x tmp_x) (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (set 'v_val (int (gtk_adjustment_get_value v_adj))) (set 'upper (- (int (g_object_get v_adj "upper" 0 0)) (int (g_object_get v_adj "page-size" 0 0)) )) (set 'tmp_y (int (gtk_server_mouse 1))) (if (< (- v_val (- tmp_y mouse_y)) upper) (gtk_adjustment_set_value v_adj (- v_val (- tmp_y mouse_y))) (gtk_adjustment_set_value v_adj upper) ) (set 'mouse_y tmp_y) ) # Open dialog (if (= event open_menu) (gtk_widget_show_all file_dialog)) # Hide dialog (if (or (= event file_dialog) (= event file_cancel)) (gtk_widget_hide file_dialog)) # About menu (if (= event about_menu)(gtk_widget_show_all about_dialog)) # About dialog (if (= event about_dialog)(gtk_widget_hide about_dialog)) # Error dialog (if (= event error_dialog)(gtk_widget_hide error_dialog)) # Warning dialog (if (= event warning_dialog)(gtk_widget_hide warning_dialog)) # Help menu (if (= event help_menu)(gtk_widget_show_all help_dialog)) # Help dialog (if (= event help_dialog)(gtk_widget_hide help_dialog)) # Open directory (if (= event file_ok) (load_comic)) # Show next (if (= event next_menu) (show_next)) # Show previous (if (= event prev_menu) (show_previous)) # Show 1 or 2 pages (if (and (= event page_menu)(!= all_pages nil)) (show_comic_forward)) # Goto first page (when (and (= event first_menu)(!= all_pages nil)) (set 'page_nr 0) (show_comic_forward) ) # Fullscreen toggle (when (= event full_menu) (if (= (gtk_check_menu_item_get_active full_menu) "1") (gtk_window_fullscreen win) (gtk_window_unfullscreen win) ) ) # Check if key pressed (when (= event "key-press-event") (set 'key (int (gtk_server_key))) (case key # Space (32 (show_next)) # Cursor right (65363 (show_next)) # Cursor left (65361 (show_previous)) # Cursor up (65362 (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (set 'v_val (int (gtk_adjustment_get_value v_adj))) (set 'upper (- (int (g_object_get v_adj "upper" 0 0)) (int (g_object_get v_adj "page-size" 0 0)) )) (if (> (- v_val 15) 0) (gtk_adjustment_set_value v_adj (- v_val 15)) (gtk_adjustment_set_value v_adj 0) ) ) # Cursor down (65364 (set 'v_adj (gtk_scrolled_window_get_vadjustment scrolled_win)) (set 'v_val (int (gtk_adjustment_get_value v_adj))) (set 'upper (- (int (g_object_get v_adj "upper" 0 0)) (int (g_object_get v_adj "page-size" 0 0)) )) (if (< (+ v_val 15) upper) (gtk_adjustment_set_value v_adj (+ v_val 15)) (gtk_adjustment_set_value v_adj upper) ) ) # F-key: toggle fullscreen (102 (if (= (gtk_check_menu_item_get_active full_menu) "0") (begin (gtk_window_fullscreen win) (gtk_check_menu_item_set_active full_menu 1) # Flush full_menu event (gtk_server_callback "update") ) (begin (gtk_window_unfullscreen win) (gtk_check_menu_item_set_active full_menu 0) # Flush full_menu event (gtk_server_callback "update") ) ) ) ) ) ) # Make sure TEMP directory is empty (if (directory? temp_dir) (dolist (x (directory temp_dir)) (delete-file (append temp_dir "/" x)))) # Exit newLisp (exit)