Min-Max limits for component width/height #1360

Open
vaadin-bot opened this Issue Dec 12, 2010 · 21 comments

Projects

None yet

4 participants

@vaadin-bot
Collaborator

Originally by @jojule


For more flexible automatic layouts min-max sizing is sometimes needed. See http://cappuccino.org/learn/tutorials/automatic-layout/ for a nice example implemented by a competitor.

We should create LimitedSizeable interface extends Sizeable that includes:

  • float getMinWidth()
  • setMinWidth(String)
  • setMinWidth(float, int unit)
  • int getMinWidthUnits()
  • setMinWidthUnits(int unit)
  • float getMinHeight()
  • setMinHeight(String)
  • setMinHeight(float, int unit)
  • int getMinHeightUnits()
  • setMinHeightUnits(int unit)
  • float getMaxWidth()
  • setMaxWidth(String)
  • setMaxWidth(float, int unit)
  • int getMaxWidthUnits()
  • setMaxWidthUnits(int unit)
  • float getMaxHeight()
  • setMaxHeight(String)
  • setMaxHeight(float, int unit)
  • int getMaxHeightUnits()
  • setMaxHeightUnits(int unit)

LimitedSizeable interface should be implemented by all classes that implement Sizeable today.

Collaborator

Originally by @jouni


Why limit the API to pixels only and not allow other fixed units, like centimeters?

Collaborator

Originally by @jojule


Good point, but is there a use-case? Different units make sense for size, but are they really useful for flexible size limits? I am not that sure about it.

On the other hand - supporting different units could complicate the API quite a bit.

Collaborator

Originally by @jouni


Replying to Lehtinen:

but is there a use-case?
The trickiest question ever. Of course someone will come up with a use case, and even if it wouldn't sound logical to us, it might be very important for them. Using ems would be the most simple example: I want to present at minimum three rows of text, but no more than 20, and otherwise have 100% height. And approximating the height using pixels will not suffice because of the varying font size.
On the other hand - supporting different units could complicate the API quite a bit.
I suppose it would be just as complex as supporting different size units currently. The API would be asymmetrical if we wouldn't support all the same units as currently, which IMO would make the API worse.

Collaborator

Originally by @jojule


True enough and the em usecase is relevant.

Still - I do not see how to get the API to get even somewhat compact.

Proposals?

Collaborator

Originally by @Artur-


The way layouting is specified it has to be implemented in the layouts and not in the components. The main reason being that the parent (layout) is the one controlling the layout and has the power to decide what 100% means. The child component then must adhere to that. Otherwise we need to redefine at least how expansion works.

The question then becomes is this a feature of every component or is this a layout feature? From a code perspective it is definitely a layout feature and the API should be provided in the layout, like alignment and expand ratio. Simply adding the API to every component and noting that it only works with certain layouts does not sound very good.

If the API is added to a layout it could be:
layout.setComponentMinWidth("100px")
layout.setComponentMinWidth(100,Units.PIXELS);
to be consistent with the Sizeable API

Collaborator

Originally by @jouni


Replying to Signell:

layout.setComponentMinWidth("100px")
That would be ugly in my opinion, even though it might be consistent from the API point of view. Component alignments are of course a somewhat similar issue, yet they feel more in place than this would.

Collaborator

Originally by @jojule


Artur, you mean:

  • layout.setComponentMinWidth(childComponent, "100px")
  • layout.setComponentMinWidth(childComponent, 100,Units.PIXELS);

In any case - how this is different from the case where component says that is 100% wide (layout can give any amount of space for it), undefined (an expanding layout might want to reserve at lest the amount of space used measured from the component) or 10em (handled in the same way as undefined)? Adding min-max support to component directly would just just add these values to component UIDL as minwidth, maxwidth, minheight, maxheight. Layout is then free to use these when calculating expansions.

Say we have a button B and textfied T inside horizontal layout L. L is 100% wide, B is of undefined width, T is 100% wide with no min set and 200px max width. B is at index 0 and T at index 1. T is align left and has expandRatio of 1.0. What happens when window is resized to affect how 100% width of L is calculated - lets call that LW. Button width is measured from offsetWidth - lets call that BW. When LW>=BW, button is fully visible and slot 0 given to button in L is BW wide. If LW<BW, slot width == LW and button is clipped. Then the slot 1 where T resides is LW-BW wide. Pixel width of T - lets call it TW - will be calculated as LW-BW>200?200:LW-BW.

A more complex example with multiple components with min and max widths and different expand ratios should not be any different. Expand ratios should be used to divide space left after min widths have been taken. If an expanding component gets more than its max value, the extra space should be divided between other expanding components. If there is more extra space to use by the expanding components than max values allow, the extra space should be used in proportion of expanding ratios and alignments used to position components.

