Saturday, July 16, 2011

Sliding doors button

And now for something completely different, well not really, just a more technical post...
I wanted to share a small widget I created after my long battle with the rounded corner button.
I did not invent anything here, just borrowed some techniques from here and there to propose a small improvement to the sliding doors technique.
You can find many explanations on the sliding doors, I personally liked this post.
The sliding doors technique requires that you add a span element “inside” your button and put the button’s text in it, this way you can use 2 different images as backgrounds to the button and the span (a left and right parts of a button image) that slide one over the other.
What was missing now was a nice wrap so I don’t need to put my text on a span element in an html.
While looking for a solution I stumbled upon this great post on button with image, the button there has exactly what I need, it puts it’s text on an inner span element.
So I used it to create my “EasySkinnableButton”, here is what I did:
public class SkinnableButton extends Button{
    private String text;
    private Element span;
    public SkinnableButton() {
        span = DOM.createElement("span");
        DOM.insertChild(getElement(), span, 0);
    }
    @Override
    public void setText(String text){
        this.text = text;
        span.setInnerText(text);
    }
    @Override
    public String getText() {
        return this.text;
    }
}

The css part:
.gwt-Button span {
    background: transparent url(images/slidingdoors_button_left.png) no-repeat top left;
    display: block;
    line-height: 22px;
    padding: 1px 0 3px 12px;
    color: #fff;
    border-style: none;
}
.gwt-Button {
    background: transparent url(images/slidingdoors_button_right.png) no-repeat top right;
    display: block;
    float: right;
    height: 24px;
    margin-right: 15px;
    padding: 0px 10px;
    text-decoration: none;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    font-weight: bold;
    border-style: none;
}
.gwt-Button:hover span {
    background-position: 0 -24px;
}
.gwt-Button:hover {
    background-position: right -24px;
}
.gwt-Button:focus span {
    background-position: 0 -48px;
}
.gwt-Button:focus {
    background-position: right -48px;
}
.gwt-Button:active span {
    background-position: 0 -72px;
}
.gwt-Button:active {
    background-position: right -72px;
}
.gwt-Button:disabled span {
    background-position: 0 -96px;
}
.gwt-Button:disabled {
    background-position: right -96px;
}

when used in a ui binder xml it looks like this:
<button:EasySkinnableButton text=”Tada!”/>

Instead of:
<button:Button><span>Tada !</span></button:Button>

You can also use it programmatically by just calling “button.setTex()”
Here are the images: