Skip to content

Commit

Permalink
better hybrid scrollers
Browse files Browse the repository at this point in the history
  • Loading branch information
ianharrigan committed May 28, 2024
1 parent af04d45 commit b101c79
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 17 deletions.
4 changes: 3 additions & 1 deletion haxe/ui/backend/AppImpl.hx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class AppImpl extends AppBase {

private override function getToolkitInit():ToolkitOptions {
return {
container: findContainer(Toolkit.backendProperties.getProp("haxe.ui.html5.container", "body"))
container: findContainer(Toolkit.backendProperties.getProp("haxe.ui.html5.container", "body")),
useHybridScrollers: Toolkit.backendProperties.getProp("haxe.ui.html5.scrollers") == "hybrid",
useNativeScrollers: Toolkit.backendProperties.getProp("haxe.ui.html5.scrollers") == "native",
};
}

Expand Down
101 changes: 85 additions & 16 deletions haxe/ui/backend/ComponentImpl.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package haxe.ui.backend;

import haxe.ui.geom.Size;
import haxe.ui.Toolkit;
import haxe.ui.backend.html5.EventMapper;
import haxe.ui.backend.html5.FilterHelper;
Expand Down Expand Up @@ -181,8 +182,12 @@ class ComponentImpl extends ComponentBase {
element.classList.add("haxeui-hide-native-scrollbars");
var scroller = cast(this, IScroller);
element.onscroll = function(e) {
scroller.vscrollPos = element.scrollTop;
scroller.hscrollPos = element.scrollLeft;
if (scroller.vscrollPos != element.scrollTop) {
scroller.vscrollPos = element.scrollTop;
}
if (scroller.hscrollPos != element.scrollLeft) {
scroller.hscrollPos = element.scrollLeft;
}
}
}
element.classList.add("haxeui-component");
Expand All @@ -198,10 +203,7 @@ class ComponentImpl extends ComponentBase {
newElement.classList.add("haxeui-component");

if (Platform.instance.useHybridScrollers && (this is haxe.ui.components.Scroll)) {
var scroller = cast(this, Component).findScroller();
//if (scroller != null) {
newElement.style.position = "sticky";
//}
newElement.style.position = "sticky";
}

if ((this is Image)) {
Expand All @@ -226,6 +228,16 @@ class ComponentImpl extends ComponentBase {
});
}

private override function handleDisabled(disable:Bool) {
if ((Platform.instance.useNativeScrollers || Platform.instance.useHybridScrollers) && this.element != null && (this is IScroller)) {
if (disable) {
this.element.style.overflow = "hidden";
} else {
this.element.style.overflow = "auto";
}
}
}

private function remapEvents() {
if (_eventMap == null) {
return;
Expand All @@ -247,11 +259,6 @@ class ComponentImpl extends ComponentBase {
return;
}

if (Platform.instance.useHybridScrollers && (this is haxe.ui.components.Scroll)) {
top--;
left--;
}

if (left != null) {
element.style.left = HtmlUtils.px(left);
}
Expand All @@ -269,6 +276,17 @@ class ComponentImpl extends ComponentBase {
return;
}

if (Platform.instance.useHybridScrollers) {
var c:Component = cast(this, Component);
var parent:Component = c.parentComponent;
if (parent != null && (parent is IScroller)) {
var size = new Size(width, height);
adjustSizeForHybridScroller(cast parent, size);
width = size.width;
height = size.height;
}
}

var c:Component = cast(this, Component);
var css:CSSStyleDeclaration = element.style;
StyleHelper.apply(this, width, height, style);
Expand All @@ -292,6 +310,32 @@ class ComponentImpl extends ComponentBase {
} else {
child.element.style.marginTop = '';
}

if (Platform.instance.useHybridScrollers && (child is IScroller)) {
adjustMarginsForHybridScroller(cast child);
}
}

if (Platform.instance.useHybridScrollers && (this is IScroller)) {
adjustMarginsForHybridScroller(cast this);
}
}

private function adjustSizeForHybridScroller(scroller:IScroller, size:Size) { // we'll artificially inflate the size of the scrollview contents in the case of
if ((this is haxe.ui.components.Scroll)) { // hybrid scrolls, this is because we are letting the browser handle the scroll size
return; // and it thinks the haxeui scrollbar is "part of" the view (which is is, but shouldnt be included in the max sizes)
}
if (scroller.isScrollableVertically) {
var hscroll = scroller.findHorizontalScrollbar();
if (hscroll != null) {
size.height += hscroll.height;
}
}
if (scroller.isScrollableHorizontally) {
var vscroll = scroller.findVerticalScrollbar();
if (vscroll != null) {
size.width += vscroll.width;
}
}
}

Expand Down Expand Up @@ -325,15 +369,23 @@ class ComponentImpl extends ComponentBase {

if (Platform.instance.useHybridScrollers) {
var use = true;
var scroller:IScroller = null;
if ((parent is IScroller)) {
var scroller = cast(parent, IScroller);
scroller = cast(parent, IScroller);
use = !scroller.virtual;
}
if (use) {
if (value != null && parent != null) {
parent.element.scrollTop = Std.int(value.top);
parent.element.scrollLeft = Std.int(value.left);
if (use && value != null && scroller != null) {
var scrollTop = Math.round(value.top);
var scrollLeft = Math.round(value.left);

if (parent.element.scrollTop != scrollTop) {
parent.element.scrollTop = scrollTop;
}
if (parent.element.scrollLeft != scrollLeft) {
parent.element.scrollLeft = scrollLeft;
}

//adjustMarginsForHybridScroller(scroller);
return;
}
}
Expand All @@ -353,6 +405,23 @@ class ComponentImpl extends ComponentBase {
}
}

private function adjustMarginsForHybridScroller(scroller:IScroller) {
if (this.parentComponent == null || this.parentComponent.style == null) {
return;
}
if (scroller.isScrollableHorizontally && scroller.isScrollableVertically) {
var borderSize = this.parentComponent.style.borderSize;
var hscroll = scroller.findHorizontalScrollbar();
var vscroll = scroller.findVerticalScrollbar();
if (hscroll != null && vscroll != null) {
var marginTop = hscroll.height;
var marginLeft = vscroll.width;
vscroll.element.style.marginTop = HtmlUtils.px(-marginTop);
hscroll.element.style.marginLeft = HtmlUtils.px(-marginLeft);
}
}
}

private override function handleVisibility(show:Bool) {
element.style.display = (show == true) ? "" : "none";
}
Expand Down

0 comments on commit b101c79

Please sign in to comment.