As a summary - IMO the min/max values should be attributes to the components - not to layouts surrounding them. Still layouts may use there values from components to provide meaningful expand ratio calculations.

Collaborator

Originally by @jouni


A little more about different units: percentage sizes as max values are very handy, and should not be disregarded.

In any case, I think these enhancements are only feasible for Vaadin 7 and not earlier. And we should probably try to rely on browsers' rendering more than currently, if that's even slightly possible (and it should be, since we're about to drop support for IE6).

Collaborator

Originally by @jojule


Jouni - is there some other case for % max size than having undefined base size?

Collaborator

Originally by @jouni


Replying to Lehtinen:

Jouni - is there some other case for % max size than having undefined base size?
Sure. The normal size, say width, is defined as 800px for example, and the max-width is 100%. The normal size would then in effect be the min-width, but the component would still shrink if the available space becomes too narrow.

Of course the priority of the values needs to be defined so these cases make sense. If the size value takes priority over min/max values, then percentage sizes as min/max make no sense.

Collaborator

Originally by @jojule


Makes sense. Updated the ticket accordingly.

Collaborator

Originally by @Legioth


Instead of forcing each and every Layout and Component to support these features, we could also consider just creating a wrapper component that can be used in that cases where this kind of functionality is required.

Collaborator

Originally by @jouni


Or as a decorator, once we get that feature inplemented.

Collaborator

Originally by grined


Is there any news about this feature? When it can be realized?

Collaborator

Originally by Marcel Hallmann


Hi there,

is there any news? I think this really would be a nice feature!

Collaborator

Originally by @jouni


For a limited set of functionality, see the Restrain add-on, which let's you set min/max-width/height from the server. It doesn't do any magic, it just set the corresponding CSS properties on the root element of the component. Expand ratios probably don't always work as expected.

Collaborator

Originally by maxuss


Replying to Koivuviita:

For a limited set of functionality, see the Restrain add-on, which let's you set min/max-width/height from the server. It doesn't do any magic, it just set the corresponding CSS properties on the root element of the component. Expand ratios probably don't always work as expected.

I tried Restrain add-on to set min and limit maxHeight of the tree component, but it does not work. Do I need to recompile widgetset or are there any other limitations?

Collaborator

Originally by @jouni


Yeah, you need to recompile the widgetset to make Restrain work.

Wow, I'm surprised that almost 7 years after being opened such a basic feature request, it's still open and undone.

I'm facin a problem with a Window, where I don't want to specify explicit dimensions for it as I'd expect it to grow dynamically to fit its contents. This works well until its contents make the window outgrow the height of the screen. I would expect a vertical scrollbar to automatically appear, but instead the window is cut and you cannot reach its "outgrown" content. The scrollbar only appears if you explicitly set a height, let's say, "90%". But what if the contents of the window only take, let's say, 20% height of the screen? Why do I want my window to have that extra 70% blank space just to be able to scroll in case it outgrows?

There should be a .setMaxHeight() method or whatever.

Member
jouni commented Feb 28, 2017

Thanks for the feedback! It is a bit strange, I admit, to not have built-in support for this yet. But we haven’t actually seen a big demand for this, so we’ve prioritized other things.

The use case you describe with the Window is probably the most often requested, and I provided a workaround for that just recently in the Frameowork Gitter chat.

Use this as your window content structure:

.v-csslayout (flex-column) <— window root content layout
   .v-csslayout (scrollable flex-1) <— whatever content
   .v-csslayout (flex-shrink-0) <— footer

Add this CSS to your theme:

.v-window {
  display: flex;
  flex-direction: column;
  max-height: calc(100% - 48px);
  overflow: hidden !important;

.v-window .popupContent,
.v-window .v-window-wrap,
.v-window .v-window-contents,
.v-window .v-scrollable {
  display: flex;
  flex-direction: column;
  position: initial;
}

.v-window .v-window-outerheader {
  display: flex;
  flex-shrink: 0;
}

.v-window .v-window-contents {
  flex: 1;
}

.v-window .v-window-contents  > .v-scrollable {
  overflow: hidden;
}

Not having minimum/maximum sizes ist quite annoying. Usually it is possible to find some workaround but it is always tricky or you need to change the layout. I encounter this problem on average maybe every 1-2 months. I wonder if it is just me that prefers dynamically sized windows and everyone else prefers a fixed size. Maybe you don't see a high demand for that feature because everyone knows some workaround but is still annoyed.

I hope you can find some time after the 8.1 release to add this. Even if it maybe just some checklist feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment