-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scaling area scales VirtualFlow's content AND scrollBars #205
Comments
Hi, I will reply in more length when at a computer, but I would go in the
|
That's a smart idea that would actually fix a different issue in my program relating to this! I'll wait for your longer reply. |
So I prefer breaking things down into composable pieces. Hard-wiring auto-scrollbars into Flowless's Yes, removing the skin shouldn't be too hard, although laborious, and would in the end simplify a bunch of other things. Let's also track this as a separate issue. Once the above two things are done, the only remaining point will be how to create scrollbar-free One option is to decide at construction time and instantiate the correct VirtualFlow. This way would keep things simple in Another way is to have a settable property that would allow to switch the presence of scrollbars after instantiation. This feels more JavaFX, but IMO would unnecessarily complicate the code, since maintaining the content position after replacing the VirtualFlow could be tricky. |
I see why a longer response was necessary ;-) I've opened the other issues. |
That might work for always visible scrollbars. For auto-scrollbars, you get into some issues with "dynamical layout", i.e. when only in the layout process you decide to add or remove children. Only after you find out the width of the content can you decide what scrollbars you need, if any. I figured I needed a hand-rolled solution in VirtualFlow, but feel free to experiment with BorderPane. Anyway, for the scrollbar-free version of VirtualFlow I don't imagine scrollbars almost being there, just turned off, but really nothing scrollbar specific being there. As a side note, I wish JavaFX controls were this way. Look e.g. at ListCell, which IMO is a really bad example of modular design. If you want to put something simple into a |
Ok. Am I correct in understanding you to be saying:
Pros & Cons of Idea 1
Pros & Cons of Idea 2
Besides that, there are a few things you said that I didn't understand. You wrote:
What do you mean by "content position? Are you referring to how far down the document that is displayed via VirtualFlow is scrolled? Also, why and when would the VirtualFlow be replaced? |
Yes. The one with scrollbars would be a wrapper around the one without scrollbars.
This is an option, too. I meant something else: when the property is turned on, the scrollbar-less VirtualFlow would be replaced by a scrollbar-ful VirtualFlow. This also answers your question about when would VirtualFlow be replaced. To elaborate more on your idea
We would probably like to reuse the same code that VirtualFlow with scrollbars already uses |
Ok, that clarifies a lot! So the two ideas are better summarized as:
In regards to the second option, what would happen if the program, for whatever reason, called What if there was an additional wrapper around StyledTextArea that uses the first approach but also includes scroll bars? Then, transformations to the content could be readily applied without losing the display-when-needed scroll bars. |
You can scroll the content even if there are no scrollbars. Scrollbar-free VirtualFlow will have those methods. I presented 2. as an option, but not that I really like it. I'm now starting to think that to achieve the best modularity, StyledTextArea should never include scrollbars, but it should be embeddable in a |
True. I just think that scroll bars appearing better fits the end-user's expectations. Seeing an area that scrolls but doesn't have scroll bars feels a bit weird IMO. I'm also thinking Option 2 isn't the best and that Option 1 would be. |
Embedding it would make more sense. |
We might provide factory methods that return |
I love convenience! Definitely! |
Tasks remaining:
|
Do you have all you need to achieve this now? |
I believe so. Now I can scale the VirtualFlow without the scrollbars getting in the way. At the same time, I can figure out how tall the scroll bar's height is by
|
Looks like VirtualizedScrollPane's layoutChildren doesn't take transformations into account.. // text content (shown below) forces both scroll bars to appear.
String text = "...";
VirtualizedScrollPane<InlineCssTextArea> vsPane = AreaFactory
.embeddedInlineCssTextArea(text);
Scene scene = new Scene(new Pane(vsPane), 1200, 600);
InlineCssTextArea area = vsPane.getContent();
vsPane.setMinWidth(600);
vsPane.setMinHeight(400);
vsPane.addEventFilter(ScrollEvent.ANY, {
area.scaleY *= 1.5
}); I get the following picture :-D |
So, the workaround I came up with was to copy VirtualizedScrollPane exactly and add some code in its |
Not sure if this is not the expected behavior of |
Adding a clip (as seen below) did fix it. My version doesn't always work correctly, but I'm sure it could be better implemented. private final Rectangle clipRect = new Rectangle();
// in the constructor, add
setClip(clipRect);
// within layoutChildren(), rewrite
content.resize(w, h);
clipRect.width = layoutWidth;
clipRect.height = layoutHeight; zooming in (scaling up) made the lower right corner between scrollbars (as both are visible in my example) White. |
Taken from FXMisc/Flowless#14, to scale a StyledTextArea<?, ?> area = // creation code
ScaledVirtualized wrapper = new ScaledVirtualized(area);
VirtualizedScrollPane<ScaledVirtualized> vsPane = new VirtualizedScrollPane(wrapper); The following class (written in Groovy) is an example of such a wrapper: class ScaledVirtualized<V extends Node & Virtualized> extends Region implements Virtualized {
final V content
Scale scale = new Scale(1, 1, 0, 0)
Val<Double> estHeight
Val<Double> estWidth
Var<Double> estScrollY
Var<Double> estScrollX
ScaledVirtualized(V content) {
super()
this.content = content
getChildren().add(content)
getTransforms().add(scale)
estHeight = Val.combine(
content.totalHeightEstimateProperty(),
scale.yProperty(),
{ estHeight, scaleFactor -> estHeight * scaleFactor }
)
estWidth = Val.combine(
content.totalWidthEstimateProperty(),
scale.xProperty(),
{ estWidth, scaleFactor -> estWidth * scaleFactor }
)
estScrollX = Var.mapBidirectional(
content.estimatedScrollXProperty(),
(Function) { double scrollX -> scrollX * scale.x },
(Function) { double scrollX -> scrollX / scale.x }
)
estScrollY = Var.mapBidirectional(
content.estimatedScrollYProperty(),
(Function) { double scrollY -> scrollY * scale.y },
(Function) { double scrollY -> scrollY / scale.y }
)
addEventFilter(ScrollEvent.SCROLL, { ScrollEvent event ->
if (event.controlDown) {
scale.with {
double factor = 0.9
if (event.deltaY > 0) {
y *= factor
x *= factor
} else {
y /= factor
x /= factor
}
}
layoutChildren()
event.consume()
}
})
}
@Override
protected void layoutChildren() {
double width = layoutBounds.width
double height = layoutBounds.height
content.resize(width / scale.x, height/ scale.y)
}
@Override
Var<Double> estimatedScrollXProperty() {
estScrollX
}
@Override
Var<Double> estimatedScrollYProperty() {
estScrollY
}
@Override
Val<Double> totalHeightEstimateProperty() {
estHeight
}
@Override
Val<Double> totalWidthEstimateProperty() {
estWidth
}
}
|
Specifically, I need more direct control to VirtualFlow in the following ways:
Not sure if it'd be better to remove the skin or just change the way that scaling is handled within RichTextFX. However, since it's down that alley, I thought I'd bring it up. You've said before that removing the skin would be tedious. However, it didn't sound hard. What would I need to do in order to remove it?
The text was updated successfully, but these errors were encountered: