Bug 51580 - [RCP][Views] Need the ability to resize views programmatically
Summary: [RCP][Views] Need the ability to resize views programmatically
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: All All
: P3 normal with 5 votes (vote)
Target Milestone: 3.4 M2   Edit
Assignee: Boris Bokowski CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2004-02-10 22:11 EST by Matthew Hatem CLA
Modified: 2010-06-24 21:32 EDT (History)
23 users (show)

See Also:


Attachments
A patch that provides support for this feature (4.97 KB, patch)
2004-03-14 23:30 EST, Matthew Hatem CLA
no flags Details | Diff
Test case for the patch (2.33 KB, text/plain)
2004-03-14 23:33 EST, Matthew Hatem CLA
no flags Details
Patch that implements this enhancement (12.62 KB, patch)
2007-02-17 02:16 EST, Stefan Xenos CLA
no flags Details | Diff
Adds an example view to the o.e.ui.tests plugin (9.46 KB, patch)
2007-02-17 02:24 EST, Stefan Xenos CLA
no flags Details | Diff
Patch against Eclipse 3.3 that implements this enhancement (19.06 KB, patch)
2007-08-17 17:23 EDT, Chris Torrence CLA
no flags Details | Diff
Modified example view to the o.e.ui.tests plugin (9.71 KB, patch)
2007-08-17 17:47 EDT, Chris Torrence CLA
no flags Details | Diff
updated patch (36.07 KB, patch)
2007-08-20 11:39 EDT, Boris Bokowski CLA
no flags Details | Diff
updated patch with adapter and better sample view (43.29 KB, patch)
2007-08-21 00:28 EDT, Chris Torrence CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Hatem CLA 2004-02-10 22:11:47 EST
We need the ability to resize any view in a perspective programmatically.
Comment 1 Nick Edgar CLA 2004-02-11 11:41:08 EST
Consider for M8.  Could you describe the use cases you need to address?
Comment 2 Matthew Hatem CLA 2004-02-11 12:03:02 EST
Here are some current use cases for this feature.  This function should 
probably be mediated by the primary application, perspective or layout.

Preview Pane Use Case:

In some applications a view is used as a "Preview Pane".  This view needs to 
snap open and closed.  The closed state would be the view sized as small as 
possible, such that just the titlebar is showing.  The open state would be 
sized programmatically or would reflect some previous state.

Preferred Size Use Case:

In some applications there may be a view that can only format it's contents 
properly at specific size intervals.  When a user sizes a view to a size that 
the view cannot support, the view should snap it's size to the closest 
supported interval.
Comment 3 Nick Edgar CLA 2004-03-09 11:04:52 EST
Reassigning to you Matt since you're doing the work on this.
Comment 4 Matthew Hatem CLA 2004-03-14 23:30:26 EST
Created attachment 8564 [details]
A patch that provides support for this feature

Here it is.  I'm okay with changing the new method name and params.  Let me
know if you don't like the inner class or the recursion.

Test case will follow.

-m@
Comment 5 Matthew Hatem CLA 2004-03-14 23:33:20 EST
Created attachment 8565 [details]
Test case for the patch

Test case for the patch.
Comment 6 Matthew Hatem CLA 2004-03-14 23:37:03 EST
This is critical for Lotus/LWP.
Comment 7 Nick Edgar CLA 2004-03-17 17:36:16 EST
I'm looking at the patch now.

