Animator add-on

Hi folks!

We’re currently redesigning the Uilder interface with Sami, and I ended up drawing a mockup that would benefit from simple animations. So I decided that it was straightforward enough to build a small component for those simple animations.

So here’s the result:



Animator Demo

See full description and download from the Directory:

Animator add-on

Have fun, and use responsibly :wink:

This really is as cool as it sounds! :slight_smile: Based on code looks very simple to use.
I think animations for transition are a good way way to emphasize something. Not that we are going to overuse them or anything…

Oh, right, forgot to add a simple example code:

Animator anim = new Animator(new Label("Animate Me!"));
anim.rollDown(300, 200);
anim.fadeIn(300, 400);
addComponent(anim);

Hi Jouni,

Thanks for this great component :slight_smile:
Is there a way to set the state of the animator to rolled up / faded out before its creation (so that its hidden on first display)?
I haven’t found a way (but I don’t know if I’ve overlooked something), so I created setters and getters for your rolled / faded fields:


	public void setFaded(boolean faded) {
		this.faded = faded;
		requestRepaint();
	}

	public boolean isFaded() {
		return faded;
	}

	public void setRolled(boolean rolled) {
		this.rolled = rolled;
		requestRepaint();
	}

	public boolean isRolled() {
		return rolled;
	}

If there is some other way, please let me know :slight_smile:
Best greetings from Germany
Eric

You’re welcome! Nice to see someone using it.

I threw this component together quite quickly, and this simple use case slipped from the first release. I realized the need myself later on as well.

Your workaround is good, I’ll add those methods myself when I get back to this pet project. Or did you have something more elegant in mind?

I am getting the following error when I try to use Animator, what does it mean? I am using Vaadin 6.3-pre-release and GWT 2.0.3

Widgetset does not contain implementation for org.vaadin.jouni.animator.Animator. Check its @ClientWidget mapping, widgetsets GWT module descrioption file and re-compile your widgetset. Unrendered UIDL:

org.vaadin.jouni.animator.Animator(NO CLIENT IMPLEMENTATION FOUND)

Thank You

Peter

Hi Peter,

Just tested it with a new Vaadin project. Works seamlessly.

I bet you’ve forgotten to re-compile your widgetset (like it says in the error message). If you’re using the Eclipse plugin, just click the “Compile Vaadin Widgets” button in the toolbar, wait for it to finish, and reload the browser.

Anybody planning on creating an Animator version of a Drawer or DisclosurePanel like GWT has?

Just trying to use Animator 1.1 (from the Directory) with Vaadin 6.3.4, but having some issues that I can’t figure out.

I am trying to animate a Panel with a small button to act something like the Drawer component.

In IE8, when my Form is first populated from a item selected in a Table list, the Panel is displayed, though the component thinks it’s rolled up. When I first click the button, the animator thinks its rolled up so I call rollDown(). But then, the animator works as expected, rolling up and down on each click of the button.

It also works correctly from this point on when I select different rows from my Table list (that is, the animator remains closed if it was previously closed, or stays open if it was previously open) and I update the contents of my Panel’s VerticalLayout.

But in FF 3.5.10, it has the same initial behavior, but it never will roll up. Each button press causes the toggling between calls to rollDown() and rollUp(), but the Panel itself always appears as though it’s rolled down.

It has the same always rolled down functionality on Chrome 5 and Safari 5 and Opera 10. Only IE8 seems to be working.

When I create my Form, I create the Panel, create the Animator for the Panel, create the button and then add them both to my Form’s layout:

permPanel = new Panel();
VerticalLayout permPanelLayout = (VerticalLayout)permPanel.getContent();
permPanelLayout.setMargin(false);
permPanelLayout.setSpacing(false);

permPanelAnim = new Animator(permPanel);
permPanelAnim.setRolledUp(true);
permPanelAnim.rollUp(0,0);
permPanelAnim.setWidth(100, UNITS_PERCENTAGE);
permPanelAnim.setImmediate(true);

