Canvas layout and widget lingering with maxWidth/maxHeight - qooxdoo

In this example, the green block has equal top and bottom layout properties. When the browser window gets resized, the block lingers to the top; that means, top offset remains constant, while bottom offset varies according to maxHeight widget property. (The block would also linger to the left should left layout property and maxWidth widget property be set.)
How do I reverse the behavior, so that the widget lingers to the bottom/right corner?

Add a composite as the root widget, give it a grid layout
add the widget you want to position fixed to the lower left corner of the screen to the composite, with row 1 and column 1
set the flex of row 0 and column 0 to 1
set a fixed height/width for rows 1 and 2 and columns 1 and 2
Width of column 1 and height of row 1 should be the dimensions you want for your widget.
Alternatively, you can play with row/column min/max height/width - see the grid layout API for all possibilities.
Yet another alternative is to use a canvas layout, where widgets stay where you put them, and their position or size is never recalculated automatically, and add a listener to the resize event of the container, in which you manually recompute everything. However, I never found a situation in which qooxdoo's containers and layouts didn't allow me to avoid this.
The demo you link to is a demo for what its name says - minimum and maximum sizes of widgets, not positioning. Controlling positioning in qooxdoo happens via layouts. (To some extent, layouts can also be used to specify rules for sizing, though.)

Related

ScrollViewer's Viewport Height VS Actual Height [duplicate]

