Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Option for SC.SegmentedView to automatically adjust its size to fit. #974

Closed
wants to merge 1 commit into from

3 participants

@jlaxson

Allows you to specify shouldAutoResize: YES on a SegmentedView and have it set its own size based on the number of items. Useful for placing in a flowed or stacked layout.

@dcporter
Owner

+1 on this guy too. It'll need a unit test though.

@publickeating

This looks pretty good, but I think it will fail if shouldHandleOverflow is set to false, which means it will fast path out of those methods and won't try to remeasure itself.

I wonder if a simpler API would be that if shouldHandleOverflow is true, then the overflow menu appears when the view overflows its set size and if shouldHandleOverflow is false, then the view re-adjusts itself using your code? The two properties seem mutually exclusive to me and so it would be simpler to just use the existing one.

@dcporter
Owner

@publickeating So what you're suggesting is... every segmented view should automatically resize itself automatically, unless shouldHandleoverflow is true, in which case it will resize itself up to its specified width (or height) and no further? Seems simple but a little counterintuitive. I suppose the current situation is no better though, where I guess if you set shouldHandleOverflow to no, then the overflowed buttons simply run out of sight? Is that the current situation? If so then I agree that resizing should simply be the view's expected behavior (like ListView), with width (or height) ignored entirely unless shouldHandleOverflow is true.

@dcporter
Owner

@publickeating question about your approach: if I've got my SegmentedView laid out with {left: 0, right:0} (my usual approach since this allows enough stretch area for the current non-resizing version), and it starts automatically resizing itself, what will it do? Or will it only auto-resize itself if it's laid out with width?

This is a simple-enough change that either we should pull it in as is or pull it in as the default behavior for 1.11 and announce it.

@dcporter dcporter referenced this pull request from a commit
@dcporter dcporter Implements SC.SegmentedView#shouldAutoResize, courtesy of @jlaxson. I…
…ncludes unit tests. Resolves #974.
9f4e0fb
@dcporter dcporter closed this pull request from a commit
@dcporter dcporter Implements SC.SegmentedView#shouldAutoResize, courtesy of @jlaxson. I…
…ncludes unit tests. Resolves #974.
9f4e0fb
@dcporter dcporter closed this in 9f4e0fb
@dcporter
Owner

Changed my mind on this after pushing to master. I'm going to implement @publickeating's suggestion and push it ASAP. Sorry about that.

@dcporter dcporter reopened this
@dcporter
Owner

Un-re-tweak-fixed this in 3f91289.

@dcporter dcporter closed this
@publickeating

I don't think I was correct on this.

ex. I have a SegmentedView that I do not want to resize nor overflow. If I set shouldHandleOverflow to false, then it's trying to resizing poorly. If I set shouldHandleOverflow to true, then it's overflowing poorly.

I believe the unverified problem in both situations is that the adjust is occurring when the view first appears at a point where its visible rect is quite small before its parent animates open.

I'm going to revert your patch and leave @jlaxson's code there for now, because it ultimately gives me the flexibility to prevent resize + overflow.

@publickeating publickeating reopened this
@publickeating

This one is still slated for 1.11.0, so I opened it up again so we can look at it further.

@dcporter
Owner

Good thing I put both approaches in the commit history then.

@publickeating publickeating modified the milestone: 1.12.0, 1.11.0
@publickeating

Closing this up again. @jlaxson's original version gives the most flexibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 9 additions and 2 deletions.
  1. +9 −2 frameworks/desktop/views/segmented.js
View
11 frameworks/desktop/views/segmented.js
@@ -296,6 +296,8 @@ SC.SegmentedView = SC.View.extend(SC.Control,
segmentViewClass: SC.SegmentView,
+ shouldAutoResize: YES,
+
/** @private
The following properties are used to map items to child views. Item keys
are looked up on the item based on this view's value for each 'itemKey'.
@@ -554,7 +556,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
if (this.get('isVisibleInWindow')) {
// Make all the views visible so that they can be measured
overflowView = childViews.lastObject();
- overflowView.set('isVisible', YES);
+ if (overflowView) overflowView.set('isVisible', YES);
for (var i = childViews.get('length') - 1; i >= 0; i--){
childViews.objectAt(i).set('isVisible', YES);
@@ -578,6 +580,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
childView,
value = this.get('value'),
overflowView = childViews.lastObject(),
+ autoResize = this.get('shouldAutoResize'),
isHorizontal = this.get('layoutDirection') === SC.LAYOUT_HORIZONTAL,
visibleDim = isHorizontal ? this.$().width() : this.$().height(), // The inner width/height of the div
curElementsDim = 0,
@@ -599,7 +602,7 @@ SC.SegmentedView = SC.View.extend(SC.Control,
// check for an overflow (leave room for the overflow segment except for with the last segment)
dimToFit = (i === length - 1) ? curElementsDim : curElementsDim + this.cachedOverflowDim;
- if (dimToFit > visibleDim) {
+ if (!autoResize && dimToFit > visibleDim) {
// Add the localItem to the overflowItems
this.overflowItems.pushObject(childView.get('localItem'));
@@ -629,6 +632,10 @@ SC.SegmentedView = SC.View.extend(SC.Control,
// Store the minimum dimension (height/width) before overflow
this.cachedMinimumDim = curElementsDim + this.cachedOverflowDim;
+
+ if (autoResize) {
+ this.adjust(this.get('layoutDirection') === SC.LAYOUT_HORIZONTAL ? 'width' : 'height', this.isOverflowing ? this.cachedMinimumDim : curElementsDim);
+ }
},
/**
Something went wrong with that request. Please try again.