permPanelButton = new Button("Permissions", new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				if ( permPanelAnim.isRolledUp() ) {
					permPanelAnim.rollDown();
				} else {
					permPanelAnim.rollUp();
				}
			}
		});
permPanelButton.setStyleName(ChameleonTheme.BUTTON_SMALL);
permPanelButton.setVisible(false);

layout.addComponent(permPanelButton);
layout.addComponent(permPanelAnim);

I used both setRolledUp(true) and rollUp(0,0) as attempts to have it be initially considered in the rolled up state, which does seem to be the case, even though when I first put data into the panel, it is visible as though the Panel were rolled down.

When I click on an item in the Table list, my setItemDataSource() basically does the following for the animator after creating 3 TwinColSelects that are stored inside the panel so that the button is visible with a caption that shows my bean’s name, which works as expected:

VerticalLayout permLayout = (VerticalLayout)permPanel.getContent();
// Remove any previous TwinColSelects in my panel's VerticalLayout
permLayout.removeAllComponents();
// add in my new TwinColSelects populated with appropriate data from bean
permLayout.addComponent(permListSelect); 
permLayout.addComponent(permViewDetailsSelect);
permLayout.addComponent(permUpdateSelect);

// Make button visible if not already so....
permPanelButton.setCaption("Open/close " + mybean.getName());
permPanelButton.setVisible(true);

It seems somewhat straightforward to me, but not sure why the other browsers can’t roll up, or why it’s initially shown like it’s rolled down, even though the component itself thinks it’s rolled up.

I did try ?debug option and noted that the layouts appeared to be okay (no errors).

Okay, I found that while ?debug had no layout errors, if I changed my Form (which is embedded in a SplitPanel which is embedding in a TabSheet which is in a SplitPanel which is in a VerticalLayout of the MainWindow) to use setSizeFull() instead of just setWidth(“100%”), then the Animator started to work with the Panel on all my browsers.

But oddly enough, I’d then end up with horizontal scrollbars (odd because 100% width was already set, but adding 100% height then caused horizontal scrollbars, something you’d think would be impacted only by width) no matter how wide I make the browser window. So I reverted to the 98% width hack so it looks normal (though 100% width didn’t show this before 100% height was added to the Form).

However, on the initial view (first item selected and shown in the Form), the Animator Panel continues to be visible even though I try to have it be rolled up. If I open the Form in a new window (instead of the lower part of the SplitPanel with Table list on top), it is rolled up as expected.

So somehow, there’s still some issue on that very first item being selected and the Animator’s status (which believes it is rolled up, though it’s actually visible). Once you click the button to toggle it open/closed, it behaves normally, and as new items are selected, they are shown correctly open/closed. And it works fine if I open the same Form in its own Window rather than in the bottom component of a SplitPanel.

If anybody is interested, I have an Animator+Panel+Button custom component that is not as “simple pretty” as the Drawer, but doesn’t have any issues with the layout, reloads, etc. and includes a hack I found I needed for Animator to work on page reloads, etc. It’s not generalized at all and assumes our needs. And the Fat Cow icon for “right” is just bullet_arrow_up.png rotated 90 degrees to the right (not sure why they didn’t include all directions).

// Open eSignForms - Web-based electronic contracting software
// Copyright (C) 2010 Yozons, Inc.
//
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License along with this program.  
// If not, see http://open.esignforms.com/agpl.txt or http://www.gnu.org/licenses/.
// Contact information is via the public forums at http://open.esignforms.com or via private email to open-esign@yozons.com.
//
package com.esignforms.open.vaadin.widget;

import org.vaadin.jouni.animator.Animator;

import com.vaadin.addon.chameleon.ChameleonTheme;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;

/**
 * A simple component that wraps a button and Animator + Panel for our general ESF use (not generalized).  
 * That is, assumes we're our ESF-based Chameleon Theme, small button, borderless panel, using our Fat Cow icons for the button, etc.
 * 
 * @author Yozons Inc.
 */
public class DisclosurePanel extends CustomComponent {
	private static final long serialVersionUID = 3437640755454758542L;

