From ff1ff98feb61fff9f9e82a159a2013ace7f7679f Mon Sep 17 00:00:00 2001 From: laffra Date: Fri, 16 Feb 2024 09:38:37 +0100 Subject: [PATCH] Use drag for splitpanes --- kitchensink.py | 2 +- ltk/ltk.css | 46 ++++++++++-------------- ltk/widgets.py | 94 +++++++++++++++++++++++++++----------------------- 3 files changed, 70 insertions(+), 72 deletions(-) diff --git a/kitchensink.py b/kitchensink.py index c36150a..e5d1474 100644 --- a/kitchensink.py +++ b/kitchensink.py @@ -50,7 +50,7 @@ def activate_tab(event, ui=None): tabs.activate(ltk.get_url_parameter("tab") or 0) ltk.find(window.document.body).append( - # ltk.Logger().element, + ltk.Logger().element, ltk.Div( tabs.css("margin-bottom", 24) .attr("id", "examples") diff --git a/ltk/ltk.css b/ltk/ltk.css index 3f87a91..d8b26cf 100644 --- a/ltk/ltk.css +++ b/ltk/ltk.css @@ -523,50 +523,40 @@ body { z-index: 1000000; } -.ltk-horizontal-split-pane { +.ltk-horizontal-split-pane, .ltk-horizontal-split-pane-left, .ltk-horizontal-split-pane-right { overflow: hidden; } -.ltk-horizontal-split-pane .ui-resizable-e { - cursor: ew-resize; -} - -.ltk-horizontal-split-pane-left { +.ltk-horizontal-split-pane-left, .ltk-horizontal-split-pane-right { width: 50%; - overflow: hidden; - border: 0px solid #EEE; - border-right-width: 4px; } -.ltk-horizontal-split-pane-left:hover { - border-color: #AAF; +.ltk-horizontal-split-pane-middle { + width: 7px; + background-color: transparent; + z-index: 10000; + cursor: ew-resize; } -.ltk-horizontal-split-pane-right { - overflow: hidden; - width: 50%; +.ltk-horizontal-split-pane-middle:hover { + background-color: #AAF; } -.ltk-vertical-split-pane { +.ltk-vertical-split-pane, .ltk-vertical-split-pane-top, .ltk-vertical-split-pane-bottom { overflow: hidden; } -.ltk-horizontal-split-pane .ui-resizable-s { - cursor: ns-resize; -} - -.ltk-vertical-split-pane-top { +.ltk-vertical-split-pane-top, .ltk-vertical-split-pane-bottom { height: 50%; - overflow: hidden; - border: 0px solid #EEE; - border-bottom-width: 4px; } -.ltk-vertical-split-pane-top:hover { - border-color: #AAF; +.ltk-vertical-split-pane-middle { + height: 7px; + background-color: transparent; + z-index: 10000; + cursor: ns-resize; } -.ltk-vertical-split-pane-bottom { - overflow: hidden; - height: 50%; +.ltk-vertical-split-pane-middle:hover { + background-color: #AAF; } \ No newline at end of file diff --git a/ltk/widgets.py b/ltk/widgets.py index 5b04b74..4d73b94 100644 --- a/ltk/widgets.py +++ b/ltk/widgets.py @@ -682,73 +682,81 @@ class TableData(Text): tag = "td" -class VerticalSplitPane(VBox): - """ Lays out its child widgets vertically with a resize handle in the center """ - classes = [ "ltk-vertical-split-pane", "ltk-vbox" ] +class HorizontalSplitPane(HBox): + """ Lays out its child widgets horizontally with a resize handle in the center """ + classes = [ "ltk-horizontal-split-pane", "ltk-hbox" ] - def resize(self): - self.bottom \ - .height(self.height() - self.top.height() - 4) \ - .trigger("resize") + def resize(self, *args): + position = self.middle.position().left + self.middle.css("left", 0) + self.left.width(position) + self.right.width(self.width() - self.left.width() - self.middle.width()) if self.key: - window.localStorage.setItem(f"vsp-height-{self.key}", self.top.height()) + window.localStorage.setItem(f"hsp-width-{self.key}", self.left.width()) - def __init__(self, top, bottom, key=""): + def __init__(self, left, right, key=""): """ - Places top and bottom on top of each other. + Places left and right next to each other. """ - VBox.__init__( + self.left, self.middle, self.right, self.key = left, Div(), right, key + HBox.__init__( self, - top - .addClass("ltk-vertical-split-pane-top") - .resizable(to_js({"handles": "s"})) - .on("resize", proxy(lambda event, ui: self.resize())), - bottom - .addClass("ltk-vertical-split-pane-bottom") + self.left + .addClass("ltk-horizontal-split-pane-left"), + self.middle + .addClass("ltk-horizontal-split-pane-middle") + .draggable() + .draggable("option", "axis", "x") + .draggable("option", "stop", proxy(self.resize)), + self.right + .addClass("ltk-horizontal-split-pane-right") ) - self.top, self.bottom, self.key = top, bottom, key if key: - schedule(self.load_height, key, 0.2) + schedule(self.load_position, key, 0.2) - def load_height(self): - self.top.height(window.localStorage.getItem(f"vsp-height-{self.key}") or "50%") - self.resize() + def load_position(self): + width = window.localStorage.getItem(f"hsp-width-{self.key}") or self.width() / 2 + self.left.width(width) -class HorizontalSplitPane(HBox): - """ Lays out its child widgets horizontally with a resize handle in the center """ - classes = [ "ltk-horizontal-split-pane", "ltk-hbox" ] +class VerticalSplitPane(VBox): + """ Lays out its child widgets vertically with a resize handle in the center """ + classes = [ "ltk-vertical-split-pane", "ltk-vbox" ] - def resize(self): - self.right \ - .width(self.width() - self.left.width() - 4) \ - .trigger("resize") + def resize(self, *args): + position = self.middle.position().top + self.middle.css("top", 0) + self.top.height(position) + self.bottom.height(self.height() - position - self.middle.height()) if self.key: - window.localStorage.setItem(f"vsp-width-{self.key}", self.left.width()) + window.localStorage.setItem(f"vsp-position-{self.key}", position) - def __init__(self, left, right, key=""): + def __init__(self, top, bottom, key=""): """ - Places left and right next to each other. + Places top and bottom below each other. """ + self.top, self.middle, self.bottom, self.key = top, Div(), bottom, key HBox.__init__( self, - left - .addClass("ltk-horizontal-split-pane-left") - .resizable(to_js({"handles": "e"})) - .on("resize", proxy(lambda event, ui: self.resize())), - right - .addClass("ltk-horizontal-split-pane-right") + self.top + .addClass("ltk-vertical-split-pane-top"), + self.middle + .addClass("ltk-vertical-split-pane-middle") + .draggable() + .draggable("option", "axis", "y") + .draggable("option", "stop", proxy(self.resize)), + self.bottom + .addClass("ltk-vertical-split-pane-bottom") ) - self.left, self.right, self.key = left, right, key if key: - schedule(self.load_width, key, 0.2) + schedule(self.load_position, key, 0.2) - def load_width(self): - self.left.width(window.localStorage.getItem(f"vsp-width-{self.key}") or "50%") + def load_position(self): + position = window.localStorage.getItem(f"vsp-position-{self.key}") or self.height() / 2 + self.middle.css("top", position) self.resize() - class TextArea(Text): """ Wraps an HTML element of type