This question already has answers here:
WPF DataGrid : CanContentScroll property causing odd behavior
(2 answers)
Closed 9 years ago.
Both are quite general terms but I'm curious to know when these height will be different apart from the case we're using Virtualization?
One more question:
I read on MSDN:
If CanContentScroll is true, the values of the ExtentHeight, ScrollableHeight, ViewportHeight, and VerticalOffset properties are number of items. If CanContentScroll is false, the values of these properties are Device Independent Pixels.
However I'm facing an issue with ViewPort Height: I've 2 listbox in application:
1. Which have Virtualization Enabled and CanContentScroll = True.
2. Which have no virtualization and CanContentScroll = True.
In ListBox 1 while drag-drop Viewport Height comes to 4/5 (Number of elements currently visible). However in ListBox 2 i get Viewport Height equal to Actual Height of Listbox.
Why this difference?
Few more findings:
1. Scrollable Height is number of items not visible in scrollviewer
2. Viewport Height is number of items visible in scrollviewer.
Thus Viewport Height + ScrollableHeight = Extent Height
Can someone please explain what's the difference between two listboxes? I need ViewPort hieght in case of Listbox 1
the ActualHeight is the actual height of the ScrollViewer. The Viewport is what is visible from the ScrollViewers Content. So to answer your question: ViewportHeight differs from ActualHeight if the horizontal Scrollbar is visible by the Height of the Scrollbar.
so, to sum this up:
ActualHeight = ViewportHeight + HorizontalScrollbarHeight
Finally This was the root cause:
Quoting from https://stackoverflow.com/a/3062692/3195477:
You are encountering the differences between physical scrolling and
logical scrolling.
As you have discovered, each has its tradeoffs.
Physical scrolling
Physical scrolling (CanContentScroll=false) just goes by pixels, so:
The viewport always represents exactly the same portion of your scroll
extent, giving you a smooth scrolling experience, and but
The entire contents of the DataGrid must have all templates fully
applied and be measured and arranged to determine the size of the
scrollbar, leading to long delays during loading and high RAM usage,
and It doesn't really scroll items so it doesn't understand
ScrollIntoView very well Logical scrolling
Logical scrolling (CanContentScroll=true) calculates its scroll viewport and extent by items instead of pixels, so:
The viewport may show a different number of items at different times,
meaning the number of items in the viewport as compared to the number
of items in the extent varies, causing the scrollbar length to change,
and
Scrolling moves from one item to the next and never in between,
leading to "jerky" scrolling
but
As long as you're using VirtualizingStackPanel under the hood, it only
needs to apply templates and measure and arrange the items that are
actually visible at the moment, and
ScrollIntoView is much simpler since it just needs to get the right
item index into view
Choosing between them
These are the only two kinds of scrolling provided by WPF. You must
choose between them based on the above tradeoffs. Generally logical
scrolling is best for medium to large datasets, and physical scrolling
is best for small ones.
A trick to speed loading during physical scrolling is to make the
physical scrolling better is to wrap your items in a custom Decorator
that has a fixed size and sets its child's Visibility to Hidden when
it is not visible. This prevents the ApplyTemplate, Measure and
Arrange from occuring on the descendant controls of that item until
you're ready for it to happen.
A trick to make physical scrolling's ScrollIntoView more reliable is
to call it twice: Once immediately and once in a dispatcher callback
of DispatcherPriority.ApplicationIdle.
Making logical scroll scrollbar more stable
If all your items are the same height, the number of items visible in
the viewport at any time will stay the same, causing the scroll thumb
size to stay the same (because the ratio with total number if items
doesn't change).
It is also possible to modify the behavior of the ScrollBar itself so
the thumb is always calculated to be a fixed size. To do this without
any hacky code-behind:
Subclass Track to replace the calculation of Thumb position and size in MeasureOverride with your own
Change the ScrollBar template used for the logical-scrolling ScrollBar to use your subclassed Track instead of the regular
one
Change the ScrollViewer template to explicitly set your custom ScrollBar template on the logical-scrolling ScrollBar
(instead of using the default template)
Change the ListBox template to use explicitly set your custom ScrollViewer template on the ScrollViewer it creates
This means copying a lot of template code fom the built-in WPF
templates, so it is not a very elegant solution. But the alternative
to this is to use hacky code-behind to wait until all the templates
are expanded, then find the ScrollBar and just replace the ScrollBar
template with the one that uses your custom Track. This code saves two
large templates (ListBox, ScrollViewer) at the cost of some very
tricky code.
Using a different Panel would be a much larger amount of work:
VirtualizingStackPanel is the only Panel that virtualizes, and only it
and StackPanel to logical scrolling. Since you are taking advantage of
VirtualizingStackPanel's virtualization abilities you would have to
re-implement all of these plus all IScrollInfo info function plus your
regular Panel functions. I could do something like that but I would
allocate several, perhaps many, days to get it right. I recommend you
not try it.
They can differ from the point of (specified) Height being evaluated to any given time during the (ongoing) rendering process.
From MSDN:
There is a difference between the
properties of Height and Width and
ActualHeight and ActualWidth. For
example, the ActualHeight property is
a calculated value based on other
height inputs and the layout system.
The value is set by the layout system
itself, based on an actual rendering
pass, and may therefore lag slightly
behind the set value of properties,
such as Height, that are the basis of
the input change.
Because ActualHeight
is a calculated value, you should be
aware that there could be multiple or
incremental reported changes to it as
a result of various operations by the
layout system. The layout system may
be calculating required measure space
for child elements, constraints by the
parent element, and so on.

Silverlight: how to use a scroll viewer to wrap a list view without specifying height?

I have a control that has a list that varies in length greatly. This control appears in various places meaning that i cannot calculate its position and desired height easily.
Moreover all I want is for the scrollviewer to simply size itself according to its parent. currently it insists on sizing itself according to the content.
currently when i have a list that exceeds the height of the screen the whole control extends off the bottom and the scrollviewer shows no bar (because it has stretched to the heigth of the contents and so thinks it is not required).
I've not included code as the object graph is fairly deep.
What i am looking for is a set of conditions that would cause the scrollviewer to resize itself according to its content rather than its parent.
I have it working in a similar situation involving grids and datagrids, the unique part of this control is that there is a list containing controls.
Any ideas? I would prefer solutions that don't require use of code behind - but im really not in a position to be choosey.
Here are common reasons that come to mind that would allow a scroll viewer to size to its contents rather than to its "parent":-
It's placed on a Canvas or a StackPanel
It's assigned to a Grid row/column with it's Horizontal or Vertical alignment not set to Stretch and its content size is less than the size of the row or column.
Its ultimately upto the containing panel how it chooses to size a child element so its not really possible to dictate this completely from code inside the child.

Retrieve the entire rectangle of a scrollable window

I'm trying to retrieve the entire rectangle of a scrollable window using the WIN32 API. I thought that GetClientRect would return what I need, but that function appears to return only the current viewport. Is there a specific function call that returns the entire scrollable region as a RECT or must I call GetScrollRange to calculate the region myself?
It doesn't work like that. As far as Windows is concerned, a scrollable window isn't a small viewport onto a larger region whose dimensions you can set or retrieve, it's just a rectangle with a scroll bar control at the edge. It's up to you to determine the appearance of the scroll bar by calculating the portion of the notional region that is visible within the viewport provided by the window, and to paint the window contents accordingly.
It sounds as if that particular window is using virtual scrolling. Even GetScrollRange doesn't necessarily tell you the dimensions, because there's no requirement that a delta of 1 on the scrollbar equals 1 pixel, in fact in many cases it is one record, one row, etc.
Another thing to try is to enumerate all the child windows, and find the minimum and maximum x and y coordinates (don't forget to include the width and height of each child window). Of course this won't help if the content is directly drawn and not a hierarchy of windows.

Silverlight canvas scrollbars

I have read that placing a canvas inside a scrollviewer won't work because the canvas does not report its size. I have been experimenting with different containers (borders, grids, canvases and scrollviewers) and could really do with a simple explanation of how scrollviewers behave within nested containers. e.g. If I have a container hierarchy of UserControl>Grid1>Canvas1>ScrollViewer>Grid2>Canvas2 should scrollbars appear around Grid2 when Canvas2 becomes wider than Canvas1? (or indeed wider than UserControl) If not, how should I organise my containers so I can add loads of uielements to Canvas2 and have scrollbars appear as necessary. (My usercontrol width and height are set to 100%)
Canvas will work with a ScrollViewer if you explicitly give it a size. The problem comes from the fact that if you don't supply a Height and Width for any control it will try and determine it's available area based off it's parent container. A ScrollViewer however has infinite available area.
Take a Grid for example. If I define a Grid that has 2 Star Width columns and 2 Star Height rows. How does the Grid know how wide each of those columns should be? The star says they should be half of the available area, but inside a ScrollViewer the available area is infinity.
What controls are you adding to Canvas2? If you are adding them with fixed positions than the ScrollViewer will expand to house all elements. If you aren't giving them fixed positions than all the controls will stack on top of each other, because that is the arrange behavior of a Canvas

WPF - automatically relocating children when parent resizes

I have a container whose size can change.
I will by dynamically creating instances of a user control and adding them to that container.
the size of the user control is fixed. what I want to do is, fit the most number of user controls in the container.
I think a good approach is to add the children horizontally until there is no more space to add another and then start another row.
Say, each row fits 3 children for a given width of the container. if it is expanded enough, it should automatically fit 4 children in a row.
Is there a container control (StackPanel Grid etc.) that I can use to host these user controls. What properties need to be changed.
On resizing the container, it should relocate the children so that the maximum children ae shown. Scrolling is okay as long as max are shown at any given time.
Is there a container that does this automatically? or should I manually create rows or panels or something and add n children to each - i.e., do it manually?
I think what you need is a WrapPanel.
There's a Panels Overview on the MSDN with a lot more information and links to specific types of Panel including the WrapPanel:
WrapPanel positions child elements in sequential position from left to right, breaking content to the next line at the edge of the containing box. Subsequent ordering happens sequentially from top to bottom or right to left, depending on the value of the Orientation property.
I think a good approach is to add the children horizontally until there is no more space to add another and then start another row.
This is exactly what a WrapPanel does.

Resources