#!/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)