	static ThemeResource closedIcon = new ThemeResource("icons/fatcow16/bullet_arrow_right.png"); 
	static ThemeResource openIcon = new ThemeResource("icons/fatcow16/bullet_arrow_down.png"); 
	
	VerticalLayout layout;
	Button button;
	Panel panel;
	final Animator animator;
	
	/**
	 * Creates a DisclosurePanel component with no caption on the button, the Panel is "rolled up" (closed - not visible).
	 * CSS style name is 'disclosurePanel' on the CustomComponent level.
	 */
	public DisclosurePanel() {
    	setStyleName("disclosurePanel");
 
    	layout = new VerticalLayout();
    	layout.setMargin(false);
    	layout.setSpacing(false);
    	
		panel = new Panel();
		panel.setStyleName(ChameleonTheme.PANEL_BORDERLESS);
        VerticalLayout panelLayout = (VerticalLayout)panel.getContent();
        panelLayout.setMargin(false);
        panelLayout.setSpacing(false);

        animator = new Animator(panel);
        animator.setRolledUp(true);
        animator.setWidth(100, UNITS_PERCENTAGE);
        animator.setImmediate(true);

        button = new Button("", new Button.ClickListener() {
			private static final long serialVersionUID = 1348946058036802825L;

			public void buttonClick(ClickEvent event) {
				if ( animator.isRolledUp() ) {
					animator.rollDown();
					button.addStyleName("down");
					button.setIcon(openIcon);
					if ( ! panel.isVisible() ) {
						panel.setVisible(true);
					}
				} else {
					animator.rollUp();
					button.removeStyleName("down");
					button.setIcon(closedIcon);
				}
			}
		});
        button.setStyleName(ChameleonTheme.BUTTON_SMALL);
        button.setIcon(closedIcon);

		layout.addComponent(button);
		layout.addComponent(animator);
		
		setCompositionRoot(layout);
    }
    
	/**
	 * Creates a Disclosure panel with the initial setting of the button caption and the specified contents of the panel.
	 * @param buttonCaption the String caption to show for the button
	 * @param panelContents the VerticalPanel initial contents of the Panel
	 */
	public DisclosurePanel(String buttonCaption, VerticalLayout panelContents) {
		this();
		setButtonCaption(buttonCaption);
		setPanelContent(panelContents);
	}
	
	/**
	 * Sets the caption on the button.
	 * @param caption the String caption for the button
	 */
	public void setButtonCaption(String caption) {
		button.setCaption(caption);
	}
	
	/**
	 * Sets the disclosure panel as visible or not.  When visible is turned off, the animator is also rolled up.
	 */
	public void setVisible(boolean v) {
		super.setVisible(v);
		
		// Hack to make appear rolled up on initial load
		if ( animator.isRolledUp() && panel.isVisible() ) {
			panel.setVisible(false);
			button.removeStyleName("down");
			button.setIcon(closedIcon);
		}  

		if ( v ) {
			button.setVisible(true);
		} else {
			button.setVisible(false);
			animator.rollUp(0,0);
		}
	}
	
	/**
	 * Gets the VerticalLayout contents of our panel.
	 * @return the VerticalLayout of our panel.
	 */
	public VerticalLayout getPanelContent() {
		return (VerticalLayout)panel.getContent();
	}

	/**
	 * Sets a new VerticalLayout to use for our panel's content.
	 * @param panelContents the VerticalLayout to use for our panel's content.
	 */
	public void setPanelContent(VerticalLayout panelContents) {
		panel.setContent(panelContents);
	}
}

Hi Jouni,

first of all, thanks for the great component, it’s really easy to use and has great features.

However while testing the fade animation with IE8, I got the problem, that the component does not fade in, but suddenly appears. I get the same result when using the online demo provided with IE8. When I click on the “Fade” Button the text simply appears or dissapears.

Everything works fine in FF though, just as I wanted. And the roll animation works fine in both browsers.

Is this a general problem with IE8?

Greetings

Sebastian

Thanks for noticing. I’m pretty sure I tested it on IE8 as well, but guess not. IE7 and 6 probably work OK.