It would be better if it applied to IWorkbenchParts in general, not just
IViewParts (I know you're not using editors, but still <g>).

Also, using your test case, it seems to have no effect when the view is zoomed.
Not sure what the expected behaviour is here.  I wouldn't expect it to unzoom,
or change the zoomed size, but perhaps it could adjust the size of its unzoomed
state.
Comment 8 Nick Edgar CLA 2004-03-17 17:36:59 EST
Stefan, would you also be able to review this patch (since you implemented
collapse and know this area better than me)?
Comment 9 Nick Edgar CLA 2004-03-17 17:47:33 EST
I've released the internal part of this to allow you to get by for M8.

I'm not yet comfortable with the API or behaviour, so this will need to get
addressed later, either for M9 or post-3.0.
Comment 10 Matthew Hatem CLA 2004-03-17 17:52:42 EST
I agree with the editor comment, but don't have the time to implement.  Are you 
suggesting resizing the whole editor area?

About zoom and unzoom.  We don't have expectations there, we aren't zooming 
anything but LWPEditors (which are actually views).

-m@
Comment 11 Nick Edgar CLA 2004-03-23 13:48:48 EST
Marking for revisiting in M9 as per comment #9.
Comment 12 Stefan Xenos CLA 2004-04-15 16:28:03 EDT
I'm don't think we should add this enhancement. The preview pane use case could
be handled by providing API to minimize a view.

However, the preferred size use case is problematic. If views are using resize
listeners to override their size, this will cause all sorts of problems:
1. If there are two such views sharing a sash, it will either cause infinite
recursion or violate one of their preferred sizes.
2. This effectively works by setting an incorrect size on the view, then
correcting it, which will cause flicker and drastically slow down the layout
algorithm (the runtime will be multiplied by the number of views with preferred
sizes).
3. Sash resizing has no knowledge of the view's preferred sizes, so there is no
way to give the user feedback as they drag the sash... the sash will simply move
to a different location than where they dropped it, which will be unexpected.

If we really need to handle this use case, we should allow the view to describe
its preferred sizes and leave it up to the layout algorithm to try to resolve
the conflicts.

Comment 13 Matthew Hatem CLA 2004-04-15 18:06:03 EDT
I agree with everything you say BUT the feature is there in the form of 
Workbench internals.  We are in a code freeze state and will be picking up 
integration builds between now and M9.  Please do not remove this feature as we 
do not have the cycles to refactor.  

-m@
Comment 14 Nick Edgar CLA 2004-05-07 11:55:57 EDT
No further changes planned here for 3.0.
We'll leave the internal method in, and working, but cannot commit to it being 
API.
Need to address the following limitations post 3.0:
- handle editors
- address conflicting constraints between parts in the same layout
Comment 15 Stefan Xenos CLA 2004-07-15 02:01:39 EDT
Note: I'm working on a fix for this in bug 53649. 

Currently, the plan is this:

Each IWorkbenchPart will be able to implement a computeMaximumSize(int
availableWidth, int availableHeight) method that returns the preferred maximum
size for the part, given the available space. 

Parts that want quantized sizes or a snapped closed size will return the
next-smallest quantized size in their computeMaximumSize method. Normal parts
will simply return the available width/height as their maximum height. The
workbench will use these methods to compute a layout with minimal conflicts (if
there are no conflicts, everything will end up at its preferred size).

There will also be API to notify the workbench that the preferred size of some
part has changed and that it should trigger a layout at the next opportunity.

Combined, these will offer the main functionality of programmatic resizing but
without the dangers.

bug 53649 will contain the changes to the workbench layout algorithm. The API
changes will be added here.
Comment 16 Nick Edgar CLA 2005-03-21 12:28:13 EST
Sorry, nothing further planned here for 3.1.
Comment 17 Nick Edgar CLA 2006-03-15 11:24:12 EST
Reassigning bugs in component areas that are changing ownership.
Comment 18 Craig CLA 2006-11-24 04:44:13 EST
Reading all this, I ask the question: Is it currently possible to adjust the size of a view programmatically? 

My use case: I want to have standalone view at the bottom of my workbench. When I click a button it will expand/contract the view's height. I want all the neighbouring views to resize as this view increases or decreases in size. 
Comment 19 Alex Blewitt CLA 2006-11-24 06:55:26 EST
This seems to be just as applicable to other OSs and not just to V3.0 -- can someone update the OS to all and the version to 3.3M3?
Comment 20 Boris Bokowski CLA 2006-11-24 08:30:33 EST
(In reply to comment #18)
> Reading all this, I ask the question: Is it currently possible to adjust the
> size of a view programmatically? 

No, not without using internals.  I haven't checked, but looking at the last comment on bug 53649 it also seems that the implementation part of this has some problems.

As with most other bugs, I'd be happy to look at a patch for this.  Matt, do you still use internals, or did you find another way to address your use cases?
Comment 21 Craig CLA 2006-11-24 09:20:09 EST
The patch will be welcomed as long as it will not introduce bugs or become incompatible with future releases. If it could meet these requirements then it could just as well be implemented in the platform?
Comment 22 Boris Bokowski CLA 2006-11-24 09:41:44 EST
Sorry if I didn't make myself clear:  I have marked this bug as helpwanted because I cannot promise anything for 3.3.  If this is important enough for someone in the community that they are willing to spend some time on this, I can give feedback on what they think the API should be, and if we can reach agreement, this will be put into the Platform.
Comment 23 Craig CLA 2006-11-27 01:03:03 EST
I'll be willing to make the necessary changes, since it will be important for our project. Can you please direct me to the classes that you think I would have to modify in order to make this work. What would be the deadline for the 3.3 release?
Comment 24 Matthew Hatem CLA 2006-11-27 10:37:18 EST
We are no longer using this internal method.  

Stephan says this is fixed by bug#53649 with new API.  See comment#15.  Has anyone tried using these new APIs?
Comment 25 Boris Bokowski CLA 2006-11-27 15:20:44 EST
There is no new API (yet).  This bug is about defining an API for the implementation added by the fix for bug 53649.  It seems that ISizeProvider is the place to start exploring what Stefan did.  Stefan, do you know if there are any examples how this can be used?

Note that we wouldn't want to open up the workbench layout (view sizes etc.) to anybody.  Only the application should be able to do this.  New API should be put into WorkbenchWindowAdvisor/Configurer if it is independent of the current presentation.  I wouldn't be surprised if this has to be tied to a presentation, in which case I am not sure where that new API belongs.  Perhaps one could define an API at the WorkbenchWindowAdvisor/Configurer which is (optionally) implemented by a presentation and being used by the application.
Comment 26 Nick Edgar CLA 2006-11-28 12:34:04 EST
Actually, I think that regular workbench parts should be able to express a desire to be resized to match some new preferred size, without having to resort to controlling this from the advisor.  E.g. imagine I added a "preview pane" view after-the-fact to a mail application.

The advisor could still control whether requests for resize are honoured though.
Comment 27 Craig CLA 2006-11-29 01:46:18 EST
I agree this behaviour (comment #26) will make more sense. 
Comment 28 Boris Bokowski CLA 2006-11-29 17:01:17 EST
(In reply to comment #27)
> I agree this behaviour (comment #26) will make more sense. 

In the end, yes, but until we have a good understanding of the use cases for this, I would prefer to start small and just add API to the advisor.  Your particular advisor implementation can then have API that is being called by your views when they want to request a resize.
Comment 29 Stefan Xenos CLA 2006-12-07 01:36:44 EST
If I recall correctly, most of the hard stuff is in place. The presentation stacks can already express a preference for their size by implementing ISizeProvider and the workbench will resolve any conflicts and size them appropriately. They can also indicate that their preferred size has changed, which will cause them to be resized.

All that's missing is some way for the views and editors themselves to participate in this. It's relatively easy to let views implement ISizeProvider and expose this to the presentation via the IPresentablePart. They'd need a new method on the site that lets them tell the workbench about changes in their preferences.

However, I hesitated in hooking up the remaining bits since I couldn't think of a good way to actually implement a presentation that handled stacks of views nicely:

1. What should we do if the views in the stack had conflicting preferred sizes?
2. What should we do if the views have size preferences but haven't yet been lazily materialized?

I definitely don't like the idea of making the stack change size when the active part changes, but I never really thought of another satisfactory solution.

Of course, none of these problems occur with standalone views. If the people who want this feature are planning on using standalone views and custom presentations, it should be easy to satisfy them. The default Eclipse presentation, however...
Comment 30 Brandon Kane CLA 2007-01-02 21:49:50 EST
To add another use case for this feature, I have a requirement to implement the ability to arrange views programmatically.  The user can size them however they want, but in cases where there are many views often this is a hassle to get them set up in a particular way.  

For example, say there are 4 of the same view stacked in a set with one view in the foreground.  The user should be able to choose to arrange these in a 2x2 grid with each view taking up one quarter of the size of the original.  This is particularly useful when the views contain similar contents, such as scientific images that vary only very slightly and being able to see several images side by side is crucial to the application's functionality.

The same logic would stand for editors, but in my particular case I am using views.

Feel free to contact me if you need any further clarification or details.

Comment 31 Boris Bokowski CLA 2007-01-03 10:40:09 EST
Currently, I am very pessimistic whether I (or anyone else on the Platform/UI team) will have the time to actively pursue a solution for this in time for 3.3.  I agree that this is important for RCP apps, but there are so many other important things to work on at the same time.

Craig, are you still willing to contribute a patch?

Note that since this affects API, it will have to go in before the API freeze, which is about mid-February.
Comment 32 Craig CLA 2007-01-08 02:06:14 EST
I would rather wait for this feature to be done properly by the Platform/UI team. Is it possible to schedule it for 3.4? If this is possible, would it also be possible to give us a quick summary of the API (for this feature), during your design process. So we can give our comments.
Comment 33 Stefan Xenos CLA 2007-01-12 16:06:45 EST
The code should be relatively easy to write. The question is: how do we handle stacks?
Comment 34 Matthew Hatem CLA 2007-01-13 12:59:28 EST
I think it's reasonable to support this feature for stand-alone views only.
Comment 35 Brandon Kane CLA 2007-01-13 13:08:38 EST
This needs to apply to stacks as well, not just to standalone views.  To give the ability to programmatically move a view in and out of a stack would be required for the use case I outlined above where we need to be able to take all views in a stack and arrange them as non-stacked, with each view being given a fraction of the real estate that the stack previously occupied.
Comment 36 Chris Torrence CLA 2007-01-25 13:01:39 EST
Another use case: I have a standalone view containing a "command line" for my programming language. I want the height of the view to be fixed (it only contains a single-line Text widget), but the width can be allowed to vary.

I see two possible solutions:

1. Have an IPageLayout.addStandaloneView that could take some additional parameters such as minWidth, maxWidth, minHeight, maxHeight (with SWT.DEFAULT if you didn't want a constraint). The only problem with that approach is that you might want to compute your minimum height (say in my case) by the actual height of the contents, and it would be too early to compute since you would not have created the contents.

2. Allow ViewPart to implement ISizeProvider (see comment#29). Perhaps it could only be honored for standalone views?
Comment 37 Boris Bokowski CLA 2007-01-25 13:28:58 EST
(In reply to comment #36)
> 2. Allow ViewPart to implement ISizeProvider (see comment#29). Perhaps it could
> only be honored for standalone views?

This is an interesting idea.  Does anyone care to implement this prototypically and report back on this bug how well it works?
Comment 38 Stefan Xenos CLA 2007-02-17 02:16:48 EST
Created attachment 59221 [details]
Patch that implements this enhancement

Here's a work-in-progress patch that implements the feature. It does the following:

1. Adds new API. 
- Workbench parts can now implement ISizeProvider as a mix-in interface.
- There is a new property, IWorkbenchPartConstants.PROP_PREFERRED_SIZE, that parts can fire when their preferred size changes. This will trigger a layout in the workbench.
- IPresentablePart now implements ISizeProvider and gets a new property ID, so the presentation can access the preferred sizes of the parts.
IMHO, the API spec is relatively clean.

2. Updates the default presentation to make use of the new API part's preferred size. This is intended mainly as an example for Boris rather than release-quality code. If there is only one part in a stack, the stack uses the constraints from that part. If there is more than one part in the stack, constraints are disabled for that stack. This logic seems reasonable, but currently the constraints from the part are used verbatim. If this were to be released, the constraints would need to be adjusted to take into account space for the tabs, border, toolbar, etc. Either way, I assume that Boris would want to make his own decisions about the logic for the default presentation so I didn't polish this bit too much.

This patch should be enough to experiment with views and presentations that use constraints. I'll attach an example view-with-constraints soon.

Todo:
- This patch isn't well tested. It should be VERY well tested before it goes in.  It's really easy to make the workbench unusable if we get this wrong.

- I'm not checking for runtime exceptions when calling client-implemented ISizeProvider methods. This should be fixed, and constraints should be disabled for any part that ever throws an exception.

- I've been able to easily create constraints that cause stacks to disappear entirely. This is either a sign that the default presentation isn't protecting against dumb constraints in its parts or that the workbench layout itself has some yet-undiscovered bugs. Probably both. We'll need to investigate these cases further.

Anyway, I'm attaching this here in case it will help someone get started... but I don't plan to polish it up to release quality. Hopefully someone will find it useful.
Comment 39 Stefan Xenos CLA 2007-02-17 02:24:45 EST
Created attachment 59222 [details]
Adds an example view to the o.e.ui.tests plugin

This patch adds an example view called "Layout Constraints Test". It has:
- Adjustable minimum and maximum horizontal and vertical sizes.
- Adjustable resolution for horizontal and vertical quantized sizes (for example, it can be set up to make the horizontal sash jump so that the view's width is always a multiple of 10 pixels)
- Optional fixed area constraint. When enabled, it tries to maintain the area of the view such that the view always covers the given number of pixels. Although silly, the logic is similar to that of a view that would try to match the size of a wrapping widget.
- Buttons to enable/disable the constraints, and to clone the view.
Comment 40 Boris Bokowski CLA 2007-02-19 14:29:08 EST
(In reply to comment #38)
> Anyway, I'm attaching this here in case it will help someone get started... but
> I don't plan to polish it up to release quality. Hopefully someone will find it
> useful.

Thanks Stefan!  I looked at the patch and it seems to work fairly well, but I agree that this needs more work before it can be put into the default presentation.  In particular, it needs to be off by default for the IDE for now because of the risk of potentially screwing the workbench layout.  Could be a preference, or something that can be configured at the advisor level.

Does anyone from the community care about this enough to help out?  We are almost there.  Craig? Brandon? Chris?
Comment 41 Brandon Kane CLA 2007-02-19 21:17:20 EST
I'm happy to help out where I can, although I must admit I'm relatively new to the inner workings of Eclipse so I'll probably need some help to get me started.  I can definitely spend some hours testing or doing additional dev work over the next few weeks if someone can take a bit of time to get me started and show me what I need to do.

Please feel free to drop me an e-mail with details of what you need me to do.

Brandon
Comment 42 Craig CLA 2007-02-20 01:19:30 EST
Since I don't have experience in working with the internals of Eclipse, I will also need a bit of help to get started. 
Comment 43 Boris Bokowski CLA 2007-02-20 08:47:37 EST
http://www.eclipse.org/articles/Article-UI-Workbench/workbench.html is a good start for understanding the workbench internals.

Here is what I believe remains to be done:
- Making sure that the important use cases are covered.
- Testing (using Stefan's example view in various layouts, but also variants of it like a standalone view, a detached view). For example, I noticed that sometimes, sashes are not draggable when they should be.
- Finishing Stefan's implementation: taking trim size into account.
- Fixing Bugs.
- Determining how best to make the new behaviour optional, e.g. using a preference, or a configuration method on Workbench(Window)Advisor, and implementing this.
- Making sure that the Javadoc for the new API is complete, and requesting permission for the necessary API changes from the PMC.

The last two of these would have to be done pretty soon (deadline: beginning of the week after EclipseCon, say March 13) because of the upcoming API freeze for 3.3.  We would also have to be sure that any remaining issues/bugs can be fixed during the M7 development cycle, because otherwise it will be hard to get PMC permission for the API change.

Note that some of these things become easier if we decided (e.g. for 3.3) that the new behaviour is only supported for standalone views.  This would make it easier to test, to compute the trim size, to fix bugs, and to specify the behaviour.

I hope I didn't scare you off by this.  Welcome to working on a platform!
Comment 44 Boris Bokowski CLA 2007-02-20 08:48:55 EST
Setting target milestone to 3.3M6.  I'm optimistic ;-)
Comment 45 Stefan Xenos CLA 2007-02-20 11:19:37 EST
IMHO, if we're confident with the implementation, it should be on by default. Whoever implements a view that uses constraints will want this behavior. Letting them have it by default will encourage them to use the workbench's layout rather than rolling their own part framework within their editors and views.


> sashes are not draggable when they should be

Could you elaborate? The sashes should always be draggable if there's anywhere they could possibly move, but they shouldn't always move with the cursor during dragging (for example, they should stop when they hit the maximum size of a view, even if you move the cursor farther).


Just for discussion (not required for this fix):

I think there *may* be a bug in the workbench's layout or the example I included. You can see it in the example view - if you turn on horizontal quantizing and try to drag the sash, half of the time the sash will drag in discrete jumps, and sometimes it will drag smoothly. I think the problem is here in the example view:

+		if (result > availableParallel) {
+			result = availableParallel;
+		}

I'll bet that availableParallel is being set exactly the remaining space in the workbench, after computing the space for the unconstrained part... so when the part says that its preferred width is bigger than the current sash position, the request gets ignored.

Of course a workaround would be to ensure that the example never asks for more than the workbench's preferred size:

change this:
result = result + (quant / 2) - ((result + quant / 2) % quant);

to this:
result = result - (result % quant);

That should make the quantizing work nicely, but the sash will always jump to one side of the cursor rather than remaining as close to the cursor as possible... I'm not sure if it would even be possible to resolve this sort of constraint - in which case we should consider it a bug in my example - I just wanted to draw attention to the problem.
Comment 46 Stefan Xenos CLA 2007-02-20 11:26:45 EST
Actually, now that I think of it, The example should be doing this:

// If we're using quantized sizes, jump to the nearest multiple 
// of the -quantized size
if (quant != ISizeProvider.INFINITE && quant != 0) {
        result = Math.min(result + quant / 2, availableParallel);
	result = result - (result % quant);
}

...it should try to put the sash in the quantized position as close to the cursor as possible -- IF the space is available. Otherwise, it will put it at the next available position. I no longer think there is anything wrong with the workbench. This is a bug in my example view.
Comment 47 Chris Torrence CLA 2007-02-25 01:03:03 EST
I hacked Stefan's changes into my Eclipse 3.2 install, and it works beautifully. I have a standalone view that should keep a constant height (it just contains a Text widget), and with the new code, it does!

The user cannot adjust the height, but they are still free to move the view around. If they move the standalone view next to a different view (so they are side-by-side), then my preferred height is ignored, and both views have the same height. This also seems correct. The user can then shrink the height of the combined pane, and it will shrink until it reaches the minimum height of the standalone view, which is exactly as expected.

Now what I really want to do in my own ViewPart is compute my own size, and not worry about the trim, tabs, etc.

In my ViewPart (m_parent is the Composite passed in to createPartControl):
    public int computePreferredSize(boolean width, int availableParallel, int availablePerpendicular, int preferredResult) {
      if (width) return preferredResult;
      Point p = m_parent.computeSize(SWT.DEFAULT, SWT.DEFAULT);
      return p.y;
    }

So, to do this, in TabbedStackPresentation.computePreferredSize(), I changed the code to adjust the preferred size by adding on the tab and border trim:

      // If there is exactly one part in the stack,
      // this just returns the preferred size of the
      // part as the preferred size of the stack.
      //
      // TODO: Should this be changed to check for standalone views?
      if (getSite().getPartList().length == 1) {
        IPresentablePart selectedPart = getSite().getSelectedPart();
        int partSize = selectedPart.computePreferredSize(width,
          availableParallel, availablePerpendicular, preferredResult);

        int minSize = 0;
        // Adjust preferred size to take into account tab and border trim.
        if (width) {
            int heightHint = availablePerpendicular ==
              INFINITE ? SWT.DEFAULT : availablePerpendicular;
            minSize = folder.getTabFolder().computeSize(SWT.DEFAULT,
              heightHint).x;
            if (minSize > 100) minSize -= 100;  // this is not good
        } else {
            int widthHint = availablePerpendicular ==
              INFINITE ? SWT.DEFAULT : availablePerpendicular;
            minSize = folder.getTabFolder().computeSize(widthHint,
              SWT.DEFAULT).y;
        }

        partSize += minSize;
        return partSize;
      }

Notice that for the width, I had to make an evil -100 adjustment because of the existing code within PaneFolder:
    public Point computeMinimumSize() {
        Point result = Geometry.getSize(tabFolder.computeTrim(0, 0, 0, 0));
        // Add some space for the minimize and maximize buttons plus a tab.
        // Right now this isn't exposed from SWT as API, so we just add 50
        // pixels.
        result.x += 100;
        return result;
    }


So, it seems like we need to make the following decisions:


1. Should this be restricted only to standalone views? This seems preferable.

If we do this only for standalone views, then I don't think we need a preference or anything turned off by default. The rule would be: If you have a standalone view, and it implements ISizeProvider, then the workbench will honor your preferred size. Since no one should have been doing this in the past, the backwards compatibility risk seems low.

If we extend this behavior to stacked views, then it's unclear how to resolve any potential preferred size conflicts. Again, the risk of breaking existing apps still seems low, since no one should have been implementing ISizeProvider. But it seems trickier to get right, both from within the workbench and for an external developer. Brandon, what do you think?


2. Do we want the user to return just the preferred size of the Composite within the ViewPart? This seems simpler for the user. Otherwise they will need to know how to compute the tab size, border trim, etc.


Not sure if I'm ready to commit to writing the actual code, but I am happy to help with ideas, or in testing any proposed solution.

Thanks for keeping this bug active!
Comment 48 Boris Bokowski CLA 2007-03-13 15:49:39 EDT
> Not sure if I'm ready to commit to writing the actual code, but I am happy to
> help with ideas, or in testing any proposed solution.

Thanks for your help. Unfortunately, it seems that we ran out of time for M6 - this week is the last week of development for M6.
Comment 49 Raji Akella CLA 2007-07-24 10:39:15 EDT
Can we get this in 3.4 ?

Comment 50 Chris Torrence CLA 2007-07-24 10:55:00 EDT
I have re-worked Stefan's patch (see comment #38) for Eclipse 3.3, and included the code to take trim size into account. It will be a few days before I have time to get this into a cvs patch format, but when I do, I will attach the patch.
Comment 51 Boris Bokowski CLA 2007-07-24 12:18:15 EDT
(In reply to comment #50)
> I have re-worked Stefan's patch (see comment #38) for Eclipse 3.3

Great! Looking forward to it.
Comment 52 Chris Torrence CLA 2007-08-17 17:23:59 EDT
Created attachment 76344 [details]
Patch against Eclipse 3.3 that implements this enhancement

Patch against Eclipse 3.3 that implements this enhancement.

This patch is a modification of Stefan's patch (see comment #38). The patch is against the latest (14 Aug 2007) code base.

Changes from Stefan's original patch:

1. TabbedStackPresentation: in computePreferredSize(), getSizeFlags() and addPart(), instead of using getSelectedPart, simply use the one-and-only stack part. This fixes a bug in Stefan's patch where you would detach a view, then reattach the view, and it wouldn't honor the view's preferred size because the view would not have been selected yet.

2. TabbedStackPresentation: added a private computePreferredMinimumSize() method, used within computePreferredSize(). This now takes into account the tab and border trim.

3. DetachedWindow: added an updateMinimumSize method, that takes into account the preferred size of the first view added to the detached window. Also made DetachedWindow be a listener of the AbstractTabFolder within the TabbedStackPresentation.


Remaining to be done:

1. Code verification and testing.
2. Add the appropriate JavaDoc.
I added one sentence to IPresentablePart, stating:
   @since 3.4 now extends {@link org.eclipse.ui.ISizeProvider}
I don't know if that is the correct format, or the correct version number.
We should also add JavaDoc about the ability for views to implement ISizeProvider. I was not sure where to put this JavaDoc: WorkbenchPart? ViewPart?


Overall Behavior:

If you have a View Part that implements ISizeProvider, and it is the only part in a stack, then the size constraints for that View Part will be used for the stack. If there is more than one part in the stack, the constraints will be disabled for that stack. The size constraints are adjusted for the size of the tab and border trim.

If your View Part is detached from the workbench, and it is the first view added to the detached window, then the minimum size constraints (if any) for that view are used to constrain the minimum size of the detached window. Note that the maximum size constraints are ignored.

I will submit a modification of Stefan's example.
Comment 53 Chris Torrence CLA 2007-08-17 17:47:40 EDT
Created attachment 76347 [details]
Modified example view to the o.e.ui.tests plugin

Modification of Stefan's example view. This updates the code to Eclipse 3.3 (code base as of 14 Aug 2007).

Changes:
1. Made the button text shorter.
2. Changed the "Clear Constraints" button to "Reset", and had it actually reset all of the widget values and trigger a layout update.
3. Applied Stefan's example code fix (see comment #46).
Comment 54 Boris Bokowski CLA 2007-08-20 11:39:11 EDT
Created attachment 76462 [details]
updated patch

Updated patch with contribution comments, and Javadoc changes.
Comment 55 Boris Bokowski CLA 2007-08-20 12:53:36 EDT
CC'ing Eric - could you please double-check this patch? Thanks.

My plan is to release this in its current form to make it easy to use for RCP application developers.

(from comment #26)
> The advisor could still control whether requests for resize are honoured
> though.

For now, the new behaviour is enabled for all applications. Just a heads up that I might add API to the workbench advisor later in 3.4 which has to be called to enable this. The problem for the IDE, or any extensible RCP application, is that allowing views to specify their size can lead to difficult-to-understand cases where users might file bugs about (e.g.) not being able to drag a sash, etc.
Comment 56 Boris Bokowski CLA 2007-08-20 12:59:51 EDT
When I showed this to Eric, he had two ideas for improvement:

1 - A RCP application might want to control the sizes of pre-existing views (e.g. Outline, Properties). For this to work, we might want to allow adapting view parts to ISizeProvider rather than requiring them to implement it directly.

2 - It would be nice if the test view included a text area showing the concrete implementations of getSizeFlags() and computePreferredSize() for easy copy-and-pasting into real view part implementations.
Comment 57 Chris Torrence CLA 2007-08-20 16:14:20 EDT
(In reply to comment #56)
> 1 - A RCP application might want to control the sizes of pre-existing views
> (e.g. Outline, Properties). For this to work, we might want to allow adapting
> view parts to ISizeProvider rather than requiring them to implement it
> directly.

This is a good idea. Just a quick clarification: I assume that I would only need to modify the TabbedStackPresentation where we do the "instanceof". (We also extended the IPresentablePart interface with ISizeProvider, but it is only used internally and is doc'd as "not intended to be implemented by clients".)

> 2 - It would be nice if the test view included a text area showing the concrete
> implementations of getSizeFlags() and computePreferredSize() for easy
> copy-and-pasting into real view part implementations.

Right now, in the test view, the getSizeFlags() and computePreferredSize() are just a bunch of "if" blocks that handle all of the different possibilities. This doesn't seem too useful as sample code, and the developer can always just look at the source for LayoutConstraintsView. It would be great if it could only show the sample code for the exact combination of settings, but that would be very tricky given the number of different combinations. Perhaps we could just include some "real world" examples in the JavaDoc?
Comment 58 Boris Bokowski CLA 2007-08-20 17:02:21 EDT
(In reply to comment #57)
> This is a good idea. Just a quick clarification: I assume that I would only
> need to modify the TabbedStackPresentation where we do the "instanceof". (We

I believe the change would be in WorkbenchPartReference. Change the two occurrences of:
    if (part instanceof ISizeProvider) {  ...
to:
    ISizeProvider sizeProvider = (ISizeProvider) org.eclipse.ui.internal.util.Util.getAdapter(part, ISizeProvider.class);
    if (sizeProvider != null) {  ...


> Right now, in the test view, the getSizeFlags() and computePreferredSize() are
> just a bunch of "if" blocks that handle all of the different possibilities.

Can't you just create methods getSizeFlagsString() and computePreferredSizeString() that returns a string with the method source that would implement the current behaviour? For example,

public int getSizeFlagsString() {
  StringBuffer result = new StringBuffer();
  result.append("public int getSizeFlags(boolean width) {\n");
  int flags = 0;
  result.append("\tif (width) {\n");
  result.append("\treturn 0 |");
  if (minWidth != ISizeProvider.INFINITE) {
    result.append(" SWT.MIN");
  }
  if (maxWidth != ISizeProvider.INFINITE) {
    result.append(" SWT.MAX");
  }
...

Anyway, this was just an idea, don't feel obliged to implement it.
Comment 59 Chris Torrence CLA 2007-08-21 00:28:35 EDT
Created attachment 76508 [details]
updated patch with adapter and better sample view

Here's the patch, which addresses both issues in comment #56.

1. Your ViewPart now just needs to adapt to ISizeProvider. I also updated the JavaDoc in IViewPart by simply changing "views may optionally implement..." to "views may optionally adapt to...".

2. Enhanced the example view to include a text pane with sample code. Despite my reluctance (see comment #57), it was actually fun to code up.
Comment 60 Eric Moffatt CLA 2007-08-27 13:24:41 EDT
In general this looks fine.

Constrained View issues:

Main presentation:

Generally speaking it has to be used with care; you can create incompatible layouts very easily.

Detached Windows / Fast Views:

Note that due to the current FV layout strategy it will be unable to honor the constraints in 'orientation' direction (i.e. 'horizontal' views -always- get the complete width of the Workbench Window and similarly for 'vertical' views getting the complete -height-. I think I can live with that...;-). Note that we should re-visit this if we change the ways that FV's appear (which is a distinct possibility in 3.4).

Maximums and quantization aren't handled. I realize that this is because of the lack of a Shell#setMaximumSize method. How necessary are constrained maximums? IF we can't honor them in any but a small subset of cases then we should at least j'doc the contrsints on the constraints...

Finally, a small nit. Then 'generated' code might look more readable if you defined local static fields and used them instead of hardcoding the actual values. This would make it more obvious to folks who may be coming into the code in the future to figure out what's going on. I'm not sure but it might be possible to actually code up the methods statically (i.e. they never change) based on the values of the various fields...just a thought.
Comment 61 Boris Bokowski CLA 2007-08-27 15:47:06 EDT
Patch released to HEAD >20070827.  The next I build (I20070828-0800) will contain the changes. Please grab the build if you can and give it a try. I would suggest dealing with any remaining issues in separate bugs.

Thanks for your help!
Comment 62 Chris Torrence CLA 2007-09-06 11:20:03 EDT
I just tried the version from I20070828-0010, and it works as expected. Thanks very much to Stefan for creating the initial patch and to Boris for driving it to completion!
Comment 63 Boris Bokowski CLA 2007-09-18 13:31:29 EDT
(In reply to comment #62)
> I just tried the version from I20070828-0010, and it works as expected.

Marking as verified.
Comment 64 Boris Bokowski CLA 2007-11-26 15:25:16 EST
I am unsure if this needs to be IP-reviewed. The original work was done by Stefan Xenos, a committer on Platform UI at the time. Chris took the original patch and made it compile (and work) for 3.3.  The same is true of the example view, which was originally written by Stefan and then improved by Chris. I was under the impression that Chris' contribution was only a few lines of code (10 to 20) in the actual patch, plus some work on the example view which I estimated to be about 100 to 150 lines of code. Chris, does this sound right?
Comment 65 Chris Torrence CLA 2007-11-26 16:49:13 EST
Boris, that is correct. I took Stefan's original patch, and made some slight modifications, as described in comment #52. The main changes were to have the TabbedStackPresentation take into account the tab and border trim, as well as make sure the preferred size was honored for a detached view. My changes were probably about 20 lines of Stefan's code.

Perhaps there is concern because the patch has exposed some other bugs? Bug 202208 had to do with using the new ISizeProvider interface with a standalone view with no title. This bug was exposed by the new interface, and the patch for 202208 simply required a check for parts without tabs.

Bug 210424 states that a minimized view fails to expand adjacent views. This required a fix to the patch. However, it looks like this was exposed by the new minimize view behavior, and is only a problem in Eclipse 3.4. I tried this with Eclipse 3.3 (with a hacked version of org.eclipse.ui.workbench that contained the 51580 patch), and there was no problem with minimized views.
Comment 66 Chris Torrence CLA 2007-11-26 17:06:53 EST
Regarding my previous comment, I don't think I directly answered the question about IP issues. I thought you were referring to the "quality" of the patch, from an outside contributer versus an internal committer.

Regarding IP, our company (ITT Visual Information Solutions) is willing (and happy) to contribute code back to the Eclipse community, under the terms of the Eclipse Public License (EPL). If you need any more information, or a signed consent form, feel free to contact me.
Comment 67 Boris Bokowski CLA 2007-11-26 17:22:46 EST
I don't have any concerns about the quality of the code. Follow-up bugs are just a fact of life.

The context for my question was that the Eclipse Foundation requires IP review (was original work submitted, as opposed to e.g. code copied from somewhere else) for any contribution over 250 lines of code coming from a non-committer. I was arguing that your contribution was less than that.

Can you give a number for how many lines you authored in the example view, too?
Comment 68 Chris Torrence CLA 2007-11-26 17:32:00 EST
Doing a quick diff, I added about 180 lines to Stefan's original example code.
Comment 69 Julian CLA 2010-06-22 07:39:48 EDT
My English not so good, I do not know whether the contents of the above resolve my needs £º

In my RCP application, I have three perspectives, let's call them P1, P2, P3.

At the left side of the editor area, I have a view folder, and there are three views stacked, call them V1, V2, V3, these three views act as "NavigateView", and these views will be shown in each perspective, and when one of these views is activated, it will activate the corresponding perspective, for example, if V1 activated, P1 will be activated.(V2 -> P2, V3 -> P3)..

The problem is:

By default, the folder has different width value for each perspective (the initial width was same, but if user resize the folder when P1 is activated, and switch to P2, the width of the folder is not same with previous resized value)

I want to keep the same width of the folder (three views) when perspective was changed. 
I think what I want is the ability to resize the folder, It seems that ISizeProvider cannot resolve this? May be I misunderstood it because of my poor english?

If anyone can read this and give me a help?

Thanks very much.
Comment 70 Boris Bokowski CLA 2010-06-22 12:56:06 EDT
(In reply to comment #69)
> I want to keep the same width of the folder (three views) when perspective was
> changed. 

I think ISizeProvider could help, but it looks like there's a bug in our code when handling multiple views in the same stack that adapt to ISizeProvider.

Here's some example code I used to experiment, and sometimes a stack with two views using this code behaved as you'd like it to (constrained to 300 pixel width) but sometimes the stack was resizable. I'd say it's worth experimenting, and ideally finding the bug and contributing a fix in a new bug report. :-)


// Sample implementation: Make sure your ViewPart adapts to ISizeProvider.
// Then implement the following two methods.

/* (non-Javadoc)
 * @see org.eclipse.ui.ISizeProvider#getSizeFlags(boolean)
 */
public int getSizeFlags(boolean width) {
	int flags = 0;
	if (width) {
		flags |= SWT.MIN;
		flags |= SWT.MAX;
	} else {
	}
	return flags;
}

/* (non-Javadoc)
 * @see org.eclipse.ui.ISizeProvider#computePreferredSize(boolean, int, int, int)
 */
public int computePreferredSize(boolean width, int availableParallel,
	int availablePerpendicular, int preferredResult) {
	int result = preferredResult;
	if (width) {
		// Ensure we go no smaller than the minimum size
		if (result < 300) result = 300;
		// Ensure we go no larger than the maximum size
		if (result > 300) result = 300;
	} else {
	}
	// Ensure that we do not use more than the available space
	if (result > availableParallel) result = availableParallel;
	if (result < 0) result = 0;
	return result;
}
Comment 71 Julian CLA 2010-06-24 13:00:20 EDT
Thank you Boris.

But I think you don't know clearly about what I need.

I don't want a "FIXED" width value of the views, I just want to keep the same width of the views between two perspectives.

In other words, when user resize the view in Perspective1 and switch into  Perspective2, I want the width value of the view in P2 is same with the value in P1. 
I don't know the numeric value of the width, this numeric value is decided by user's resize operation.

Here's my use case:

I'm working on a RCP application looks like Microsoft Outlook, 
there are some navigate views at the left side of workbench, like Contacts, Mail, Tasks etc. and I wrote my own presentations looks like Outlook (also like org.eclipse.nebula.widgets.collapsiblebuttons)

Each navigate view has a corresponding perspective and some other views are contributed into this perspective from org.eclipse.ui.perspectiveExtensions, 
and when user activate one navigate view, the corresponding perspective will be activated.

What I want is to keep the width value of navigate views same between perpectives.

Thanks very much.
Comment 72 Boris Bokowski CLA 2010-06-24 15:28:46 EDT
Sorry, I don't think the current infrastructure supports what you need.  You should have better luck with e4 where you can get hold of the underlying model of the perspectives, stacks, and views and manipulate the model to keep the sizes in sync. But that's only coming together now, not sure if it's worth porting your application to use e4 just because of this one feature.
Comment 73 Julian CLA 2010-06-24 17:25:01 EDT
(In reply to comment #72)

Thank you very much, Boris. You really helped me.


Now I have an idea:

1. Attach a PerspectiveListener to the WorkbenchWindow

	window.addPerspectiveListener(new PerspectiveAdapter() {....});

2. Get the width of the view's container when the previous perspective is about to be deactivated.

	public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {

		width = container.getSize().x; //Assume that the value is equal to 365.
	}

3, When the target perspective is activated, call firePropertyChange of the view with the propertyId "PROP_PREFERRED_SIZE":

	view.firePropertyChange(IWorkbenchPartConstants.PROP_PREFERRED_SIZE);

4. Now I can use getSizeFlags and computePreferredSize to tell the underlying infrastructure that I want the view to have the width equals to 365 and finally please allow the user can resize the view.

The problem is that I am not very clear with the mechanism of ISizeProvider. I can make the with of the view equals to 365 now, but I don't know how to tell the underlying infrastructure that finally user can resize the view...

Can you take some time to read this and help me, great thanks.
Comment 74 Boris Bokowski CLA 2010-06-24 21:32:13 EDT
(In reply to comment #73)
> The problem is that I am not very clear with the mechanism of ISizeProvider. I
> can make the with of the view equals to 365 now, but I don't know how to tell
> the underlying infrastructure that finally user can resize the view...
> 
> Can you take some time to read this and help me, great thanks.

Sorry, I don't think I can help you with this. You could try changing your size constraints to a fixed width of 365 first, and then removing the size constraint immediately. But you're on your own now, trying to trick the system. Good luck!