WIP Controls Added; Improved thumbnail scroll
This commit is contained in:
parent
f54acba4cb
commit
c413e74977
|
@ -8,6 +8,7 @@ from gi.repository import Gtk
|
||||||
# Application imports
|
# Application imports
|
||||||
from .left_box import LeftBox
|
from .left_box import LeftBox
|
||||||
from .right_box import RightBox
|
from .right_box import RightBox
|
||||||
|
from ..widgets.button_controls import ButtonControls
|
||||||
from ..widgets.path_label import PathLabel
|
from ..widgets.path_label import PathLabel
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,11 +30,15 @@ class BaseContainer(Gtk.Box):
|
||||||
...
|
...
|
||||||
|
|
||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
box = Gtk.Box()
|
box = Gtk.Box()
|
||||||
box.set_orientation(Gtk.Orientation.HORIZONTAL)
|
box2 = Gtk.Box()
|
||||||
|
box.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
|
box2.set_orientation(Gtk.Orientation.HORIZONTAL)
|
||||||
|
|
||||||
box.add(LeftBox())
|
box.add(ButtonControls())
|
||||||
box.add(RightBox())
|
box.add(PathLabel())
|
||||||
|
box2.add(LeftBox())
|
||||||
|
box2.add(RightBox())
|
||||||
|
|
||||||
self.add(PathLabel())
|
|
||||||
self.add(box)
|
self.add(box)
|
||||||
|
self.add(box2)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ImageListScroll(Gtk.ScrolledWindow):
|
||||||
self.image_list_widget = None
|
self.image_list_widget = None
|
||||||
self.size = 0
|
self.size = 0
|
||||||
self.start = 0
|
self.start = 0
|
||||||
self.end = 9
|
self.end = settings.get_max_ring_thumbnail_list()
|
||||||
|
|
||||||
self._setup_styling()
|
self._setup_styling()
|
||||||
self._setup_signals()
|
self._setup_signals()
|
||||||
|
@ -29,6 +29,7 @@ class ImageListScroll(Gtk.ScrolledWindow):
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
self.set_vexpand(True)
|
self.set_vexpand(True)
|
||||||
|
self.set_overlay_scrolling(False)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("edge-reached", self._handle_edge_reached)
|
self.connect("edge-reached", self._handle_edge_reached)
|
||||||
|
@ -46,25 +47,34 @@ class ImageListScroll(Gtk.ScrolledWindow):
|
||||||
def _update_list_size_constraints(self, size):
|
def _update_list_size_constraints(self, size):
|
||||||
self.size = size
|
self.size = size
|
||||||
self.start = 0
|
self.start = 0
|
||||||
self.end = 9
|
self.end = settings.get_max_ring_thumbnail_list()
|
||||||
|
|
||||||
def _handle_edge_reached(self, widget, edge):
|
def _handle_edge_reached(self, widget, edge):
|
||||||
img_list = widget.get_children()[0].get_children()[0]
|
children = self.image_list_widget.get_children()
|
||||||
children = self.image_list_widget.get_children()
|
vadjustment = self.get_vadjustment()
|
||||||
|
vvalue = vadjustment.get_value()
|
||||||
|
|
||||||
if edge == Gtk.PositionType.TOP:
|
if edge == Gtk.PositionType.TOP:
|
||||||
if self.start >= 1:
|
if self.start >= 1:
|
||||||
self.start -= 1
|
self.start -= 1
|
||||||
children[self.end].hide()
|
self._unload_image(children[self.end])
|
||||||
children[self.start].show()
|
children[self.start].show()
|
||||||
self.end -= 1
|
self.end -= 1
|
||||||
|
|
||||||
|
vadjustment.set_value(vvalue + 1)
|
||||||
if edge == Gtk.PositionType.BOTTOM:
|
if edge == Gtk.PositionType.BOTTOM:
|
||||||
if (self.end + 1) < self.size:
|
if (self.end + 1) < self.size:
|
||||||
self.end += 1
|
self.end += 1
|
||||||
children[self.start].hide()
|
self._unload_image(children[self.start])
|
||||||
|
|
||||||
if not children[self.end].is_loaded:
|
if not children[self.end].is_loaded:
|
||||||
children[self.end].load_pixbuf()
|
children[self.end].load_pixbuf()
|
||||||
|
|
||||||
children[self.end].show()
|
children[self.end].show()
|
||||||
self.start += 1
|
self.start += 1
|
||||||
|
vadjustment.set_value(vvalue - 1)
|
||||||
|
|
||||||
|
def _unload_image(self, child):
|
||||||
|
child.hide()
|
||||||
|
# child.image.clear()
|
||||||
|
child.is_loaded = False
|
||||||
|
|
|
@ -23,7 +23,7 @@ class LeftBox(Gtk.Box):
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
self.set_orientation(Gtk.Orientation.VERTICAL)
|
self.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
self.set_size_request(settings.get_thumbnail_with(), -1)
|
self.set_size_request(settings.get_thumbnail_with() + 15, -1)
|
||||||
self.set_vexpand(True)
|
self.set_vexpand(True)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ButtonControls(Gtk.ButtonBox):
|
||||||
|
def __init__(self):
|
||||||
|
super(ButtonControls, self).__init__()
|
||||||
|
|
||||||
|
self._setup_styling()
|
||||||
|
self._setup_signals()
|
||||||
|
self._load_widgets()
|
||||||
|
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_styling(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
def _setup_signals(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
def _load_widgets(self):
|
||||||
|
center_widget = Gtk.ButtonBox()
|
||||||
|
lrotate_button = Gtk.Button(label = "Rotate Left")
|
||||||
|
vflip_button = Gtk.Button(label = "Flip Vertical")
|
||||||
|
one2one_button = Gtk.ToggleButton(label = "1:1")
|
||||||
|
fit_button = Gtk.ToggleButton(label = "Fit")
|
||||||
|
hflip_button = Gtk.Button(label = "Flip Horizontal")
|
||||||
|
rrotate_button = Gtk.Button(label = "Rotate Right")
|
||||||
|
|
||||||
|
center_widget.add(lrotate_button)
|
||||||
|
center_widget.add(vflip_button)
|
||||||
|
center_widget.add(one2one_button)
|
||||||
|
center_widget.add(fit_button)
|
||||||
|
center_widget.add(hflip_button)
|
||||||
|
center_widget.add(rrotate_button)
|
||||||
|
|
||||||
|
lrotate_button.set_image( Gtk.Image.new_from_icon_name("gtk-undelete", 4) )
|
||||||
|
vflip_button.set_image( Gtk.Image.new_from_icon_name("gtk-orientation-reverse-portrait", 4) )
|
||||||
|
one2one_button.set_image( Gtk.Image.new_from_icon_name("gtk-zoom-100", 4) )
|
||||||
|
fit_button.set_image( Gtk.Image.new_from_icon_name("gtk-zoom-fit", 4) )
|
||||||
|
hflip_button.set_image( Gtk.Image.new_from_icon_name("gtk-orientation-reverse-landscape", 4) )
|
||||||
|
rrotate_button.set_image( Gtk.Image.new_from_icon_name("object-rotate-right", 4) )
|
||||||
|
|
||||||
|
# TODO: add if check against settings pull to set 1:1 or fit
|
||||||
|
one2one_button.set_active(True)
|
||||||
|
|
||||||
|
lrotate_button.connect("clicked", self._rotate_left)
|
||||||
|
vflip_button.connect("clicked", self._vertical_flip)
|
||||||
|
one2one_button.connect("clicked", self._scale_1_two_1)
|
||||||
|
fit_button.connect("clicked", self._fit_to_container)
|
||||||
|
hflip_button.connect("clicked", self._horizontal_flip)
|
||||||
|
rrotate_button.connect("clicked", self._rotate_right)
|
||||||
|
|
||||||
|
self.set_center_widget(center_widget)
|
||||||
|
|
||||||
|
def _rotate_left(self, widget = None, eve = None):
|
||||||
|
event_system.emit("rotate_left")
|
||||||
|
def _vertical_flip(self, widget = None, eve = None):
|
||||||
|
event_system.emit("vertical_flip")
|
||||||
|
def _scale_1_two_1(self, widget = None, eve = None):
|
||||||
|
event_system.emit("scale_1_two_1")
|
||||||
|
def _fit_to_container(self, widget = None, eve = None):
|
||||||
|
event_system.emit("fit_to_container")
|
||||||
|
def _horizontal_flip(self, widget = None, eve = None):
|
||||||
|
event_system.emit("horizontal_flip")
|
||||||
|
def _rotate_right(self, widget = None, eve = None):
|
||||||
|
event_system.emit("rotate_right")
|
|
@ -46,9 +46,6 @@ class Image(Gtk.EventBox):
|
||||||
self.image.show()
|
self.image.show()
|
||||||
self.add(self.image)
|
self.add(self.image)
|
||||||
|
|
||||||
def set_from_pixbuf(self, pixbuf):
|
|
||||||
self.image.set_from_pixbuf(pixbuf)
|
|
||||||
|
|
||||||
def set_image_to_view(self, widget = None, eve = None):
|
def set_image_to_view(self, widget = None, eve = None):
|
||||||
if eve.button == 1:
|
if eve.button == 1:
|
||||||
event_system.emit("handle_file_from_dnd", (self.path, ))
|
event_system.emit("handle_file_from_dnd", (self.path, ))
|
||||||
|
@ -59,6 +56,9 @@ class Image(Gtk.EventBox):
|
||||||
self._thumbnail_height) )
|
self._thumbnail_height) )
|
||||||
self.is_loaded = True
|
self.is_loaded = True
|
||||||
|
|
||||||
|
def set_from_pixbuf(self, pixbuf):
|
||||||
|
self.image.set_from_pixbuf(pixbuf)
|
||||||
|
|
||||||
def get_pixbuf_data(self, path, w = 126, h = 126):
|
def get_pixbuf_data(self, path, w = 126, h = 126):
|
||||||
path = self.path if not path else path
|
path = self.path if not path else path
|
||||||
pixbuf = None
|
pixbuf = None
|
||||||
|
|
|
@ -5,6 +5,7 @@ import os
|
||||||
import gi
|
import gi
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import GLib
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.image import Image
|
from ..widgets.image import Image
|
||||||
|
@ -67,17 +68,18 @@ class ImageList(Gtk.Box):
|
||||||
self.show_range()
|
self.show_range()
|
||||||
|
|
||||||
# TODO: Setup to load range start/end values from settings
|
# TODO: Setup to load range start/end values from settings
|
||||||
def show_range(self, i = 0, j = 9):
|
def show_range(self, i = 0, j = settings.get_max_ring_thumbnail_list()):
|
||||||
children = self.get_children()
|
children = self.get_children()
|
||||||
if len(children) <= j:
|
if len(children) <= j:
|
||||||
j = len(children) - 1
|
j = len(children) - 1
|
||||||
|
|
||||||
while i <= j:
|
while i <= j:
|
||||||
child = children[i]
|
child = children[i]
|
||||||
self.load_pixbuf_threaded(child)
|
self.load_child_pixbuf_threaded(child)
|
||||||
child.show()
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
@daemon_threaded
|
@daemon_threaded
|
||||||
def load_pixbuf_threaded(self, child):
|
def load_child_pixbuf_threaded(self, child):
|
||||||
child.load_pixbuf()
|
GLib.idle_add(child.load_pixbuf)
|
||||||
|
GLib.idle_add(child.show)
|
||||||
|
Gtk.main_iteration()
|
||||||
|
|
|
@ -6,6 +6,7 @@ gi.require_version('Gtk', '3.0')
|
||||||
gi.require_version('Gdk', '3.0')
|
gi.require_version('Gdk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
|
from gi.repository import GdkPixbuf
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
|
||||||
|
@ -15,8 +16,9 @@ class ImageView(Gtk.Image):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(ImageView, self).__init__()
|
super(ImageView, self).__init__()
|
||||||
|
|
||||||
self.pixbuf = None
|
self.bak_pixbuf = None
|
||||||
self.animation = None
|
self.pixbuf = None
|
||||||
|
self.animation = None
|
||||||
|
|
||||||
self._setup_styling()
|
self._setup_styling()
|
||||||
self._setup_signals()
|
self._setup_signals()
|
||||||
|
@ -35,6 +37,12 @@ class ImageView(Gtk.Image):
|
||||||
|
|
||||||
def _subscribe_to_events(self):
|
def _subscribe_to_events(self):
|
||||||
event_system.subscribe("handle_file_from_dnd", self._handle_file_from_dnd)
|
event_system.subscribe("handle_file_from_dnd", self._handle_file_from_dnd)
|
||||||
|
event_system.subscribe("vertical_flip", self._vertical_flip)
|
||||||
|
event_system.subscribe("rotate_left", self._rotate_left)
|
||||||
|
event_system.subscribe("scale_1_two_1", self._scale_1_two_1)
|
||||||
|
event_system.subscribe("fit_to_container", self._fit_to_container)
|
||||||
|
event_system.subscribe("horizontal_flip", self._horizontal_flip)
|
||||||
|
event_system.subscribe("rotate_right", self._rotate_right)
|
||||||
|
|
||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
...
|
...
|
||||||
|
@ -47,8 +55,9 @@ class ImageView(Gtk.Image):
|
||||||
logger.debug("Start animation stub...")
|
logger.debug("Start animation stub...")
|
||||||
|
|
||||||
def load_path(self, path):
|
def load_path(self, path):
|
||||||
self.pixbuf = None
|
self.bak_pixbuf = None
|
||||||
self.animation = None
|
self.pixbuf = None
|
||||||
|
self.animation = None
|
||||||
|
|
||||||
if path.endswith(".gif"):
|
if path.endswith(".gif"):
|
||||||
try:
|
try:
|
||||||
|
@ -63,5 +72,36 @@ class ImageView(Gtk.Image):
|
||||||
except Exception:
|
except Exception:
|
||||||
self.pixbuf = Gtk.Image.new_from_resource(path).get_pixbuf()
|
self.pixbuf = Gtk.Image.new_from_resource(path).get_pixbuf()
|
||||||
|
|
||||||
|
self.bak_pixbuf = self.pixbuf
|
||||||
self.set_from_pixbuf(self.pixbuf)
|
self.set_from_pixbuf(self.pixbuf)
|
||||||
event_system.emit("update_path_label", (path,))
|
event_system.emit("update_path_label", (path,))
|
||||||
|
|
||||||
|
def _rotate_left(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
self.pixbuf = self.pixbuf.rotate_simple(GdkPixbuf.PixbufRotation.COUNTERCLOCKWISE)
|
||||||
|
self.set_from_pixbuf(self.pixbuf)
|
||||||
|
|
||||||
|
def _vertical_flip(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
self.pixbuf = self.pixbuf.flip(False)
|
||||||
|
self.set_from_pixbuf(self.pixbuf)
|
||||||
|
|
||||||
|
def _scale_1_two_1(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
...
|
||||||
|
...
|
||||||
|
|
||||||
|
def _fit_to_container(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
...
|
||||||
|
...
|
||||||
|
|
||||||
|
def _horizontal_flip(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
self.pixbuf = self.pixbuf.flip(True)
|
||||||
|
self.set_from_pixbuf(self.pixbuf)
|
||||||
|
|
||||||
|
def _rotate_right(self):
|
||||||
|
if self.pixbuf:
|
||||||
|
self.pixbuf = self.pixbuf.rotate_simple(GdkPixbuf.PixbufRotation.CLOCKWISE)
|
||||||
|
self.set_from_pixbuf(self.pixbuf)
|
||||||
|
|
|
@ -145,6 +145,7 @@ class Settings(StartCheckMixin, Singleton):
|
||||||
|
|
||||||
def get_thumbnail_with(self) -> int: return self._config["thumbnail_with"]
|
def get_thumbnail_with(self) -> int: return self._config["thumbnail_with"]
|
||||||
def get_thumbnail_height(self) -> int: return self._config["thumbnail_height"]
|
def get_thumbnail_height(self) -> int: return self._config["thumbnail_height"]
|
||||||
|
def get_max_ring_thumbnail_list(self) -> int: return self._config["max_ring_thumbnail_list"]
|
||||||
|
|
||||||
# Filter returns
|
# Filter returns
|
||||||
def get_office_filter(self) -> tuple: return tuple(self._settings["filters"]["office"])
|
def get_office_filter(self) -> tuple: return tuple(self._settings["filters"]["office"])
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"text_app": "leafpad",
|
"text_app": "leafpad",
|
||||||
"file_manager_app": "solarfm",
|
"file_manager_app": "solarfm",
|
||||||
"terminal_app": "terminator",
|
"terminal_app": "terminator",
|
||||||
|
"max_ring_thumbnail_list": 10,
|
||||||
"thumbnail_with": 256,
|
"thumbnail_with": 256,
|
||||||
"thumbnail_height": 256
|
"thumbnail_height": 256
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
/* Set fm to have transparent window */
|
.image-view {
|
||||||
box,
|
/* background-color: rgba(0, 0, 0, 0.0); */
|
||||||
iconview,
|
|
||||||
notebook,
|
|
||||||
paned,
|
|
||||||
stack,
|
|
||||||
scrolledwindow,
|
|
||||||
treeview.view,
|
|
||||||
.content-view,
|
|
||||||
.view {
|
|
||||||
background: rgba(19, 21, 25, 0.14);
|
|
||||||
color: rgba(255, 255, 255, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
notebook > header > tabs > tab:checked {
|
|
||||||
/* Neon Blue 00e8ff */
|
|
||||||
background-color: rgba(0, 232, 255, 0.2);
|
|
||||||
/* Dark Bergundy */
|
/* Dark Bergundy */
|
||||||
/* background-color: rgba(116, 0, 0, 0.25); */
|
border: 2px solid rgba(56, 56, 56, 1);
|
||||||
|
|
||||||
color: rgba(255, 255, 255, 0.8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#message_view {
|
|
||||||
font: 16px "Monospace";
|
|
||||||
}
|
|
||||||
|
|
||||||
.view:selected,
|
|
||||||
.view:selected:hover {
|
|
||||||
box-shadow: inset 0 0 0 9999px rgba(21, 158, 167, 0.34);
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-border {
|
|
||||||
border: 2px solid rgba(116, 0, 0, 0.64);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-border {
|
|
||||||
border: 2px solid rgba(136, 204, 39, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.notebook-selected-focus {
|
|
||||||
/* Neon Blue 00e8ff border */
|
|
||||||
border: 2px solid rgba(0, 232, 255, 0.34);
|
|
||||||
/* Dark Bergundy */
|
|
||||||
/* border: 2px solid rgba(116, 0, 0, 0.64); */
|
|
||||||
}
|
|
||||||
|
|
||||||
.notebook-unselected-focus {
|
|
||||||
/* Neon Blue 00e8ff border */
|
|
||||||
/* border: 2px solid rgba(0, 232, 255, 0.25); */
|
|
||||||
/* Dark Bergundy */
|
|
||||||
/* border: 2px solid rgba(116, 0, 0, 0.64); */
|
|
||||||
/* Snow White */
|
|
||||||
border: 2px solid rgba(255, 255, 255, 0.24);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* * {
|
|
||||||
background: rgba(0, 0, 0, 0.14);
|
|
||||||
color: rgba(255, 255, 255, 1);
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* * selection {
|
|
||||||
background-color: rgba(116, 0, 0, 0.65);
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
} */
|
|
||||||
|
|
||||||
/* Rubberband coloring */
|
|
||||||
/* .rubberband,
|
|
||||||
rubberband,
|
|
||||||
flowbox rubberband,
|
|
||||||
treeview.view rubberband,
|
|
||||||
.content-view rubberband,
|
|
||||||
.content-view .rubberband,
|
|
||||||
XfdesktopIconView.view .rubberband {
|
|
||||||
border: 1px solid #6c6c6c;
|
|
||||||
background-color: rgba(21, 158, 167, 0.57);
|
|
||||||
}
|
|
||||||
|
|
||||||
XfdesktopIconView.view:active {
|
|
||||||
background-color: rgba(172, 102, 21, 1);
|
|
||||||
} */
|
|
||||||
|
|
Loading…
Reference in New Issue