There seems to be something wrong in GWT so that setting the opacity using GWT’s methods doesn’t affect IE8. I’ll take a look at asap and try to fix it. I have a couple of more updates to the add-on anyhow.

Problem solved, uploaded version 1.5 to the Directory moments ago. GWT should probably fix this in coming releases, but I fixed it to the add-on for now.

Updated the
demo
as well, and added a whole bunch of new animations using the AnimatorProxy component, allowing you to animate even sub-windows. Size animations are probably going to be very handy to some of you as well.

Get the update from the Directory (v.1.5):
Animator add-on
.

I’m trying to see if I can use Disclosure as a replacement for Drawer in my Forms. But maybe I need to take a different approach as well.

Today, when the Form is created, I create the Disclosure. Then when an Item is selected, I create the appropriate layout to show in the Disclosure, populated with data from that Item, then call

disclosure.setContent(gridlayout);
disclosure.setVisible(true);

This only appears to work for the first Item set in the Form. When a subsequent Item is set, the call to disclosure.setContent(gridlayout) takes place, but the Disclosure itself is not updated. It appears that I cannot change the content of the Disclosure based on the Item coming in. Is this a problem, or should my approach be to create a new Disclosure for each Item and replace the Disclosure in my Form’s layout?

I tried adding requestRepaintAll(), but that had no effect.

I then tried recreating the Disclosure each time, and that works, but does require I keep track of the previous so I can either add/replace the component in my Form’s layout.

However, can you make the ‘open’ variable accessible with a “public boolean isOpen() { return open; }” accessor in Disclosure so when I replace the Disclosure, I can open the new one if the previous was open?

Sorry to post yet another item today, but just noted that IE8 is showing an alignment issue with the Disclosure arrow. It seems that FF, Safari, Chrome and Opera show it fine, and your demo site in my IE8 looks fine. When the arrow is “open” (down), nothing is clipped, but it’s still high up.

As far as I know, I don’t put any additional CSS, but I am using your Chameleon Theme (1.0.1) with the “blue” option with Vaadin 6.4.8.

The Disclosure arrow is the “Member” one, with the one below actually from Drawer.

Thoughts on what I might check?

No worries, I’m just happy to hear someone is using the Animator and finds it useful enough to ask for help :slight_smile:

That’s most likely just a CSS problem, and you need to tweak the background-position for the v-disclosure-caption element a bit.

This was caused by an obvious programming error on my part in the Disclosure component. I never tested the setContent method properly, and it didn’t actually change the component to the hierarchy, it just changed the internal variable reference.


Released a new version (1.5.2), now in the Directory
, that fixes the setContent problem. I also added isOpen() mehtod, and made all the private variables protected.

Thank you so much for the impossibly fast turnaround, Jouni.

The setContent() solution works perfectly again.

For the IE8 issue, this seemed to put the arrows in better positions (but the original values are fine on other browsers):
.v-ie8 .v-disclosure-button .v-button-caption { background-position: 2px -35px; } /* was 2px -39px /
.v-ie8 .v-disclosure-button-open .v-button-caption { background-position: -9px -7px; } /
was -9px -11px */

Not sure why, but on FF, I found the caption getting clipped on the bottom (on letter ‘g’), so changed my CSS as follows:
.v-disclosure-button { height: 19px !important; } /* was 18px */

And I switched the style to be more like a link:
.v-disclosure-button .v-button-caption { font-weight: normal; text-decoration: underline; } /* was font-weight: bold */

Ugh! I know you made all the fields protected, so I can subclass to do this, but can you perhaps update Disclosure one more time for a use case that I hadn’t seen yesterday, and that’s the ability to change the caption.

Disclosure.setCaption() right now sets the component’s caption, not the caption of the Button. And there’s no accessor method for the Button to set it directly. So perhaps the following would be great:

  1. String getDisclosureCaption() { return caption.getCaption(); }
  2. setDisclosureCaption(String caption) { caption.setCaption(caption); }

The second is really all I need. I figure giving access to the Button itself could be done, but have no need myself for that and if you are tweaking the button beyond the caption, perhaps subclassing would make sense.

Pretty please! :love: