├── .gitignore ├── README.md ├── bin └── eluminance ├── data ├── desktop │ └── eluminance.desktop ├── icons │ ├── 128x128 │ │ └── apps │ │ │ └── eluminance.png │ ├── 48x48 │ │ └── apps │ │ │ └── eluminance.png │ └── scalable │ │ └── apps │ │ └── eluminance.svg ├── po │ ├── LINGUAS │ ├── POTFILES │ ├── de.po │ ├── eluminance.pot │ ├── en.po │ └── it.po ├── screenshots │ ├── eluminance01.jpg │ ├── eluminance02.jpg │ └── eluminance03.jpg └── themes │ └── default │ ├── cropper.edc │ ├── elm_slideshow.edc │ ├── images │ ├── bevel.png │ ├── bg_fill.png │ ├── bg_overlay.png │ ├── controls_bg.png │ ├── glint.png │ ├── icon_bookmark_add.png │ ├── icon_bookmark_remove.png │ ├── icon_document_save.png │ ├── icon_document_save_as.png │ ├── icon_edit_cut.png │ ├── icon_go_next.png │ ├── icon_go_previous.png │ ├── icon_info.png │ ├── icon_media_playback_pause.png │ ├── icon_media_playback_start.png │ ├── icon_object_flip_horizontal.png │ ├── icon_object_flip_vertical.png │ ├── icon_object_rotate_left.png │ ├── icon_object_rotate_right.png │ ├── icon_preferences_system.png │ ├── icon_resize.png │ ├── icon_rotate.png │ ├── icon_starred.png │ ├── icon_view_fullscreen.png │ ├── icon_zoom.png │ ├── icon_zoom_fit_best.png │ ├── icon_zoom_in.png │ ├── icon_zoom_original.png │ ├── icon_zoom_out.png │ ├── sel_border.png │ ├── sel_corner1.png │ ├── sel_corner3.png │ ├── sel_corner5.png │ ├── sel_corner7.png │ └── status_bg.png │ └── main.edc ├── eluminance ├── __init__.py ├── eluminance.py └── utils.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | installed_files.txt 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Eluminance 2 | ========== 3 | 4 | A fast photo browser written in python. 5 | 6 | ![Screenshot1](https://github.com/davemds/eluminance/blob/master/data/screenshots/eluminance01.jpg) 7 | ![Screenshot2](https://github.com/davemds/eluminance/blob/master/data/screenshots/eluminance02.jpg) 8 | ![Screenshot3](https://github.com/davemds/eluminance/blob/master/data/screenshots/eluminance03.jpg) 9 | 10 | ## Usage tips ## 11 | * The ui provide 3 hotspots to show controls on mouse hover: 12 | * top of the window to show the control buttons 13 | * right to show the thumbnails in the current directory 14 | * left to show the directory tree 15 | * Right mouse button on the photo to toggle the visibility of the tree and the thumbnails 16 | * Mouse wheel to change zoom 17 | * Drag the image to pan around 18 | 19 | ## Requirements ## 20 | 21 | * Python 2.7 or higher 22 | * Python-EFL 1.14 or higher 23 | * python modules: efl, xdg 24 | 25 | ## Installation ## 26 | 27 | * For system-wide installation (needs administrator privileges): 28 | 29 | `(sudo) python setup.py install` 30 | 31 | * For user installation: 32 | 33 | `python setup.py install --user` 34 | 35 | * To install for different version of python: 36 | 37 | `pythonX setup.py install` 38 | 39 | * Install with a custom prefix: 40 | 41 | `python setup.py install --prefix=/MY_PREFIX` 42 | 43 | * To create distribution packages: 44 | 45 | `python setup.py sdist` 46 | 47 | ## License ## 48 | 49 | GNU General Public License v3 - see COPYING 50 | -------------------------------------------------------------------------------- /bin/eluminance: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from eluminance.eluminance import main 4 | 5 | sys.exit(main()) 6 | -------------------------------------------------------------------------------- /data/desktop/eluminance.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Type=Application 4 | Name=Eluminance 5 | GenericName=Image Viewer 6 | GenericName[it]=Visualizzatore immagini 7 | Icon=eluminance 8 | Exec=eluminance %f 9 | Terminal=false 10 | MimeType=inode/directory;image/bmp;image/jpeg;image/gif;image/png;image/tiff;image/x-bmp;image/x-ico;image/x-png;image/x-pcx;image/x-tga;image/xpm;image/svg+xml; 11 | Categories=Graphics;Viewer;Photography; 12 | -------------------------------------------------------------------------------- /data/icons/128x128/apps/eluminance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/icons/128x128/apps/eluminance.png -------------------------------------------------------------------------------- /data/icons/48x48/apps/eluminance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/icons/48x48/apps/eluminance.png -------------------------------------------------------------------------------- /data/icons/scalable/apps/eluminance.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 25 | 28 | 32 | 36 | 37 | 40 | 44 | 48 | 49 | 52 | 56 | 60 | 61 | 64 | 68 | 72 | 73 | 76 | 80 | 84 | 85 | 95 | 106 | 114 | 118 | 119 | 128 | 139 | 150 | 159 | 169 | 180 | 188 | 192 | 193 | 201 | 205 | 206 | 210 | 213 | 214 | 215 | 247 | 252 | 253 | 255 | 256 | 258 | image/svg+xml 259 | 261 | 262 | 263 | 264 | 265 | 271 | 278 | 284 | 290 | 295 | 297 | 302 | 312 | 321 | 331 | 332 | 339 | 344 | 350 | 356 | 362 | 371 | 380 | 389 | 398 | 399 | 400 | -------------------------------------------------------------------------------- /data/po/LINGUAS: -------------------------------------------------------------------------------- 1 | en 2 | it 3 | de 4 | -------------------------------------------------------------------------------- /data/po/POTFILES: -------------------------------------------------------------------------------- 1 | eluminance/eluminance.py 2 | eluminance/utils.py 3 | -------------------------------------------------------------------------------- /data/po/de.po: -------------------------------------------------------------------------------- 1 | # German translation for Eluminance 2 | # Copyright (C) 2015 Davide Andreoli 3 | # This file is distributed under the same license as the Eluminance package. 4 | # Davide Andreoli , 2015. 5 | # Wolfgang Morawetz , 2015. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Eluminance 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2015-05-24 18:13+0200\n" 12 | "PO-Revision-Date: 2015-10-10 19:46+0200\n" 13 | "Last-Translator: Wolfgang Morawetz \n" 14 | "Language-Team: Deutsch <>\n" 15 | "Language: German\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | "X-Generator: Gtranslator 2.91.7\n" 21 | 22 | #: eluminance/eluminance.py:174 23 | msgid "No items to show" 24 | msgstr "Keine einträge vorhanden" 25 | 26 | #: eluminance/eluminance.py:206 27 | msgid "Set as root" 28 | msgstr "Hauptverzeichnis Festlegen" 29 | 30 | #: eluminance/eluminance.py:209 31 | msgid "Remove from favorites" 32 | msgstr "Aus Favoriten entfernen" 33 | 34 | #: eluminance/eluminance.py:212 35 | msgid "Add to favorites" 36 | msgstr "Zu Favoriten hinzufügen" 37 | 38 | #: eluminance/eluminance.py:587 39 | msgid "No image selected" 40 | msgstr "Kein Bild ausgewählt" 41 | 42 | #: eluminance/eluminance.py:603 43 | #, python-brace-format 44 | msgid "File {0} of {1}" 45 | msgstr "Datei {0} von {1}" 46 | 47 | #: eluminance/eluminance.py:607 48 | msgid "Resolution" 49 | msgstr "Auflösung" 50 | 51 | #: eluminance/eluminance.py:608 52 | msgid "Size" 53 | msgstr "Größe" 54 | 55 | #: eluminance/eluminance.py:609 56 | msgid "Zoom" 57 | msgstr "Bildvergrößerung" 58 | 59 | #: eluminance/eluminance.py:626 60 | msgid "Zoom in" 61 | msgstr "Vergrößern" 62 | 63 | #: eluminance/eluminance.py:627 64 | msgid "Zoom out" 65 | msgstr "Verkleinern" 66 | 67 | #: eluminance/eluminance.py:628 68 | msgid "Zoom 1:1" 69 | msgstr "Original Göße" 70 | 71 | #: eluminance/eluminance.py:629 72 | msgid "Zoom fit" 73 | msgstr "Einpassen" 74 | 75 | #: eluminance/eluminance.py:630 76 | msgid "Zoom fill" 77 | msgstr "Anpassen" 78 | 79 | #: eluminance/eluminance.py:632 80 | msgid "Previous photo" 81 | msgstr "Vorheriges Bild" 82 | 83 | #: eluminance/eluminance.py:633 84 | msgid "Next photo" 85 | msgstr "Nächstes Bild" 86 | 87 | #: eluminance/eluminance.py:634 88 | msgid "Start/Stop slideshow" 89 | msgstr "Start/Stop Diaschau" 90 | 91 | #: eluminance/eluminance.py:635 92 | msgid "Transition time" 93 | msgstr "Übergangszeit" 94 | 95 | #: eluminance/eluminance.py:636 96 | msgid "Transition style" 97 | msgstr "Übergangsstil" 98 | 99 | #: eluminance/eluminance.py:638 100 | msgid "Toggle fullscreen mode" 101 | msgstr "Wechsle Vollbildmodus" 102 | 103 | #: eluminance/eluminance.py:639 104 | msgid "Eluminance info" 105 | msgstr "Eluminance info" 106 | 107 | #: eluminance/eluminance.py:647 eluminance/eluminance.py:696 108 | msgid "Play" 109 | msgstr "Abspielen" 110 | 111 | #: eluminance/eluminance.py:689 112 | msgid "Pause" 113 | msgstr "Pause" 114 | 115 | #: eluminance/eluminance.py:819 116 | #, python-format 117 | msgid "Version: %s" 118 | msgstr "Version: %s" 119 | 120 | #: eluminance/eluminance.py:828 121 | msgid "Eluminance" 122 | msgstr "Eluminance" 123 | 124 | #: eluminance/eluminance.py:833 125 | msgid "Website" 126 | msgstr "Webseite" 127 | 128 | #: eluminance/eluminance.py:838 129 | msgid "Authors" 130 | msgstr "Autoren" 131 | 132 | #: eluminance/eluminance.py:843 133 | msgid "License" 134 | msgstr "Lizenz" 135 | -------------------------------------------------------------------------------- /data/po/eluminance.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2015-05-24 18:13+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: eluminance/eluminance.py:174 21 | msgid "No items to show" 22 | msgstr "" 23 | 24 | #: eluminance/eluminance.py:206 25 | msgid "Set as root" 26 | msgstr "" 27 | 28 | #: eluminance/eluminance.py:209 29 | msgid "Remove from favorites" 30 | msgstr "" 31 | 32 | #: eluminance/eluminance.py:212 33 | msgid "Add to favorites" 34 | msgstr "" 35 | 36 | #: eluminance/eluminance.py:587 37 | msgid "No image selected" 38 | msgstr "" 39 | 40 | #: eluminance/eluminance.py:603 41 | #, python-brace-format 42 | msgid "File {0} of {1}" 43 | msgstr "" 44 | 45 | #: eluminance/eluminance.py:607 46 | msgid "Resolution" 47 | msgstr "" 48 | 49 | #: eluminance/eluminance.py:608 50 | msgid "Size" 51 | msgstr "" 52 | 53 | #: eluminance/eluminance.py:609 54 | msgid "Zoom" 55 | msgstr "" 56 | 57 | #: eluminance/eluminance.py:626 58 | msgid "Zoom in" 59 | msgstr "" 60 | 61 | #: eluminance/eluminance.py:627 62 | msgid "Zoom out" 63 | msgstr "" 64 | 65 | #: eluminance/eluminance.py:628 66 | msgid "Zoom 1:1" 67 | msgstr "" 68 | 69 | #: eluminance/eluminance.py:629 70 | msgid "Zoom fit" 71 | msgstr "" 72 | 73 | #: eluminance/eluminance.py:630 74 | msgid "Zoom fill" 75 | msgstr "" 76 | 77 | #: eluminance/eluminance.py:632 78 | msgid "Previous photo" 79 | msgstr "" 80 | 81 | #: eluminance/eluminance.py:633 82 | msgid "Next photo" 83 | msgstr "" 84 | 85 | #: eluminance/eluminance.py:634 86 | msgid "Start/Stop slideshow" 87 | msgstr "" 88 | 89 | #: eluminance/eluminance.py:635 90 | msgid "Transition time" 91 | msgstr "" 92 | 93 | #: eluminance/eluminance.py:636 94 | msgid "Transition style" 95 | msgstr "" 96 | 97 | #: eluminance/eluminance.py:638 98 | msgid "Toggle fullscreen mode" 99 | msgstr "" 100 | 101 | #: eluminance/eluminance.py:639 102 | msgid "Eluminance info" 103 | msgstr "" 104 | 105 | #: eluminance/eluminance.py:647 eluminance/eluminance.py:696 106 | msgid "Play" 107 | msgstr "" 108 | 109 | #: eluminance/eluminance.py:689 110 | msgid "Pause" 111 | msgstr "" 112 | 113 | #: eluminance/eluminance.py:819 114 | #, python-format 115 | msgid "Version: %s" 116 | msgstr "" 117 | 118 | #: eluminance/eluminance.py:828 119 | msgid "Eluminance" 120 | msgstr "" 121 | 122 | #: eluminance/eluminance.py:833 123 | msgid "Website" 124 | msgstr "" 125 | 126 | #: eluminance/eluminance.py:838 127 | msgid "Authors" 128 | msgstr "" 129 | 130 | #: eluminance/eluminance.py:843 131 | msgid "License" 132 | msgstr "" 133 | -------------------------------------------------------------------------------- /data/po/en.po: -------------------------------------------------------------------------------- 1 | # English translation for Eluminance 2 | # Copyright (C) 2015 Davide Andreoli 3 | # This file is distributed under the same license as the Eluminance package. 4 | # Davide Andreoli , 2015. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: Eluminance 1.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2015-05-24 18:13+0200\n" 11 | "PO-Revision-Date: 2015-05-24 18:14+0200\n" 12 | "Last-Translator: Davide Andreoli \n" 13 | "Language-Team: \n" 14 | "Language: English\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 19 | 20 | #: eluminance/eluminance.py:174 21 | msgid "No items to show" 22 | msgstr "" 23 | 24 | #: eluminance/eluminance.py:206 25 | msgid "Set as root" 26 | msgstr "" 27 | 28 | #: eluminance/eluminance.py:209 29 | msgid "Remove from favorites" 30 | msgstr "" 31 | 32 | #: eluminance/eluminance.py:212 33 | msgid "Add to favorites" 34 | msgstr "" 35 | 36 | #: eluminance/eluminance.py:587 37 | msgid "No image selected" 38 | msgstr "No image selected" 39 | 40 | #: eluminance/eluminance.py:603 41 | #, python-brace-format 42 | msgid "File {0} of {1}" 43 | msgstr "File {0} of {1}" 44 | 45 | #: eluminance/eluminance.py:607 46 | msgid "Resolution" 47 | msgstr "Resolution" 48 | 49 | #: eluminance/eluminance.py:608 50 | msgid "Size" 51 | msgstr "Size" 52 | 53 | #: eluminance/eluminance.py:609 54 | msgid "Zoom" 55 | msgstr "Zoom" 56 | 57 | #: eluminance/eluminance.py:626 58 | msgid "Zoom in" 59 | msgstr "Zoom in" 60 | 61 | #: eluminance/eluminance.py:627 62 | msgid "Zoom out" 63 | msgstr "Zoom out" 64 | 65 | #: eluminance/eluminance.py:628 66 | msgid "Zoom 1:1" 67 | msgstr "Zoom 1:1" 68 | 69 | #: eluminance/eluminance.py:629 70 | msgid "Zoom fit" 71 | msgstr "Zoom fit" 72 | 73 | #: eluminance/eluminance.py:630 74 | msgid "Zoom fill" 75 | msgstr "" 76 | 77 | #: eluminance/eluminance.py:632 78 | msgid "Previous photo" 79 | msgstr "Previous photo" 80 | 81 | #: eluminance/eluminance.py:633 82 | msgid "Next photo" 83 | msgstr "Next photo" 84 | 85 | #: eluminance/eluminance.py:634 86 | msgid "Start/Stop slideshow" 87 | msgstr "Start/Stop slideshow" 88 | 89 | #: eluminance/eluminance.py:635 90 | msgid "Transition time" 91 | msgstr "Transition time" 92 | 93 | #: eluminance/eluminance.py:636 94 | msgid "Transition style" 95 | msgstr "Transition style" 96 | 97 | #: eluminance/eluminance.py:638 98 | msgid "Toggle fullscreen mode" 99 | msgstr "Toggle fullscreen mode" 100 | 101 | #: eluminance/eluminance.py:639 102 | msgid "Eluminance info" 103 | msgstr "Eluminance info" 104 | 105 | #: eluminance/eluminance.py:647 eluminance/eluminance.py:696 106 | msgid "Play" 107 | msgstr "Play" 108 | 109 | #: eluminance/eluminance.py:689 110 | msgid "Pause" 111 | msgstr "Pause" 112 | 113 | #: eluminance/eluminance.py:819 114 | #, python-format 115 | msgid "Version: %s" 116 | msgstr "Version: %s" 117 | 118 | #: eluminance/eluminance.py:828 119 | msgid "Eluminance" 120 | msgstr "Eluminance" 121 | 122 | #: eluminance/eluminance.py:833 123 | msgid "Website" 124 | msgstr "Website" 125 | 126 | #: eluminance/eluminance.py:838 127 | msgid "Authors" 128 | msgstr "Authors" 129 | 130 | #: eluminance/eluminance.py:843 131 | msgid "License" 132 | msgstr "License" 133 | -------------------------------------------------------------------------------- /data/po/it.po: -------------------------------------------------------------------------------- 1 | # Traduzione italiana per Eluminance. 2 | # Copyright (C) 2015 Davide Andreoli 3 | # This file is distributed under the same license as the Eluminance package. 4 | # Davide Andreoli , 2015. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: Eluminance 1.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2015-05-24 18:13+0200\n" 11 | "PO-Revision-Date: 2015-05-24 18:14+0200\n" 12 | "Last-Translator: Davide Andreoli \n" 13 | "Language-Team: \n" 14 | "Language: Italiano\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 19 | 20 | #: eluminance/eluminance.py:174 21 | msgid "No items to show" 22 | msgstr "" 23 | 24 | #: eluminance/eluminance.py:206 25 | msgid "Set as root" 26 | msgstr "" 27 | 28 | #: eluminance/eluminance.py:209 29 | msgid "Remove from favorites" 30 | msgstr "" 31 | 32 | #: eluminance/eluminance.py:212 33 | msgid "Add to favorites" 34 | msgstr "" 35 | 36 | #: eluminance/eluminance.py:587 37 | msgid "No image selected" 38 | msgstr "Nessuna immagine selezionata" 39 | 40 | #: eluminance/eluminance.py:603 41 | #, python-brace-format 42 | msgid "File {0} of {1}" 43 | msgstr "File {0} di {1}" 44 | 45 | #: eluminance/eluminance.py:607 46 | msgid "Resolution" 47 | msgstr "Risoluzione" 48 | 49 | #: eluminance/eluminance.py:608 50 | msgid "Size" 51 | msgstr "Dimensione" 52 | 53 | #: eluminance/eluminance.py:609 54 | msgid "Zoom" 55 | msgstr "Zoom" 56 | 57 | #: eluminance/eluminance.py:626 58 | msgid "Zoom in" 59 | msgstr "Aumenta zoom" 60 | 61 | #: eluminance/eluminance.py:627 62 | msgid "Zoom out" 63 | msgstr "Diminuisci zoom" 64 | 65 | #: eluminance/eluminance.py:628 66 | msgid "Zoom 1:1" 67 | msgstr "Zoom 1:1" 68 | 69 | #: eluminance/eluminance.py:629 70 | msgid "Zoom fit" 71 | msgstr "Adatta alla dimensione" 72 | 73 | #: eluminance/eluminance.py:630 74 | msgid "Zoom fill" 75 | msgstr "" 76 | 77 | #: eluminance/eluminance.py:632 78 | msgid "Previous photo" 79 | msgstr "Foto precedente" 80 | 81 | #: eluminance/eluminance.py:633 82 | msgid "Next photo" 83 | msgstr "Foto successiva" 84 | 85 | #: eluminance/eluminance.py:634 86 | msgid "Start/Stop slideshow" 87 | msgstr "Inizia/Interrompi presentazione" 88 | 89 | #: eluminance/eluminance.py:635 90 | msgid "Transition time" 91 | msgstr "Tempo tra le foto" 92 | 93 | #: eluminance/eluminance.py:636 94 | msgid "Transition style" 95 | msgstr "Stile della transizione" 96 | 97 | #: eluminance/eluminance.py:638 98 | msgid "Toggle fullscreen mode" 99 | msgstr "Alterna modalità schermo intero" 100 | 101 | #: eluminance/eluminance.py:639 102 | msgid "Eluminance info" 103 | msgstr "Informazioni" 104 | 105 | #: eluminance/eluminance.py:647 eluminance/eluminance.py:696 106 | msgid "Play" 107 | msgstr "Inizia" 108 | 109 | #: eluminance/eluminance.py:689 110 | msgid "Pause" 111 | msgstr "Interrompi" 112 | 113 | #: eluminance/eluminance.py:819 114 | #, python-format 115 | msgid "Version: %s" 116 | msgstr "Versione: %s" 117 | 118 | #: eluminance/eluminance.py:828 119 | msgid "Eluminance" 120 | msgstr "Eluminance" 121 | 122 | #: eluminance/eluminance.py:833 123 | msgid "Website" 124 | msgstr "Sito web" 125 | 126 | #: eluminance/eluminance.py:838 127 | msgid "Authors" 128 | msgstr "Autori" 129 | 130 | #: eluminance/eluminance.py:843 131 | msgid "License" 132 | msgstr "Licenza" 133 | -------------------------------------------------------------------------------- /data/screenshots/eluminance01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/screenshots/eluminance01.jpg -------------------------------------------------------------------------------- /data/screenshots/eluminance02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/screenshots/eluminance02.jpg -------------------------------------------------------------------------------- /data/screenshots/eluminance03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/screenshots/eluminance03.jpg -------------------------------------------------------------------------------- /data/themes/default/cropper.edc: -------------------------------------------------------------------------------- 1 | 2 | images { 3 | image: "sel_border.png" COMP; 4 | image: "sel_corner1.png" COMP; 5 | image: "sel_corner3.png" COMP; 6 | image: "sel_corner5.png" COMP; 7 | image: "sel_corner7.png" COMP; 8 | } 9 | 10 | 11 | group { name: "sel"; 12 | script { 13 | public message(Msg_Type:type, id, ...) { 14 | if ((type == MSG_FLOAT_SET) && (id == 1)) { 15 | new Float:rel1x, Float:rel1y; 16 | new Float:rel2x, Float:rel2y; 17 | 18 | rel1x = getfarg(2); 19 | rel1y = getfarg(3); 20 | rel2x = getfarg(4); 21 | rel2y = getfarg(5); 22 | 23 | custom_state(PART:"selector", "default", 0.0); 24 | set_state_val(PART:"selector", STATE_REL1, rel1x, rel1y); 25 | set_state_val(PART:"selector", STATE_REL2, rel2x, rel2y); 26 | set_state(PART:"selector", "custom", 0.0); 27 | } 28 | } 29 | } 30 | parts { 31 | part { name: "shader_top"; type: RECT; 32 | repeat_events: 1; 33 | description { state: "default" 0.0; 34 | color: 0 0 0 150; 35 | rel2 { 36 | to_y: "selector"; 37 | relative: 1.0 0.0; 38 | } 39 | } 40 | } 41 | part { name: "shader_bottom"; type: RECT; 42 | repeat_events: 1; 43 | description { state: "default" 0.0; 44 | color: 0 0 0 150; 45 | rel1 { 46 | to_y: "selector"; 47 | relative: 0.0 1.0; 48 | } 49 | } 50 | } 51 | part { name: "shader_left"; type: RECT; 52 | repeat_events: 1; 53 | description { state: "default" 0.0; 54 | color: 0 0 0 150; 55 | rel1 { 56 | to_y: "selector"; 57 | relative: 0.0 0.0; 58 | } 59 | rel2 { 60 | to: "selector"; 61 | relative: 0.0 1.0; 62 | } 63 | } 64 | } 65 | part { name: "shader_right"; type: RECT; 66 | repeat_events: 1; 67 | description { state: "default" 0.0; 68 | color: 0 0 0 150; 69 | rel1 { 70 | to: "selector"; 71 | relative: 1.0 0.0; 72 | } 73 | rel2 { 74 | to_y: "selector"; 75 | relative: 1.0 1.0; 76 | } 77 | } 78 | } 79 | part { name: "selector"; type: IMAGE; 80 | repeat_events: 1; 81 | description { state: "default" 0.0; 82 | color: 255 255 255 200; 83 | rel1.relative: 0.2 0.2; 84 | rel2.relative: 0.8 0.8; 85 | image { 86 | normal: "sel_border.png"; 87 | border: 3 3 3 3; 88 | middle: NONE; 89 | } 90 | } 91 | part { name: "h1"; type: IMAGE; 92 | repeat_events: 1; 93 | description { state: "default" 0.0; 94 | FIXED_SIZE(22, 22) 95 | rel1.offset: 1 1; 96 | align: 0.0 0.0; 97 | color: 255 255 255 0; 98 | image.normal: "sel_corner1.png"; 99 | } 100 | description { state: "visible" 0.0; 101 | inherit: "default" 0.0; 102 | color: 255 255 255 200; 103 | } 104 | } 105 | part { name: "h2"; type: RECT; 106 | repeat_events: 1; 107 | description { state: "default" 0.0; 108 | color: 255 255 255 0; 109 | rel1 { 110 | to: "h1"; 111 | relative: 1.0 0.0; 112 | offset: 3 2; 113 | } 114 | rel2 { 115 | to: "h3"; 116 | relative: 0.0 1.0; 117 | offset: -4 -2; 118 | } 119 | } 120 | description { state: "visible" 0.0; 121 | inherit: "default" 0.0; 122 | color: 255 255 255 80; 123 | } 124 | } 125 | part { name: "h3"; type: IMAGE; 126 | repeat_events: 1; 127 | description { state: "default" 0.0; 128 | FIXED_SIZE(22, 22) 129 | rel1.offset: 0 1; 130 | rel2.offset: -2 -1; 131 | align: 1.0 0.0; 132 | color: 255 255 255 0; 133 | image.normal: "sel_corner3.png"; 134 | } 135 | description { state: "visible" 0.0; 136 | inherit: "default" 0.0; 137 | color: 255 255 255 200; 138 | } 139 | } 140 | part { name: "h4"; type: RECT; 141 | repeat_events: 1; 142 | description { state: "default" 0.0; 143 | color: 255 255 255 0; 144 | rel1 { 145 | to: "h3"; 146 | relative: 0.0 1.0; 147 | offset: 1 3; 148 | } 149 | rel2 { 150 | to: "h5"; 151 | relative: 1.0 0.0; 152 | offset: -3 -4; 153 | } 154 | } 155 | description { state: "visible" 0.0; 156 | inherit: "default" 0.0; 157 | color: 255 255 255 80; 158 | } 159 | } 160 | part { name: "h5"; type: IMAGE; 161 | repeat_events: 1; 162 | description { state: "default" 0.0; 163 | FIXED_SIZE(22, 22) 164 | rel2.offset: -2 -2; 165 | align: 1.0 1.0; 166 | color: 255 255 255 0; 167 | image.normal: "sel_corner5.png"; 168 | } 169 | description { state: "visible" 0.0; 170 | inherit: "default" 0.0; 171 | color: 255 255 255 200; 172 | } 173 | } 174 | part { name: "h6"; type: RECT; 175 | repeat_events: 1; 176 | description { state: "default" 0.0; 177 | rel1 { 178 | to: "h7"; 179 | relative: 1.0 0.0; 180 | offset: 3 1; 181 | } 182 | rel2 { 183 | to: "h5"; 184 | relative: 0.0 1.0; 185 | offset: -4 -3; 186 | } 187 | color: 255 255 255 0; 188 | } 189 | description { state: "visible" 0.0; 190 | inherit: "default" 0.0; 191 | color: 255 255 255 80; 192 | } 193 | } 194 | part { name: "h7"; type: IMAGE; 195 | repeat_events: 1; 196 | description { state: "default" 0.0; 197 | FIXED_SIZE(22, 22) 198 | rel1.offset: 1 0; 199 | rel2.offset: -1 -2; 200 | align: 0.0 1.0; 201 | color: 255 255 255 0; 202 | image.normal: "sel_corner7.png"; 203 | } 204 | description { state: "visible" 0.0; 205 | inherit: "default" 0.0; 206 | color: 255 255 255 200; 207 | } 208 | } 209 | part { name: "h8"; type: RECT; 210 | repeat_events: 1; 211 | description { state: "default" 0.0; 212 | rel1 { 213 | to: "h1"; 214 | relative: 0.0 1.0; 215 | offset: 2 3; 216 | } 217 | rel2 { 218 | to: "h7"; 219 | relative: 1.0 0.0; 220 | offset: -2 -4; 221 | } 222 | color: 255 255 255 0; 223 | } 224 | description { state: "visible" 0.0; 225 | inherit: "default" 0.0; 226 | color: 255 255 255 80; 227 | } 228 | } 229 | part { name: "hm"; type: RECT; 230 | repeat_events: 1; 231 | description { state: "default" 0.0; 232 | color: 255 255 255 0; 233 | rel1 { 234 | to: "h1"; 235 | relative: 1.0 1.0; 236 | } 237 | rel2 { 238 | to: "h5"; 239 | relative: 0.0 0.0; 240 | } 241 | } 242 | } 243 | 244 | program { name: "show corner selectors"; 245 | signal: "mouse,in"; source: "selector"; 246 | action: STATE_SET "visible" 0.0; 247 | transition: LINEAR 0.3 ; 248 | targets: "h1" "h3" "h5" "h7"; 249 | } 250 | program { name: "hide corner selectors"; 251 | signal: "mouse,out"; source: "selector"; 252 | action: STATE_SET "default" 0.0; 253 | transition: LINEAR 0.3 ; 254 | targets: "h1" "h3" "h5" "h7"; 255 | } 256 | 257 | #define SHOW_HIDE_LATERALS(_NAME_) \ 258 | program { signal: "mouse,in"; source: _NAME_; \ 259 | action: STATE_SET "visible" 0.0; \ 260 | transition: LINEAR 0.3 ; \ 261 | target: _NAME_; } \ 262 | program { signal: "mouse,out"; source: _NAME_; \ 263 | action: STATE_SET "default" 0.0; \ 264 | transition: LINEAR 0.3 ; \ 265 | target: _NAME_; } 266 | SHOW_HIDE_LATERALS("h2") 267 | SHOW_HIDE_LATERALS("h4") 268 | SHOW_HIDE_LATERALS("h6") 269 | SHOW_HIDE_LATERALS("h8") 270 | #undef SHOW_HIDE_LATERALS 271 | } 272 | } 273 | } 274 | 275 | -------------------------------------------------------------------------------- /data/themes/default/elm_slideshow.edc: -------------------------------------------------------------------------------- 1 | group { name: "elm/slideshow/base/eluminance"; 2 | data { 3 | item: transitions "fade fade_fast black_fade horizontal vertical square immediate"; 4 | item: layouts "fullscreen not_fullscreen"; 5 | } 6 | parts { 7 | part { name: "whole"; type: RECT; 8 | description { state: "default" 0.0; 9 | color: 0 0 0 0; 10 | } 11 | description { state: "play" 0.0; 12 | color: 0 0 0 255; 13 | } 14 | } 15 | part { name: "image_1_whole"; type: RECT; 16 | description { state: "default" 0.0; 17 | } 18 | description { state: "fade_prev_next" 0.0; 19 | inherit: "default" 0.0; 20 | color: 255 255 255 0; 21 | } 22 | description { state: "black_fade_prev_next_init" 0.0; 23 | inherit: "default" 0.0; 24 | color: 255 255 255 255; 25 | } 26 | description { state: "black_fade_prev_next" 0.0; 27 | inherit: "default" 0.0; 28 | color: 0 0 0 255; 29 | } 30 | description { state: "horizontal_next_init" 0.0; 31 | inherit: "default" 0.0; 32 | } 33 | description { state: "horizontal_next" 0.0; 34 | inherit: "default" 0.0; 35 | rel1.relative: -1.0 0.0; 36 | rel2.relative: 0.0 1.0; 37 | } 38 | description { state: "horizontal_prev_init" 0.0; 39 | inherit: "default" 0.0; 40 | } 41 | description { state: "horizontal_prev" 0.0; 42 | inherit: "default" 0.0; 43 | rel1.relative: 1.0 0.0; 44 | rel2.relative: 2.0 1.0; 45 | } 46 | description { state: "vertical_next_init" 0.0; 47 | inherit: "default" 0.0; 48 | } 49 | description { state: "vertical_next" 0.0; 50 | inherit: "default" 0.0; 51 | rel1.relative: 0.0 -1.0; 52 | rel2.relative: 1.0 0.0; 53 | } 54 | description { state: "vertical_prev_init" 0.0; 55 | inherit: "default" 0.0; 56 | } 57 | description { state: "vertical_prev" 0.0; 58 | inherit: "default" 0.0; 59 | rel1.relative: 0.0 1.0; 60 | rel2.relative: 1.0 2.0; 61 | } 62 | description { state: "square_prev_next" 0.0; 63 | inherit: "default" 0.0; 64 | color: 255 255 255 0; 65 | } 66 | } 67 | part { name: "image_2_whole"; type: RECT; 68 | description { state: "default" 0.0; 69 | color: 255 255 255 0; 70 | } 71 | description { state: "fade_prev_next" 0.0; 72 | inherit: "default" 0.0; 73 | color: 255 255 255 255; 74 | } 75 | description { state: "black_fade_prev_next_init" 0.0; 76 | inherit: "default" 0.0; 77 | color: 0 0 0 0; 78 | } 79 | description { state: "black_fade_prev_next" 0.0; 80 | inherit: "default" 0.0; 81 | color: 255 255 255 255; 82 | } 83 | description { state: "horizontal_next_init" 0.0; 84 | inherit: "default" 0.0; 85 | rel1.relative: 1.0 0.0; 86 | rel2.relative: 2.0 1.0; 87 | color: 255 255 255 255; 88 | } 89 | description { state: "horizontal_next" 0.0; 90 | inherit: "default" 0.0; 91 | color: 255 255 255 255; 92 | } 93 | description { state: "horizontal_prev_init" 0.0; 94 | inherit: "default" 0.0; 95 | rel1.relative: -1.0 0.0; 96 | rel2.relative: 0.0 1.0; 97 | color: 255 255 255 255; 98 | } 99 | description { state: "horizontal_prev" 0.0; 100 | inherit: "default" 0.0; 101 | color: 255 255 255 255; 102 | } 103 | description { state: "vertical_next_init" 0.0; 104 | inherit: "default" 0.0; 105 | rel1.relative: 0.0 1.0; 106 | rel2.relative: 1.0 2.0; 107 | color: 255 255 255 255; 108 | } 109 | description { state: "vertical_next" 0.0; 110 | inherit: "default" 0.0; 111 | color: 255 255 255 255; 112 | } 113 | description { state: "vertical_prev_init" 0.0; 114 | inherit: "default" 0.0; 115 | rel1.relative: 0.0 -1.0; 116 | rel2.relative: 1.0 0.0; 117 | color: 255 255 255 255; 118 | } 119 | description { state: "vertical_prev" 0.0; 120 | inherit: "default" 0.0; 121 | color: 255 255 255 255; 122 | } 123 | description { state: "square_prev_next_init" 0.0; 124 | inherit: "default" 0.0; 125 | rel1.relative: 0.5 0.5; 126 | rel2.relative: 0.5 0.5; 127 | color: 255 255 255 255; 128 | } 129 | description { state: "square_prev_next" 0.0; 130 | inherit: "default" 0.0; 131 | rel1.relative: 0.0 0.0; 132 | rel2.relative: 1.0 1.0; 133 | color: 255 255 255 255; 134 | } 135 | } 136 | part { name: "elm.swallow.1"; type: SWALLOW; 137 | clip_to: "image_1_whole"; 138 | description { state: "default" 0.0; 139 | rel1.to: "image_1_whole"; 140 | rel2.to: "image_1_whole"; 141 | } 142 | description { state: "not_fullscreen" 0.0; 143 | rel1.relative: 0.1 0.1; 144 | rel1.to: "image_1_whole"; 145 | rel2.relative: 0.9 0.9; 146 | rel2.to: "image_1_whole"; 147 | } 148 | } 149 | part { name: "elm.swallow.2"; type: SWALLOW; 150 | clip_to: "image_2_whole"; 151 | description { 152 | state: "default" 0.0; 153 | rel1.to: "image_2_whole"; 154 | rel2.to: "image_2_whole"; 155 | } 156 | description { state: "not_fullscreen" 0.0; 157 | rel1.relative: 0.1 0.1; 158 | rel1.to: "image_2_whole"; 159 | rel2.relative: 0.9 0.9; 160 | rel2.to: "image_2_whole"; 161 | } 162 | } 163 | part { name: "events_catcher"; type: RECT; repeat_events: 1; 164 | description { state: "default" 0.0; 165 | color: 0 0 0 0; 166 | } 167 | } 168 | } 169 | programs { 170 | program { signal: "elm,layout,fullscreen"; source: "elm"; 171 | action: STATE_SET "default" 0.0; 172 | target: "elm.swallow.1"; 173 | target: "elm.swallow.2"; 174 | transition: SINUSOIDAL 1.0; 175 | } 176 | program { signal: "elm,layout,not_fullscreen"; source: "elm"; 177 | action: STATE_SET "not_fullscreen" 0.0; 178 | target: "elm.swallow.1"; 179 | target: "elm.swallow.2"; 180 | transition: SINUSOIDAL 1.0; 181 | } 182 | // Transition: fade 183 | program { signal: "elm,fade,next"; source: "elm"; 184 | action: STATE_SET "default" 0.0; 185 | target: "image_1_whole"; 186 | target: "image_2_whole"; 187 | after: "fade_next_2"; 188 | } 189 | program { name: "fade_next_2"; 190 | action: STATE_SET "fade_prev_next" 0.0; 191 | target: "image_1_whole"; 192 | target: "image_2_whole"; 193 | transition: SINUSOIDAL 1.5; 194 | after: "end"; 195 | } 196 | program { signal: "elm,fade,previous"; source: "elm"; 197 | action: STATE_SET "default" 0.0; 198 | target: "image_1_whole"; 199 | target: "image_2_whole"; 200 | after: "fade_previous_2"; 201 | } 202 | program { name: "fade_previous_2"; 203 | action: STATE_SET "fade_prev_next" 0.0; 204 | target: "image_1_whole"; 205 | target: "image_2_whole"; 206 | transition: SINUSOIDAL 1.5; 207 | after: "end"; 208 | } 209 | // Transition: fade_fast 210 | program { signal: "elm,fade_fast,next"; source: "elm"; 211 | action: STATE_SET "default" 0.0; 212 | target: "image_1_whole"; 213 | target: "image_2_whole"; 214 | after: "fade_fast_next_2"; 215 | } 216 | program { name: "fade_fast_next_2"; 217 | action: STATE_SET "fade_prev_next" 0.0; 218 | target: "image_1_whole"; 219 | target: "image_2_whole"; 220 | transition: SINUSOIDAL 0.5; 221 | after: "end"; 222 | } 223 | program { signal: "elm,fade_fast,previous"; source: "elm"; 224 | action: STATE_SET "default" 0.0; 225 | target: "image_1_whole"; 226 | target: "image_2_whole"; 227 | after: "fade_fast_previous_2"; 228 | } 229 | program { name: "fade_fast_previous_2"; 230 | action: STATE_SET "fade_prev_next" 0.0; 231 | target: "image_1_whole"; 232 | target: "image_2_whole"; 233 | transition: SINUSOIDAL 0.5; 234 | after: "end"; 235 | } 236 | // Transition: black_fade 237 | program { 238 | signal: "elm,black_fade,next"; source: "elm"; 239 | action: STATE_SET "black_fade_prev_next_init" 0.0; 240 | target: "image_1_whole"; 241 | target: "image_2_whole"; 242 | after: "black_fade_next_2"; 243 | } 244 | program { name: "black_fade_next_2"; 245 | action: STATE_SET "black_fade_prev_next" 0.0; 246 | target: "image_1_whole"; 247 | transition: SINUSOIDAL 0.75; 248 | after: "black_fade_next_3"; 249 | } 250 | program { name: "black_fade_next_3"; 251 | action: STATE_SET "black_fade_prev_next" 0.0; 252 | target: "image_2_whole"; 253 | transition: SINUSOIDAL 0.75; 254 | after: "end"; 255 | } 256 | program { signal: "elm,black_fade,previous"; source: "elm"; 257 | action: STATE_SET "black_fade_prev_next_init" 0.0; 258 | target: "image_1_whole"; 259 | target: "image_2_whole"; 260 | after: "black_fade_previous_2"; 261 | } 262 | program { name: "black_fade_previous_2"; 263 | action: STATE_SET "black_fade_prev_next" 0.0; 264 | target: "image_1_whole"; 265 | transition: SINUSOIDAL 0.75; 266 | after: "black_fade_previous_3"; 267 | } 268 | program { name: "black_fade_previous_3"; 269 | action: STATE_SET "black_fade_prev_next" 0.0; 270 | target: "image_2_whole"; 271 | transition: SINUSOIDAL 0.75; 272 | after: "end"; 273 | } 274 | // Transition: horizontal 275 | program { signal: "elm,horizontal,next"; source: "elm"; 276 | action: STATE_SET "horizontal_next_init" 0.0; 277 | target: "image_1_whole"; 278 | target: "image_2_whole"; 279 | after: "horizontal_next_2"; 280 | } 281 | program { name: "horizontal_next_2"; 282 | action: STATE_SET "horizontal_next" 0.0; 283 | target: "image_1_whole"; 284 | target: "image_2_whole"; 285 | transition: SINUSOIDAL 1.5; 286 | after: "end"; 287 | } 288 | program { name: "horizontal_previous"; 289 | signal: "elm,horizontal,previous"; source: "elm"; 290 | action: STATE_SET "horizontal_prev_init" 0.0; 291 | target: "image_1_whole"; 292 | target: "image_2_whole"; 293 | after: "horizontal_previous_2"; 294 | } 295 | program { name: "horizontal_previous_2"; 296 | action: STATE_SET "horizontal_prev" 0.0; 297 | target: "image_1_whole"; 298 | target: "image_2_whole"; 299 | transition: SINUSOIDAL 1.5; 300 | after: "end"; 301 | } 302 | // Transition: vertical 303 | program { signal: "elm,vertical,next"; source: "elm"; 304 | action: STATE_SET "vertical_next_init" 0.0; 305 | target: "image_1_whole"; 306 | target: "image_2_whole"; 307 | after: "vertical_next_2"; 308 | } 309 | program { name: "vertical_next_2"; 310 | action: STATE_SET "vertical_next" 0.0; 311 | target: "image_1_whole"; 312 | target: "image_2_whole"; 313 | transition: SINUSOIDAL 1.5; 314 | after: "end"; 315 | } 316 | program { signal: "elm,vertical,previous"; source: "elm"; 317 | action: STATE_SET "vertical_prev_init" 0.0; 318 | target: "image_1_whole"; 319 | target: "image_2_whole"; 320 | after: "vertical_previous_2"; 321 | } 322 | program { name: "vertical_previous_2"; 323 | action: STATE_SET "vertical_prev" 0.0; 324 | target: "image_1_whole"; 325 | target: "image_2_whole"; 326 | transition: SINUSOIDAL 1.5; 327 | after: "end"; 328 | } 329 | // Transition: square 330 | program { signal: "elm,square,next"; source: "elm"; 331 | action: STATE_SET "square_prev_next_init" 0.0; 332 | target: "image_2_whole"; 333 | after: "square_next_2"; 334 | } 335 | program { name: "square_next_2"; 336 | action: STATE_SET "square_prev_next" 0.0; 337 | target: "image_2_whole"; 338 | target: "image_1_whole"; 339 | transition: SINUSOIDAL 1.5; 340 | after: "end"; 341 | } 342 | program { signal: "elm,square,previous"; source: "elm"; 343 | action: STATE_SET "square_prev_next_init" 0.0; 344 | target: "image_2_whole"; 345 | after: "square_next_2"; 346 | } 347 | program { signal: "elm,none,next"; source: "elm"; 348 | action: STATE_SET "fade_prev_next" 0.0; 349 | target: "image_1_whole"; 350 | target: "image_2_whole"; 351 | after: "end"; 352 | } 353 | program { signal: "elm,none,previous"; source: "elm"; 354 | action: STATE_SET "fade_prev_next" 0.0; 355 | target: "image_1_whole"; 356 | target: "image_2_whole"; 357 | after: "end"; 358 | } 359 | // Transition: immediate 360 | program { signal: "elm,immediate,next"; source: "elm"; 361 | action: STATE_SET "fade_prev_next" 0.0; 362 | target: "image_1_whole"; 363 | target: "image_2_whole"; 364 | after: "end"; 365 | } 366 | program { signal: "elm,immediate,previous"; source: "elm"; 367 | action: STATE_SET "fade_prev_next" 0.0; 368 | target: "image_1_whole"; 369 | target: "image_2_whole"; 370 | after: "end"; 371 | } 372 | // Anim end 373 | program { name: "end"; 374 | action: SIGNAL_EMIT "elm,end" "elm"; 375 | } 376 | program { signal: "elm,anim,end"; source: "elm"; 377 | action: STATE_SET "default" 0.0; 378 | target: "image_1_whole"; 379 | target: "image_2_whole"; 380 | } 381 | // Custom eluminance play/pause mode 382 | program { signal: "eluminance,play"; source: "eluminance"; 383 | action: STATE_SET "play" 0.0; 384 | transition: LINEAR 1.0; 385 | target: "whole"; 386 | } 387 | program { signal: "eluminance,pause"; source: "eluminance"; 388 | action: STATE_SET "default" 0.0; 389 | transition: LINEAR 1.0; 390 | target: "whole"; 391 | } 392 | } 393 | } 394 | 395 | /////////////////////////////////////////////////////////////////////////////// 396 | -------------------------------------------------------------------------------- /data/themes/default/images/bevel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/bevel.png -------------------------------------------------------------------------------- /data/themes/default/images/bg_fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/bg_fill.png -------------------------------------------------------------------------------- /data/themes/default/images/bg_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/bg_overlay.png -------------------------------------------------------------------------------- /data/themes/default/images/controls_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/controls_bg.png -------------------------------------------------------------------------------- /data/themes/default/images/glint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/glint.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_bookmark_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_bookmark_add.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_bookmark_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_bookmark_remove.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_document_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_document_save.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_document_save_as.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_document_save_as.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_edit_cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_edit_cut.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_go_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_go_next.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_go_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_go_previous.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_info.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_media_playback_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_media_playback_pause.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_media_playback_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_media_playback_start.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_object_flip_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_object_flip_horizontal.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_object_flip_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_object_flip_vertical.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_object_rotate_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_object_rotate_left.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_object_rotate_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_object_rotate_right.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_preferences_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_preferences_system.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_resize.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_rotate.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_starred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_starred.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_view_fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_view_fullscreen.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_zoom.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_zoom_fit_best.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_zoom_fit_best.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_zoom_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_zoom_in.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_zoom_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_zoom_original.png -------------------------------------------------------------------------------- /data/themes/default/images/icon_zoom_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/icon_zoom_out.png -------------------------------------------------------------------------------- /data/themes/default/images/sel_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/sel_border.png -------------------------------------------------------------------------------- /data/themes/default/images/sel_corner1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/sel_corner1.png -------------------------------------------------------------------------------- /data/themes/default/images/sel_corner3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/sel_corner3.png -------------------------------------------------------------------------------- /data/themes/default/images/sel_corner5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/sel_corner5.png -------------------------------------------------------------------------------- /data/themes/default/images/sel_corner7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/sel_corner7.png -------------------------------------------------------------------------------- /data/themes/default/images/status_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/data/themes/default/images/status_bg.png -------------------------------------------------------------------------------- /data/themes/default/main.edc: -------------------------------------------------------------------------------- 1 | 2 | #define DBG_SHOW(_PART, _R, _G, _B) \ 3 | part { name: "dbg_show"_PART; \ 4 | type: RECT; mouse_events: 0; \ 5 | description { state: "default" 0.0; \ 6 | rel1.to: _PART; rel2.to: _PART; \ 7 | color: _R _G _B 50; } } 8 | 9 | #define SHOW(_PART) DBG_SHOW(_PART, 50, 0, 0) 10 | 11 | #define FIXED_SIZE(_W, _H) \ 12 | min: _W _H; max: _W _H; fixed: 1 1; 13 | 14 | 15 | images { 16 | image: "bg_fill.png" COMP; 17 | image: "bg_overlay.png" COMP; 18 | image: "bevel.png" COMP; 19 | image: "glint.png" COMP; 20 | image: "status_bg.png" COMP; 21 | image: "controls_bg.png" COMP; 22 | } 23 | 24 | collections { 25 | 26 | /// MAIN UI //////////////////////////////////////////////////////////////// 27 | group { name: "eluminance/main"; 28 | parts { 29 | //// Background ----------------------------------------------------- 30 | part { name: "bg_fill"; mouse_events: 0; 31 | description { state: "default" 0.0; 32 | fixed: 1 1; 33 | image.normal: "bg_fill.png"; 34 | fill { 35 | size.relative: 0.0 0.0; 36 | size.offset: 64 64; 37 | } 38 | } 39 | part { name: "bg_overlay"; mouse_events: 0; 40 | description { state: "default" 0.0; 41 | fixed: 1 1; 42 | image.normal: "bg_overlay.png"; 43 | fill.smooth: 0; 44 | } 45 | } 46 | } 47 | 48 | //// Photocam ------------------------------------------------------- 49 | part { name: "photo.swallow"; type: SWALLOW; 50 | description { state: "default" 0.0; 51 | } 52 | } 53 | part { name: "photo_events"; type: RECT; 54 | repeat_events: 1; 55 | description { state: "default" 0.0; 56 | color: 0 0 0 0; 57 | } 58 | description { state: "visible" 0.0; // used to implement the toggle 59 | color: 0 0 0 0; 60 | } 61 | } 62 | program { // show tree and grid (permanently) 63 | signal: "mouse,down,3"; source: "photo_events"; 64 | filter: "photo_events" "default"; 65 | action: STATE_SET "visible" 0.0; 66 | transition: DECEL 0.3; 67 | target: "photo_events"; 68 | target: "grid_clip"; 69 | target: "tree_clip"; 70 | } 71 | program { // hide tree and grid 72 | signal: "mouse,down,3"; source: "photo_events"; 73 | filter: "photo_events" "visible"; 74 | action: STATE_SET "default" 0.0; 75 | transition: ACCELERATE 0.3; 76 | target: "photo_events"; 77 | target: "grid_clip"; 78 | target: "tree_clip"; 79 | } 80 | 81 | //// Tree ----------------------------------------------------------- 82 | part { name: "tree_clip"; type: RECT; 83 | description { state: "default" 0.0; 84 | rel2.relative: 0.0 0.0; 85 | rel2.to_y: "status"; 86 | rel2.offset: -1 0; 87 | min: 200 0; 88 | fixed: 1 1; 89 | align: 1.0 0.0; 90 | color: 255 255 255 0; 91 | } 92 | description { state: "visible" 0.0; 93 | inherit: "default" 0.0; 94 | align: 0.0 0.0; 95 | color: 255 255 255 255; 96 | } 97 | } 98 | part { name: "tree.swallow"; type: SWALLOW; 99 | clip_to: "tree_clip"; 100 | description { state: "default" 0.0; 101 | rel1.to: "tree_clip"; 102 | rel2.to: "tree_clip"; 103 | fixed: 1 1; 104 | } 105 | } 106 | part { name: "tree_event"; type: RECT; 107 | repeat_events: 1; 108 | description { state: "default" 0.0; 109 | rel1.to: "tree_clip"; 110 | rel2.to: "tree_clip"; 111 | rel2.offset: 50 -1; 112 | color: 0 0 0 0; 113 | fixed: 1 1; 114 | } 115 | } 116 | program { // show tree and grid 117 | signal: "mouse,in"; source: "tree_event"; 118 | action: STATE_SET "visible" 0.0; 119 | transition: DECEL 0.3 CURRENT; 120 | target: "tree_clip"; 121 | // target: "grid_clip"; 122 | // CURRENT is broken for multiple targets, thus use after here... 123 | after: "show_grid"; 124 | } 125 | program { // hide tree and grid 126 | signal: "mouse,out"; source: "tree_event"; 127 | filter: "photo_events" "default"; // do not hide if fixed 128 | action: STATE_SET "default" 0.0; 129 | transition: ACCEL 0.3 CURRENT; 130 | target: "tree_clip"; 131 | target: "grid_clip"; 132 | } 133 | 134 | //// Grid ---------------------------------------------------------- 135 | part { name: "grid_clip"; type: RECT; 136 | description { state: "default" 0.0; 137 | rel1.relative: 1.0 0.0; 138 | rel2.to_y: "status"; 139 | rel2.relative: 1.0 0.0; 140 | rel2.offset: -1 0; 141 | min: 150 0; 142 | fixed: 1 1; 143 | align: 0.0 0.0; 144 | color: 255 255 255 0; 145 | } 146 | description { state: "visible" 0.0; 147 | inherit: "default" 0.0; 148 | align: 1.0 0.0; 149 | color: 255 255 255 255; 150 | } 151 | } 152 | part { name: "grid.swallow"; type: SWALLOW; 153 | clip_to: "grid_clip"; 154 | description { state: "default" 0.0; 155 | rel1.to: "grid_clip"; 156 | rel2.to: "grid_clip"; 157 | fixed: 1 1; 158 | } 159 | } 160 | part { name: "grid_events"; type: RECT; 161 | repeat_events: 1; 162 | description { state: "default" 0.0; 163 | rel1.to: "grid_clip"; 164 | rel2.to: "grid_clip"; 165 | rel1.offset: -50 0; 166 | color: 0 0 0 0; 167 | fixed: 1 1; 168 | } 169 | } 170 | program { name: "show_grid"; 171 | signal: "mouse,in"; source: "grid_events"; 172 | action: STATE_SET "visible" 0.0; 173 | transition: DECEL 0.3 CURRENT; 174 | target: "grid_clip"; 175 | } 176 | program { name: "hide grid"; 177 | signal: "mouse,out"; source: "grid_events"; 178 | filter: "photo_events" "default"; // do not hide if fixed 179 | action: STATE_SET "default" 0.0; 180 | transition: ACCEL 0.3 CURRENT; 181 | target: "grid_clip"; 182 | } 183 | 184 | //// Controls ------------------------------------------------------- 185 | part { name: "controls_bg"; type: IMAGE; 186 | description { state: "default" 0.0; 187 | rel1.to: "controls.box"; 188 | rel2.to: "controls.box"; 189 | rel1.offset: -13 -10; 190 | rel2.offset: 11 9; 191 | image { 192 | normal: "controls_bg.png"; 193 | border: 15 15 15 15; 194 | } 195 | } 196 | } 197 | part { name: "controls.box"; type: BOX; 198 | description { state: "default" 0.0; 199 | rel1.relative: 0.5 0.0; 200 | rel2.relative: 0.5 0.0; 201 | align: 0.5 1.0; 202 | fixed: 1 1; 203 | box.min: 1 1; 204 | box.layout: "horizontal"; 205 | } 206 | description { state: "visible" 0.0; 207 | inherit: "default" 0.0; 208 | align: 0.5 0.0; 209 | rel1.offset: 0 3; 210 | } 211 | } 212 | part { name: "controls_event"; type: RECT; 213 | repeat_events: 1; 214 | description { state: "default" 0.0; 215 | rel1.relative: 1.0 0.0; 216 | rel2.relative: 0.0 0.0; 217 | rel1.to_x: "tree_clip"; 218 | rel2.to_x: "grid_clip"; 219 | rel1.offset: 0 0; 220 | rel2.offset: 0 35; 221 | color: 0 0 0 0; 222 | } 223 | } 224 | program { name: "show_controls"; 225 | signal: "mouse,in"; source: "controls_event"; 226 | action: STATE_SET "visible" 0.0; 227 | transition: DECEL 0.2; 228 | target: "controls.box"; 229 | after: "show status in play mode"; 230 | } 231 | program { name: "show status in play mode"; 232 | action: SIGNAL_EMIT "status,show" ""; 233 | } 234 | program { name: "hide_controls"; 235 | signal: "mouse,out"; source: "controls_event"; 236 | action: STATE_SET "default" 0.0; 237 | transition: ACCEL 0.2; 238 | target: "controls.box"; 239 | after: "hide status in play mode"; 240 | in: 0.5 0; 241 | } 242 | program { name: "hide status in play mode"; 243 | action: SIGNAL_EMIT "status,hide" ""; 244 | } 245 | program { name: "stop_hiding"; 246 | signal: "mouse,in"; source: "controls_event"; 247 | action: ACTION_STOP; 248 | target: "hide_controls"; 249 | } 250 | 251 | //// Statusbar ----------------------------------------------------- 252 | part { name: "status"; type: IMAGE; 253 | description { state: "default" 0.0; // always visible (pause mode) 254 | rel1.relative: 0.0 1.0; 255 | rel1.offset: 0 -24; 256 | image.normal: "status_bg.png"; 257 | fixed: 1 1; 258 | } 259 | description { state: "hidden" 0.0; // hidden in play mode 260 | inherit: "default" 0.0; 261 | rel1.offset: 0 0; 262 | rel2.offset: 0 24; 263 | } 264 | description { state: "visible" 0.0; // visible in play mode 265 | inherit: "default" 0.0; 266 | } 267 | part { name: "status.swallow"; type: SWALLOW; 268 | description { state: "default" 0.0; 269 | rel1.offset: 3 0; 270 | rel2.offset: -4 -1; 271 | } 272 | } 273 | part { name: "status_bevel"; mouse_events: 0; 274 | description { state: "default" 0.0; 275 | image.normal: "bevel.png"; 276 | image.border: 0 0 1 1; 277 | image.middle: 0; 278 | fill.smooth: 0; 279 | } 280 | } 281 | part { name: "status_glint"; type: IMAGE; 282 | description { state: "default" 0.0; 283 | FIXED_SIZE(79, 5) 284 | rel2.relative: 1.0 0.0; 285 | rel2.offset: -1 0; 286 | image.normal: "glint.png"; 287 | } 288 | } 289 | } 290 | program { signal: "eluminance,play"; source: "eluminance"; 291 | action: STATE_SET "hidden" 0.0; 292 | transition: ACCEL 0.3; 293 | target: "status"; 294 | } 295 | program { signal: "eluminance,pause"; source: "eluminance"; 296 | action: STATE_SET "default" 0.0; 297 | transition: DECEL 0.3; 298 | target: "status"; 299 | } 300 | program { signal: "status,show"; source: ""; 301 | filter: "status" "hidden"; 302 | action: STATE_SET "visible" 0.0; 303 | transition: DECEL 0.3; 304 | target: "status"; 305 | } 306 | program { signal: "status,hide"; source: ""; 307 | filter: "status" "visible"; 308 | action: STATE_SET "hidden" 0.0; 309 | transition: ACCEL 0.3; 310 | target: "status"; 311 | } 312 | } 313 | } 314 | 315 | /// TRANSPARENT SCROLLER (used in the ScrollablePhoto class) /////////////// 316 | group { name: "elm/scroller/base/trans"; 317 | parts { 318 | part { name: "elm.swallow.content"; 319 | type: SWALLOW; 320 | description { state: "default" 0.0; 321 | } 322 | } 323 | } 324 | } 325 | 326 | /// ELM SLIDESHOW ////////////////////////////////////////////////////////// 327 | #include "elm_slideshow.edc" 328 | 329 | /// CROPPER //////////////////////////////////////////////////////////////// 330 | #include "cropper.edc" 331 | 332 | 333 | /// ICONS ////////////////////////////////////////////////////////////////// 334 | #define IC(Name, File) \ 335 | group { name: "elm/icon/"##Name##"/default"; \ 336 | min: 16 16; max: 0 0; \ 337 | images.image: File COMP; \ 338 | parts { part { name: "base"; \ 339 | description { \ 340 | aspect: 1.0 1.0; aspect_preference: BOTH; \ 341 | image.normal: File; } } } } 342 | IC("document-save", "icon_document_save.png") 343 | IC("document-save-as", "icon_document_save_as.png") 344 | IC("edit-cut", "icon_edit_cut.png") 345 | IC("go-next", "icon_go_next.png") 346 | IC("go-previous", "icon_go_previous.png") 347 | IC("media-playback-start", "icon_media_playback_start.png") 348 | IC("media-playback-pause", "icon_media_playback_pause.png") 349 | IC("zoom", "icon_zoom.png") 350 | IC("zoom-in", "icon_zoom_in.png") 351 | IC("zoom-out", "icon_zoom_out.png") 352 | IC("zoom-original", "icon_zoom_original.png") 353 | IC("zoom-fit-best", "icon_zoom_fit_best.png") 354 | IC("rotate", "icon_rotate.png") 355 | IC("resize", "icon_resize.png") 356 | IC("object-rotate-left", "icon_object_rotate_left.png") 357 | IC("object-rotate-right", "icon_object_rotate_right.png") 358 | IC("object-flip-vertical", "icon_object_flip_horizontal.png") 359 | IC("object-flip-horizontal", "icon_object_flip_vertical.png") 360 | IC("preferences-system", "icon_preferences_system.png") 361 | IC("view-fullscreen", "icon_view_fullscreen.png") 362 | IC("info", "icon_info.png") 363 | IC("bookmark-add", "icon_bookmark_add.png") 364 | IC("bookmark-remove", "icon_bookmark_remove.png") 365 | IC("starred", "icon_starred.png") 366 | #undef IC 367 | 368 | } 369 | 370 | -------------------------------------------------------------------------------- /eluminance/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaveMDS/eluminance/fe1bfceeac99fcf5b3f060f961ca0cca544a44f0/eluminance/__init__.py -------------------------------------------------------------------------------- /eluminance/eluminance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | # Copyright (C) 2015-2016 Davide Andreoli 5 | # 6 | # This file is part of Eluminance. 7 | # 8 | # Eluminance is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Lesser General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 3 of the License, or (at your option) any later version. 12 | # 13 | # Eluminance is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with Eluminance. If not, see . 20 | 21 | from __future__ import absolute_import, print_function 22 | 23 | import os 24 | import sys 25 | import pickle 26 | import gettext 27 | from xdg.BaseDirectory import xdg_config_home 28 | 29 | from efl import edje 30 | from efl import elementary as elm 31 | from efl.evas import EXPAND_BOTH, EXPAND_HORIZ, EXPAND_VERT, \ 32 | FILL_BOTH, FILL_HORIZ, FILL_VERT 33 | 34 | import eluminance.utils as utils 35 | 36 | __version__ = '0.9' 37 | 38 | IMG_EXTS = ('.jpg','.jpeg','.png','.gif','.tiff','.bmp') 39 | 40 | script_path = os.path.dirname(os.path.abspath(__file__)) 41 | # Fix for lib64 taken from commit https://github.com/DaveMDS/egitu/commit/c92699b5e66f5d2a0ee02d5f4a5fa60afb3b21fb 42 | install_prefix = script_path[0:script_path.find('/python')] 43 | install_prefix = install_prefix[0:install_prefix.rfind('/')] 44 | data_path = os.path.join(install_prefix, 'share', 'eluminance') 45 | config_file = os.path.join(xdg_config_home, 'eluminance', 'config.pickle') 46 | THEME_FILE = os.path.join(data_path, 'themes', 'default.edj') 47 | 48 | # install the _() and ngettext() functions in the main namespace 49 | locale_dir = os.path.join(install_prefix, 'share', 'locale') 50 | gettext.install('eluminance', names='ngettext', localedir=locale_dir) 51 | 52 | 53 | class Options(object): 54 | """ Class for persistent application settings """ 55 | def __init__(self): 56 | self.sshow_timeout = 5.0 57 | self.sshow_transition = 'fade_fast' 58 | self.sshow_loop = True 59 | self.favorites = [] 60 | 61 | def load(self): 62 | try: 63 | # load only attributes (not methods) from the instance saved to disk 64 | saved = pickle.load(open(config_file, 'rb')) 65 | for attr in dir(self): 66 | if attr[0] != '_' and not callable(getattr(self, attr)): 67 | if hasattr(saved, attr): 68 | setattr(self, attr, getattr(saved, attr)) 69 | except: 70 | pass 71 | 72 | def save(self): 73 | # create config folder if needed 74 | config_path = os.path.dirname(config_file) 75 | if not os.path.exists(config_path): 76 | os.makedirs(config_path) 77 | # save this whole class instance to file 78 | with open(config_file, 'wb') as f: 79 | pickle.dump(self, f, pickle.HIGHEST_PROTOCOL) 80 | 81 | app = None 82 | options = Options() 83 | 84 | 85 | class StdButton(elm.Button): 86 | """ A Button with a standard fdo icon """ 87 | def __init__(self, parent, icon, *args, **kargs): 88 | elm.Button.__init__(self, parent, *args, **kargs) 89 | self.icon = icon 90 | self.show() 91 | 92 | @property 93 | def icon(self): 94 | return self.content 95 | 96 | @icon.setter 97 | def icon(self, name): 98 | self.content = utils.SafeIcon(self, name, size_hint_min=(18,18)) 99 | 100 | 101 | class TreeView(elm.Table): 102 | def __init__(self, parent, select_cb): 103 | self._select_cb = select_cb 104 | 105 | elm.Table.__init__(self, parent, size_hint_expand=EXPAND_BOTH, 106 | size_hint_fill=FILL_BOTH) 107 | 108 | bg = elm.Background(self, size_hint_expand=EXPAND_BOTH, 109 | size_hint_fill=FILL_BOTH) 110 | self.pack(bg, 0, 0, 1, 2) 111 | bg.show() 112 | 113 | self.sc = elm.SegmentControl(self) 114 | it = self.sc.item_add(None, 'Home') # TODO: translate 115 | it.data['path'] = os.path.expanduser('~') 116 | it = self.sc.item_add(None, 'Root') 117 | it.data['path'] = '/' 118 | it = self.sc.item_add(None, 'Favs') 119 | it.data['path'] = 'favs' 120 | self.sc.callback_changed_add(self._segment_changed_cb) 121 | pad = elm.Frame(self, style='pad_small', content=self.sc, 122 | size_hint_expand=EXPAND_HORIZ) 123 | self.pack(pad, 0, 0, 1, 1) 124 | pad.show() 125 | 126 | self.itc = elm.GenlistItemClass('one_icon', 127 | text_get_func=self._gl_text_get, 128 | content_get_func=self._gl_content_get) 129 | self.li = elm.Genlist(self, size_hint_expand=EXPAND_BOTH, 130 | size_hint_fill=FILL_BOTH) 131 | self.li.callback_selected_add(self._item_selected_cb) 132 | self.li.callback_expand_request_add(self._item_expand_request_cb) 133 | self.li.callback_expanded_add(self._item_expanded_cb) 134 | self.li.callback_contract_request_add(self._item_contract_request_cb) 135 | self.li.callback_contracted_add(self._item_contracted_cb) 136 | self.li.callback_clicked_double_add(self._item_expand_request_cb) 137 | self.li.callback_clicked_right_add(self._item_clicked_right_cb) 138 | self.li.callback_longpressed_add(self._item_clicked_right_cb) 139 | self.pack(self.li, 0, 1, 1, 1) 140 | self.li.show() 141 | 142 | def _gl_text_get(self, gl, part, item_data): 143 | if item_data is None: return _('No items to show') 144 | return os.path.basename(item_data) 145 | 146 | def _gl_content_get(self, gl, part, item_data): 147 | if item_data is not None: 148 | icon = 'starred' if item_data in options.favorites else 'folder' 149 | return utils.SafeIcon(gl, icon, resizable=(False,False)) 150 | 151 | def _item_selected_cb(self, gl, item): 152 | self._select_cb(item.data) 153 | 154 | def _item_expand_request_cb(self, gl, item): 155 | item.expanded = True 156 | 157 | def _item_expanded_cb(self, gl, item): 158 | self.populate(item.data, item) 159 | 160 | def _item_contract_request_cb(self, gl, item): 161 | item.expanded = False 162 | 163 | def _item_contracted_cb(self, gl, item): 164 | item.subitems_clear() 165 | 166 | def _item_clicked_right_cb(self, gl, item): 167 | if item.disabled: return 168 | item.selected = True 169 | app.win.freeze() 170 | 171 | pop = elm.Ctxpopup(app.win, direction_priority=( 172 | elm.ELM_CTXPOPUP_DIRECTION_RIGHT, elm.ELM_CTXPOPUP_DIRECTION_DOWN, 173 | elm.ELM_CTXPOPUP_DIRECTION_LEFT, elm.ELM_CTXPOPUP_DIRECTION_UP)) 174 | pop.callback_dismissed_add(self._popup_dismissed_cb) 175 | pop.item_append(_('Set as root'), None, 176 | self._popup_set_root_cb, item.data) 177 | if item.data in options.favorites: 178 | label = _('Remove from favorites') 179 | icon = utils.SafeIcon(pop, 'bookmark-remove') 180 | else: 181 | label = _('Add to favorites') 182 | icon = utils.SafeIcon(pop, 'bookmark-add') 183 | pop.item_append(label, icon, self._popup_toggle_fav_cb, item.data) 184 | 185 | x, y = self.evas.pointer_canvas_xy_get() 186 | pop.move(x, y) 187 | pop.show() 188 | 189 | def _popup_set_root_cb(self, pop, item, path): 190 | self.set_root(path) 191 | pop.dismiss() 192 | 193 | def _popup_toggle_fav_cb(self, pop, item, path): 194 | if path in options.favorites: 195 | options.favorites.remove(path) 196 | else: 197 | options.favorites.append(path) 198 | pop.dismiss() 199 | 200 | def _popup_dismissed_cb(self, pop): 201 | app.win.unfreeze() 202 | pop.delete() 203 | 204 | def _segment_changed_cb(self, sc, item): 205 | self.set_root(item.data['path'], update_sc=False) 206 | 207 | def set_root(self, path, update_sc=True): 208 | if update_sc: 209 | for idx in range(self.sc.item_count): 210 | it = self.sc.item_get(idx) 211 | if it.data['path'] == path: 212 | it.selected = True 213 | return 214 | if self.sc.item_selected is not None: 215 | self.sc.item_selected.selected = False 216 | 217 | self.li.clear() 218 | self.populate(path) 219 | 220 | def populate(self, path, parent=None): 221 | it = None 222 | if path == 'favs': 223 | for path in utils.natural_sort(options.favorites): 224 | it = self.li.item_append(self.itc, path, parent, 225 | flags=elm.ELM_GENLIST_ITEM_TREE) 226 | else: 227 | for f in utils.natural_sort(os.listdir(path)): 228 | if f[0] == '.': continue 229 | fullpath = os.path.join(path, f) 230 | if os.path.isdir(fullpath): 231 | it = self.li.item_append(self.itc, fullpath, parent, 232 | flags=elm.ELM_GENLIST_ITEM_TREE) 233 | if it is None: 234 | it = self.li.item_append(self.itc, None, parent) 235 | it.disabled = True 236 | 237 | def expand_to_folder(self, path): 238 | if os.path.isfile(path): 239 | path = os.path.dirname(path) 240 | it = self.li.first_item 241 | while it: 242 | if it.data == path: 243 | it.expanded = True 244 | it.selected = True 245 | it.show() 246 | return 247 | if path.startswith(it.data + os.path.sep): 248 | it.expanded = True 249 | it = it.subitems_get()[0] 250 | else: 251 | it = it.next 252 | 253 | 254 | class PhotoGrid(elm.Gengrid): 255 | def __init__(self, parent, select_cb): 256 | self._select_cb = select_cb 257 | self.itc = elm.GengridItemClass('default', 258 | text_get_func=self._gg_text_get, 259 | content_get_func=self._gg_content_get) 260 | elm.Gengrid.__init__(self, parent, 261 | item_size=(128, 128), align=(0.5, 0.0), 262 | select_mode=elm.ELM_OBJECT_SELECT_MODE_ALWAYS) 263 | self.callback_selected_add(self._item_selected_cb) 264 | self.drag_item_container_add(0.2, 0.0, 265 | self._drag_item_get, 266 | self._drag_item_data_get) 267 | 268 | def _drag_item_get(self, obj, x, y): 269 | return self.at_xy_item_get(x, y) 270 | 271 | def _drag_item_data_get(self, obj, item, info): 272 | info.format = elm.ELM_SEL_FORMAT_TARGETS 273 | info.createicon = self._drag_create_icon 274 | info.createdata = item 275 | info.dragdone = self._drag_done 276 | info.donecbdata = item 277 | info.data = 'file://' + item.data 278 | return True 279 | 280 | def _drag_create_icon(self, win, xoff, yoff, item): 281 | item.cursor = 'fleur' 282 | ic = elm.Photo(win, file=item.data, aspect_fixed=True, 283 | fill_inside=False, size=100) 284 | mx, my = self.evas.pointer_canvas_xy 285 | return (ic, mx - 60, my - 60) 286 | 287 | def _drag_done(self, obj, accepted, item): 288 | item.cursor = None 289 | 290 | def _gg_content_get(self, gg, part, item_data): 291 | if part == 'elm.swallow.icon': 292 | return elm.Thumb(gg, style='noframe', aspect=elm.ETHUMB_THUMB_CROP, 293 | file=item_data) 294 | 295 | def _gg_text_get(self, gg, part, item_data): 296 | return os.path.basename(item_data) 297 | 298 | def _item_selected_cb(self, gg, item): 299 | self._select_cb(item.data, item.index - 1) 300 | 301 | def photo_add(self, path): 302 | self.item_append(self.itc, path) 303 | 304 | def file_select(self, path): 305 | if self.selected_item and self.selected_item.data == path: 306 | return 307 | it = self.first_item 308 | while it: 309 | if it.data == path: 310 | it.selected = True 311 | it.show() # XXX this is quite annoying if you are browsing the grid 312 | return 313 | it = it.next 314 | 315 | 316 | class ScrollablePhoto(elm.Scroller): 317 | ZOOMS = [5, 7, 10, 15, 20, 30, 50, 75, 100, 150, 200, 300, 318 | 500, 750, 1000, 1500, 2000, 3000, 5000, 7500, 10000] 319 | def __init__(self, parent, zoom_changed_cb): 320 | self._zoom_changed_cb = zoom_changed_cb 321 | self._zoom_mode = None # 'fill' or 'fit' on resize 322 | self.image_size = 0, 0 # original image pixel size 323 | 324 | elm.Scroller.__init__(self, parent, style="trans", 325 | policy=(elm.ELM_SCROLLER_POLICY_OFF, elm.ELM_SCROLLER_POLICY_OFF), 326 | movement_block=elm.ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL | 327 | elm.ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL) 328 | self.on_mouse_wheel_add(self._on_mouse_wheel) 329 | self.on_mouse_down_add(self._on_mouse_down) 330 | self.on_mouse_up_add(self._on_mouse_up) 331 | self.on_resize_add(self._on_resize) 332 | 333 | self.img = elm.Image(self, preload_disabled=False) 334 | self.img.show() 335 | 336 | # table help to keep the image centered in the scroller 337 | tb = elm.Table(self, size_hint_expand=EXPAND_BOTH, 338 | size_hint_fill=FILL_BOTH) 339 | tb.pack(self.img, 0, 0, 1, 1) 340 | self.content = tb 341 | 342 | def file_set(self, file): 343 | self.img.file_set(file) 344 | self.image_size = self.img.object_size 345 | if self.img.animated_available: 346 | self.img.animated = True 347 | self.img.animated_play = True 348 | 349 | def zoom_set(self, val): 350 | self._zoom_mode = None 351 | if val == 'fit' or val == 'fill': 352 | self._zoom_mode = val 353 | self._on_resize(self) 354 | elif val == '1:1': 355 | self.zoom = 100 356 | elif val == 'in': 357 | cur = self.zoom + 1 358 | for z in self.ZOOMS: 359 | if cur < z: break 360 | self.zoom_centered(z) 361 | elif val == 'out': 362 | cur = self.zoom - 1 363 | for z in reversed(self.ZOOMS): 364 | if cur > z: break 365 | self.zoom_centered(z) 366 | 367 | @property 368 | def zoom(self): 369 | return (float(self.img.size[0]) / float(self.image_size[0])) * 100 370 | 371 | @zoom.setter 372 | def zoom(self, val): 373 | z = utils.clamp(self.ZOOMS[0], val, self.ZOOMS[-1]) / 100.0 374 | w, h = self.image_size[0] * z, self.image_size[1] * z 375 | self.img.size_hint_min = w, h 376 | self.img.size_hint_max = w, h 377 | self._zoom_changed_cb(z * 100) 378 | 379 | def zoom_centered(self, val, center_on_mouse=False): 380 | iw, ih = self.img.size 381 | if ih > 0 and ih > 0: 382 | rx, ry, rw, rh = self.region 383 | cx, cy = self.evas.pointer_canvas_xy if center_on_mouse else \ 384 | (rw / 2, rh / 2) 385 | dy, dx = float(cy + ry) / ih, float(cx + rx) / iw 386 | 387 | self.zoom = val 388 | if ih > 0 and ih > 0: 389 | w, h = self.img.size_hint_min 390 | rx, ry = int(w * dx) - cx, int(h * dy) - cy 391 | self.region_show(rx, ry, rw, rh) 392 | 393 | # mouse wheel: zoom 394 | def _on_mouse_wheel(self, obj, event): 395 | self._zoom_mode = None 396 | val = self.zoom * (0.9 if event.z == 1 else 1.1) 397 | self.zoom_centered(val, center_on_mouse=True) 398 | 399 | # mouse drag: pan 400 | def _on_mouse_down(self, obj, event): 401 | if event.button in (1, 2): 402 | self._drag_start_region = obj.region 403 | self._drag_start_x, self._drag_start_y = event.position.canvas 404 | obj.on_mouse_move_add(self._on_mouse_move) 405 | obj.cursor = 'fleur' 406 | 407 | def _on_mouse_up(self, obj, event): 408 | if event.button in (1, 2): 409 | obj.on_mouse_move_del(self._on_mouse_move) 410 | obj.cursor = None 411 | 412 | def _on_mouse_move(self, obj, event): 413 | x, y = event.position.canvas 414 | dx, dy = self._drag_start_x - x, self._drag_start_y - y 415 | x, y, w, h = self._drag_start_region 416 | obj.region_show(x + dx, y + dy, w, h) 417 | 418 | # scroller resize: keep the image fitted or filled 419 | def _on_resize(self, obj): 420 | if self._zoom_mode is not None: 421 | cw, ch = self.region[2], self.region[3] 422 | iw, ih = self.image_size 423 | if cw > 0 and ch > 0 and iw > 0 and ih > 0: 424 | zx, zy = float(cw) / float(iw), float(ch) / float(ih) 425 | z = min(zx, zy) if self._zoom_mode == 'fit' else max(zx, zy) 426 | self.zoom_centered(z * 100) 427 | 428 | 429 | class ScrollablePhotocam(elm.Photocam, elm.Scrollable): 430 | ZOOMS = [0.05, 0.07, 0.1, 0.15, 0.2, 0.3, 0.5, 0.75, 1.0, 1.5, 431 | 2.0, 3.0, 5.0, 7.5, 10, 15, 20, 30, 50, 75, 100] 432 | def __init__(self, parent, changed_cb): 433 | self._changed_cb = changed_cb 434 | elm.Photocam.__init__(self, parent, paused=True, 435 | zoom_mode=elm.ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT) 436 | self.policy = elm.ELM_SCROLLER_POLICY_OFF, elm.ELM_SCROLLER_POLICY_OFF 437 | self.callback_zoom_change_add(self._zoom_change_cb) 438 | self.on_mouse_wheel_add(self._on_mouse_wheel) 439 | self.on_mouse_down_add(self._on_mouse_down) 440 | self.on_mouse_up_add(self._on_mouse_up) 441 | # self.on_del_add(self._on_del) # UNUSED region selector 442 | # self._drag_start_geom = None # UNUSED region selector 443 | # self.sel = None # UNUSED region selector 444 | 445 | def zoom_set(self, val): 446 | if isinstance(val, float): 447 | self.zoom_mode = elm.ELM_PHOTOCAM_ZOOM_MODE_MANUAL 448 | self.zoom = utils.clamp(self.ZOOMS[-1] ** -1, val, self.ZOOMS[0] ** -1) 449 | self._zoom_change_cb(self) 450 | elif val == '1:1': 451 | self.zoom_set(1.0) 452 | elif val == 'fill': 453 | self.zoom_mode = elm.ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL 454 | elif val == 'fit': 455 | self.zoom_mode = elm.ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT 456 | elif val == 'in': 457 | old = self.zoom ** -1 458 | for z in self.ZOOMS: 459 | if old < z: break 460 | self.zoom_set(z ** -1) 461 | elif val == 'out': 462 | old = self.zoom ** -1 463 | for z in reversed(self.ZOOMS): 464 | if old > z: break 465 | self.zoom_set(z ** -1) 466 | 467 | # def _on_del(self, obj): # UNUSED region selector 468 | # if self.sel: self.sel.delete() 469 | 470 | # mouse wheel: zoom 471 | def _on_mouse_wheel(self, obj, event): 472 | new = self.zoom * (1.1 if event.z == 1 else 0.9) 473 | self.zoom_set(new) 474 | 475 | def _zoom_change_cb(self, obj): 476 | self._changed_cb((self.zoom ** -1) * 100) 477 | 478 | # mouse drag: pan 479 | def _on_mouse_down(self, obj, event): 480 | if event.button in (1, 2): 481 | self._drag_start_region = obj.region 482 | self._drag_start_x, self._drag_start_y = event.position.canvas 483 | self.on_mouse_move_add(self._on_mouse_move) 484 | self.cursor = 'fleur' 485 | 486 | def _on_mouse_up(self, obj, event): 487 | if event.button in (1, 2): 488 | self.on_mouse_move_del(self._on_mouse_move) 489 | self.cursor = None 490 | 491 | def _on_mouse_move(self, obj, event): 492 | # if self._drag_start_geom is None: # UNUSED region selector 493 | x, y = event.position.canvas 494 | dx, dy = self._drag_start_x - x, self._drag_start_y - y 495 | x, y, w, h = self._drag_start_region 496 | obj.region_show(x + dx, y + dy, w, h) 497 | 498 | """ UNUSED region selector stuff 499 | def region_selector_show(self): 500 | # from efl.edje import Edje 501 | self.sel = Edje(self.evas, file=THEME_FILE, group='sel') 502 | self.sel.show() 503 | 504 | internal = self.internal_image 505 | internal.on_move_add(self._internal_on_move_resize) 506 | internal.on_resize_add(self._internal_on_move_resize) 507 | self._internal_on_move_resize(internal) 508 | 509 | for part in ('h1','h2','h3','h4','h5','h6','h7','h8','hm'): 510 | h = self.sel.part_object_get(part) 511 | h.on_mouse_down_add(self._on_handler_mouse_down, part) 512 | h.on_mouse_up_add(self._on_handler_mouse_up, part) 513 | 514 | def _internal_on_move_resize(self, obj): 515 | self.sel.geometry = obj.geometry 516 | 517 | def _on_handler_mouse_down(self, obj, event, part): 518 | self._drag_start_x, self._drag_start_y = event.position.canvas 519 | self._drag_start_geom = self.sel.part_object_get('selector').geometry 520 | obj.on_mouse_move_add(self._on_handler_mouse_move, part) 521 | 522 | def _on_handler_mouse_up(self, obj, event, part): 523 | obj.on_mouse_move_del(self._on_handler_mouse_move) 524 | self._drag_start_geom = None 525 | 526 | def _on_handler_mouse_move(self, obj, event, part): 527 | x, y = event.position.canvas 528 | dx, dy = x - self._drag_start_x, y - self._drag_start_y 529 | x, y, w, h = self._drag_start_geom 530 | px, py, pw, ph = self.internal_image.geometry 531 | 532 | # calc new selection gemetry 533 | if part == 'hm': 534 | x, y = x + dx, y + dy 535 | elif part == 'h1': 536 | x, y = x + dx, y + dy 537 | w, h = w - dx, h - dy 538 | elif part == 'h2': 539 | y = y + dy 540 | h = h - dy 541 | elif part == 'h3': 542 | y = y + dy 543 | w, h = w + dx, h - dy 544 | elif part == 'h4': 545 | w = w + dx 546 | elif part == 'h5': 547 | w, h = w + dx, h + dy 548 | elif part == 'h6': 549 | h = h + dy 550 | elif part == 'h7': 551 | x, y = x + dx, y 552 | w, h = w - dx, h + dy 553 | elif part == 'h8': 554 | x = x + dx 555 | w = w - dx 556 | 557 | w, h = max(50, w), max(50, h) 558 | 559 | # calc new relative pos 560 | rel1x = float(x - px) / pw 561 | rel1y = float(y - py) / ph 562 | rel2x = float(x + w - px) / pw 563 | rel2y = float(y + h - py) / ph 564 | 565 | # constrain inside photo geometry 566 | rel1x = utils.clamp(0.0, rel1x, 1.0) 567 | rel1y = utils.clamp(0.0, rel1y, 1.0) 568 | rel2x = utils.clamp(0.0, rel2x, 1.0) 569 | rel2y = utils.clamp(0.0, rel2y, 1.0) 570 | 571 | # send signal to edje with new rels 572 | self.sel.message_send(1, (rel1x, rel1y, rel2x, rel2y)) 573 | """ 574 | 575 | 576 | class StatusBar(elm.Box): 577 | def __init__(self, parent): 578 | elm.Box.__init__(self, parent, horizontal=True, 579 | size_hint_expand=EXPAND_HORIZ, 580 | size_hint_fill=FILL_HORIZ) 581 | 582 | self.lb_name = elm.Label(self, ellipsis=True, 583 | size_hint_expand=EXPAND_HORIZ, size_hint_fill=FILL_HORIZ, 584 | text='{}'.format(_('No image selected'))) 585 | self.pack_end(self.lb_name) 586 | self.lb_name.show() 587 | 588 | self.lb_info = elm.Label(self) 589 | self.pack_end(self.lb_info) 590 | self.lb_info.show() 591 | 592 | # edit button 593 | # bt = StdButton(self, icon='edit') 594 | # bt.callback_clicked_add(lambda b: ImageEditor(self.app)) 595 | # self.pack_end(bt) 596 | # self.btn_edit = bt 597 | 598 | def update(self, img_path, img_num, tot_imgs, img_size, zoom): 599 | self.lb_name.text = '{}: {}'.format( 600 | _('File {0} of {1}').format(img_num, tot_imgs), 601 | os.path.basename(img_path)) 602 | self.lb_info.text = \ 603 | '{}: {}x{} {}: {} {}: {:.0f}%'.format( 604 | _('Resolution'), img_size[0], img_size[1], 605 | _('Size'), utils.file_hum_size(img_path), 606 | _('Zoom'), zoom) 607 | 608 | 609 | class SlideShow(elm.Slideshow): 610 | TRANSITIONS = ('fade', 'fade_fast', 'black_fade', 'horizontal', 'vertical', 611 | 'square', 'immediate') 612 | def __init__(self, parent, photo_changed_cb, zoom_changed_cb): 613 | self._photo_changed_cb = photo_changed_cb 614 | self._zoom_changed_cb = zoom_changed_cb 615 | 616 | self.itc = elm.SlideshowItemClass(self._item_get_func) 617 | elm.Slideshow.__init__(self, parent, style='eluminance', 618 | loop=options.sshow_loop, 619 | transition=options.sshow_transition) 620 | self.callback_changed_add(self._changed_cb) 621 | 622 | buttons = [ # (mode, tooltip, icon, action) 623 | (None, _('Zoom in'), 'zoom-in', 'in'), 624 | (None, _('Zoom out'), 'zoom-out', 'out'), 625 | (None, _('Zoom 1:1'), 'zoom-original', '1:1'), 626 | (None, _('Zoom fit'), 'zoom-fit', 'fit'), 627 | (None, _('Zoom fill'), 'zoom-fill', 'fill'), 628 | ('sep', None, None, None), 629 | (None, _('Previous photo'), 'go-previous', 'prev'), 630 | (None, _('Next photo'), 'go-next', 'next'), 631 | ('toggle', _('Start/Stop slideshow'), None, None), 632 | ('spinner', _('Transition time'), None, None), 633 | ('hover', _('Transition style'), None, None), 634 | ('sep', None, None, None), 635 | (None, _('Toggle fullscreen mode'), 'view-fullscreen', 'fs'), 636 | (None, _('Eluminance info'), 'help-about', 'info'), 637 | ] 638 | 639 | for mode, tooltip, icon, action in buttons: 640 | if mode == 'sep': 641 | w = elm.Separator(self) 642 | # Play/Pause toggle button 643 | elif mode == 'toggle': 644 | w = StdButton(self, icon='media-playback-start', text=_('Play')) 645 | w.callback_clicked_add(self._buttons_cb, 'slideshow') 646 | self.toggle_btn = w 647 | # timeout spinner 648 | elif mode == 'spinner': 649 | w = elm.Spinner(self, label_format="%2.0f secs.", 650 | step=1, min_max=(3, 60), 651 | value=options.sshow_timeout) 652 | w.callback_changed_add(self._spinner_cb) 653 | self.spinner = w 654 | # Transition selector 655 | elif mode == 'hover': 656 | w = elm.Hoversel(self, hover_parent=parent, 657 | text=_(options.sshow_transition)) 658 | w.callback_clicked_add(lambda h: app.win.freeze()) 659 | w.callback_dismissed_add(lambda h: app.win.unfreeze()) 660 | for t in self.TRANSITIONS: 661 | w.item_add(t, None, 0, self._transition_cb, t) 662 | self.hs_transition = w 663 | # normal buttons 664 | else: 665 | w = StdButton(self, icon=icon) 666 | w.callback_clicked_add(self._buttons_cb, action) 667 | 668 | parent.layout.box_append('controls.box', w) 669 | if tooltip: w.tooltip_text_set(tooltip) 670 | w.show() 671 | 672 | def photo_add(self, path): 673 | item_data = (path, self.count + 1) 674 | item = self.item_add(self.itc, item_data) 675 | # XXX the first added item get the changed_cb called before 676 | # python-efl can do the _set_obj, so we get a null item.object in the cb 677 | if self.count == 1 and item.object: 678 | self._photo_changed_cb(path) 679 | 680 | def photo_nth_show(self, index): 681 | self.nth_item_get(index).show() 682 | 683 | def play(self): 684 | self.timeout = options.sshow_timeout 685 | self.toggle_btn.text = _('Pause') 686 | self.toggle_btn.icon = 'media-playback-pause' 687 | self.signal_emit('eluminance,play', 'eluminance') 688 | app.win.layout.signal_emit('eluminance,play', 'eluminance') 689 | 690 | def pause(self): 691 | self.timeout = 0.0 692 | self.toggle_btn.text = _('Play') 693 | self.toggle_btn.icon = 'media-playback-start' 694 | self.signal_emit('eluminance,pause', 'eluminance') 695 | app.win.layout.signal_emit('eluminance,pause', 'eluminance') 696 | 697 | @property 698 | def photo(self): 699 | return self.current_item.object 700 | 701 | @property 702 | def index(self): 703 | path, index = self.current_item.data 704 | return index 705 | 706 | def _item_get_func(self, obj, item_data): 707 | path, index = item_data 708 | # img = ScrollablePhotocam(self, self._zoom_changed_cb) 709 | img = ScrollablePhoto(self, self._zoom_changed_cb) 710 | img.file_set(path) 711 | img.zoom_set('fit') 712 | return img 713 | 714 | def _changed_cb(self, obj, item): 715 | if item.object: # XXX see below note in photo_add() 716 | path, index = item.data 717 | self._photo_changed_cb(path) 718 | 719 | def _buttons_cb(self, bt, action): 720 | if action == 'next': 721 | self.next() 722 | elif action == 'prev': 723 | self.previous() 724 | elif action == 'slideshow': 725 | self.play() if self.timeout == 0 else self.pause() 726 | elif action == 'fs': 727 | app.win.fullscreen = not app.win.fullscreen 728 | elif action == 'info': 729 | InfoWin(app.win) 730 | elif action in ('in', 'out', 'fit', 'fill', '1:1'): 731 | self.photo.zoom_set(action) 732 | 733 | def _spinner_cb(self, spinner): 734 | options.sshow_timeout = spinner.value 735 | if self.timeout != 0: 736 | self.timeout = options.sshow_timeout 737 | 738 | def _transition_cb(self, hoversel, item, transition): 739 | self.transition = options.sshow_transition = transition 740 | self.hs_transition.text = _(transition) 741 | 742 | 743 | class InfoWin(elm.DialogWindow): 744 | def __init__(self, parent): 745 | elm.DialogWindow.__init__(self, parent, 'eluminance-info', 'Eluminance', 746 | autodel=True) 747 | 748 | fr = elm.Frame(self, style='pad_large', size_hint_expand=EXPAND_BOTH, 749 | size_hint_align=FILL_BOTH) 750 | self.resize_object_add(fr) 751 | fr.show() 752 | 753 | hbox = elm.Box(self, horizontal=True, padding=(12,12)) 754 | fr.content = hbox 755 | hbox.show() 756 | 757 | vbox = elm.Box(self, align=(0.0,0.0), padding=(6,6), 758 | size_hint_expand=EXPAND_VERT, size_hint_fill=FILL_VERT) 759 | hbox.pack_end(vbox) 760 | vbox.show() 761 | 762 | # icon + version 763 | ic = utils.SafeIcon(self, 'eluminance', size_hint_min=(64,64)) 764 | vbox.pack_end(ic) 765 | ic.show() 766 | 767 | lb = elm.Label(self, text=_('Version: %s') % __version__) 768 | vbox.pack_end(lb) 769 | lb.show() 770 | 771 | sep = elm.Separator(self, horizontal=True) 772 | vbox.pack_end(sep) 773 | sep.show() 774 | 775 | # buttons 776 | bt = elm.Button(self, text=_('Eluminance'), size_hint_fill=FILL_HORIZ) 777 | bt.callback_clicked_add(lambda b: self.entry.text_set(utils.INFO)) 778 | vbox.pack_end(bt) 779 | bt.show() 780 | 781 | bt = elm.Button(self, text=_('Website'),size_hint_align=FILL_HORIZ) 782 | bt.callback_clicked_add(lambda b: utils.xdg_open(utils.HOMEPAGE)) 783 | vbox.pack_end(bt) 784 | bt.show() 785 | 786 | bt = elm.Button(self, text=_('Authors'), size_hint_align=FILL_HORIZ) 787 | bt.callback_clicked_add(lambda b: self.entry.text_set(utils.AUTHORS)) 788 | vbox.pack_end(bt) 789 | bt.show() 790 | 791 | bt = elm.Button(self, text=_('License'), size_hint_align=FILL_HORIZ) 792 | bt.callback_clicked_add(lambda b: self.entry.text_set(utils.LICENSE)) 793 | vbox.pack_end(bt) 794 | bt.show() 795 | 796 | # main text 797 | self.entry = elm.Entry(self, editable=False, scrollable=True, 798 | text=utils.INFO, size_hint_expand=EXPAND_BOTH, 799 | size_hint_fill=FILL_BOTH) 800 | self.entry.callback_anchor_clicked_add(lambda e,i: utils.xdg_open(i.name)) 801 | hbox.pack_end(self.entry) 802 | self.entry.show() 803 | 804 | self.resize(400, 200) 805 | self.show() 806 | 807 | 808 | class MainWin(elm.StandardWindow): 809 | def __init__(self): 810 | elm.StandardWindow.__init__(self, 'eluminance', 'Eluminance', 811 | autodel=True, size=(800,600), 812 | tree_focus_allow=False) 813 | self.callback_delete_request_add(lambda o: elm.exit()) 814 | 815 | self.layout = elm.Layout(self, file=(THEME_FILE, 'eluminance/main'), 816 | size_hint_expand=EXPAND_BOTH, 817 | tree_focus_allow=False) 818 | self.resize_object_add(self.layout) 819 | self.layout.show() 820 | 821 | def swallow_all(self, app): 822 | self.layout.content_set('photo.swallow', app.sshow) 823 | self.layout.content_set('grid.swallow', app.grid) 824 | self.layout.content_set('tree.swallow', app.tree) 825 | self.layout.content_set('status.swallow', app.status) 826 | 827 | def freeze(self): 828 | self.layout.edje.play_set(False) 829 | 830 | def unfreeze(self): 831 | self.layout.edje.play_set(True) 832 | 833 | 834 | class EluminanceApp(object): 835 | def __init__(self): 836 | self.win = MainWin() 837 | self.sshow = SlideShow(self.win, self.photo_changed, self.zoom_changed) 838 | self.grid = PhotoGrid(self.win, self.grid_selected) 839 | self.tree = TreeView(self.win, self.tree_selected) 840 | self.status = StatusBar(self.win) 841 | self.win.swallow_all(self) 842 | 843 | home = os.path.expanduser('~') 844 | self.current_path = home 845 | self.current_file = None 846 | request = None 847 | 848 | if len(sys.argv) > 1: 849 | request = os.path.abspath(sys.argv[1]) 850 | if not os.path.exists(request): 851 | request = None 852 | 853 | if request: 854 | if request.startswith(home): 855 | self.tree.set_root(home) 856 | else: 857 | self.tree.set_root('/') 858 | self.tree.expand_to_folder(request) 859 | if os.path.isfile(request): 860 | self.grid.file_select(request) 861 | else: 862 | self.tree.set_root(home) 863 | 864 | self.win.show() 865 | 866 | def tree_selected(self, path): 867 | self.current_path = path 868 | self.sshow.clear() 869 | self.grid.clear() 870 | for f in utils.natural_sort(os.listdir(path)): 871 | if os.path.splitext(f)[-1].lower() in IMG_EXTS: 872 | full_path = os.path.join(path, f) 873 | self.grid.photo_add(full_path) 874 | self.sshow.photo_add(full_path) 875 | self.win.title = 'eluminance - ' + self.current_path 876 | 877 | def grid_selected(self, path, index): 878 | self.sshow.photo_nth_show(index) 879 | 880 | def photo_changed(self, path): 881 | self.current_file = path 882 | self.grid.file_select(path) 883 | self.status.update(self.current_file, self.sshow.index, self.sshow.count, 884 | self.sshow.photo.image_size, 0) 885 | 886 | def zoom_changed(self, zoom): 887 | # TODO update only the zoom 888 | self.status.update(self.current_file, self.sshow.index, self.sshow.count, 889 | self.sshow.photo.image_size, zoom) 890 | 891 | 892 | def main(): 893 | options.load() 894 | elm.need_ethumb() 895 | elm.theme_extension_add(THEME_FILE) 896 | 897 | global app 898 | app = EluminanceApp() 899 | elm.run() 900 | options.save() 901 | 902 | if __name__ == '__main__': 903 | sys.exit(main()) 904 | 905 | 906 | """ 907 | class ImageEditor(object): 908 | def __init__(self, app): 909 | self.bg = Background(app.win, size_hint_expand=EXPAND_BOTH) 910 | app.win.resize_object_add(self.bg) 911 | self.bg.show() 912 | 913 | box = elm.Box(self.bg, size_hint_expand=EXPAND_BOTH, 914 | size_hint_fill=FILL_BOTH) 915 | app.win.resize_object_add(box) 916 | box.show() 917 | 918 | tb = elm.Toolbar(app.win, homogeneous=True, menu_parent=app.win, 919 | size_hint_expand=EXPAND_HORIZ, 920 | size_hint_fill=FILL_HORIZ) 921 | 922 | item = tb.item_append('rotate', 'Rotate') 923 | item.menu = True 924 | item.menu.item_add(None, 'Rotate Right', 'object-rotate-right') 925 | item.menu.item_add(None, 'Rotate Left', 'object-rotate-left') 926 | item.menu.item_add(None, 'Mirror', 'object-flip-horizontal') 927 | item.menu.item_add(None, 'Flip', 'object-flip-vertical') 928 | 929 | tb.item_append('edit-cut', 'Crop', self._crop_item_cb) 930 | tb.item_append('resize', 'Resize') 931 | 932 | sep = tb.item_append(None, None) 933 | sep.separator = True 934 | 935 | tb.item_append('document-save', 'Save') 936 | tb.item_append('document-save-as', 'Save as') 937 | tb.item_append('document-close', 'Close', self._close_item_cb) 938 | 939 | box.pack_end(tb) 940 | tb.show() 941 | 942 | self.photo = ScrollablePhotocam(app, box, file=app.photo.file, 943 | size_hint_expand=EXPAND_BOTH, 944 | size_hint_fill=FILL_BOTH) 945 | box.pack_end(self.photo) 946 | self.photo.show() 947 | 948 | def _crop_item_cb(self, tb, item): 949 | self.photo.region_selector_show() 950 | 951 | def _close_item_cb(self, tb, item): 952 | self.bg.delete() 953 | """ 954 | -------------------------------------------------------------------------------- /eluminance/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | # Copyright (C) 2015-2016 Davide Andreoli 5 | # 6 | # This file is part of Eluminance. 7 | # 8 | # Eluminance is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Lesser General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 3 of the License, or (at your option) any later version. 12 | # 13 | # Eluminance is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public License 19 | # along with Eluminance. If not, see . 20 | 21 | from __future__ import absolute_import, print_function, unicode_literals 22 | 23 | import os 24 | import re 25 | from efl.ecore import Exe 26 | from efl.elementary import Icon 27 | 28 | 29 | def xdg_open(url_or_file): 30 | Exe('xdg-open "%s"' % url_or_file) 31 | 32 | def clamp(low, val, high): 33 | if val < low: return low 34 | if val > high: return high 35 | return val 36 | 37 | def file_hum_size(file_path): 38 | bytes = float(os.path.getsize(file_path)) 39 | if bytes >= 1099511627776: 40 | terabytes = bytes / 1099511627776 41 | size = '%.1fT' % terabytes 42 | elif bytes >= 1073741824: 43 | gigabytes = bytes / 1073741824 44 | size = '%.1fG' % gigabytes 45 | elif bytes >= 1048576: 46 | megabytes = bytes / 1048576 47 | size = '%.1fM' % megabytes 48 | elif bytes >= 1024: 49 | kilobytes = bytes / 1024 50 | size = '%.1fK' % kilobytes 51 | else: 52 | size = '%.1fb' % bytes 53 | return size 54 | 55 | def natural_sort(l): 56 | convert = lambda text: int(text) if text.isdigit() else text.lower() 57 | alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] 58 | return sorted(l, key=alphanum_key) 59 | 60 | 61 | class SafeIcon(Icon): 62 | def __init__(self, parent, icon_name, **kargs): 63 | Icon.__init__(self, parent, **kargs) 64 | try: 65 | self.standard = icon_name 66 | except RuntimeWarning: 67 | print("ERROR: Cannot find icon: '%s'" % icon_name) 68 | 69 | 70 | HOMEPAGE = 'https://github.com/davemds/eluminance' 71 | 72 | AUTHORS = """ 73 |
74 | 75 | 76 | Davide Andreoli (davemds)
77 | dave@gurumeditation.it

78 | 79 | Wolfgang Morawetz (wfx)
80 | wolfgang.morawetz@gmail.com

81 | 82 | 83 | """ 84 | 85 | INFO = """ 86 | 87 | Eluminance is a fast photo browser written in python.
88 | 89 | """ 90 | 91 | LICENSE = """ 92 | 93 | 94 | GNU GENERAL PUBLIC LICENSE
95 | Version 3, 29 June 2007

96 |
97 | 98 | This program is free software: you can redistribute it and/or modify 99 | it under the terms of the GNU General Public License as published by 100 | the Free Software Foundation, either version 3 of the License, or 101 | (at your option) any later version.

102 | 103 | This program is distributed in the hope that it will be useful, 104 | but WITHOUT ANY WARRANTY; without even the implied warranty of 105 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 106 | GNU General Public License for more details.

107 | 108 | You should have received a copy of the GNU General Public License 109 | along with this program. If not, see
110 | http://www.gnu.org/licenses/ 111 | 112 | """ 113 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | from distutils.version import StrictVersion 5 | from efl.utils.setup import build_extra, build_edc, build_fdo, build_i18n, uninstall 6 | from efl import __version__ as efl_version 7 | 8 | 9 | MIN_EFL = '1.18' 10 | if StrictVersion(efl_version) < MIN_EFL: 11 | print('Your python-efl version is too old! Found: ' + efl_version) 12 | print('You need at least version ' + MIN_EFL) 13 | exit(1) 14 | 15 | setup( 16 | name = 'eluminance', 17 | version = '0.9', 18 | description = 'Photo browser', 19 | long_description = 'A photo browser written in python-efl', 20 | license = "GNU GPL", 21 | author = 'Dave Andreoli', 22 | author_email = 'dave@gurumeditation.it', 23 | packages = ['eluminance'], 24 | requires = ['efl (>=1.18)', 'xdg'], 25 | provides = ['eluminance'], 26 | scripts = ['bin/eluminance'], 27 | cmdclass={ 28 | 'build': build_extra, 29 | 'build_edc': build_edc, 30 | 'build_fdo': build_fdo, 31 | 'build_i18n': build_i18n, 32 | 'uninstall': uninstall, 33 | }, 34 | command_options={ 35 | 'install': {'record': ('setup.py', 'installed_files.txt')} 36 | }, 37 | ) 38 | 39 | --------------------------------------------------------------------------------