001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx.ui;
021 
022 import js.Id;
023 import js.Js;
024 import jsx.ui.event.OnRender;
025 import jsx.ui.event.Render;
026 
027 /**
028  * <p>A base class for control widgets.</p>
029  * 
030  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
031  */
032 public class Control extends Widget implements OnRender
033 {
034     /**
035      * <p>Constructs a control widget.</p>
036      * @param html The HTML of the control widget.
037      * @since 1.0
038      */
039     public Control(String html) {
040         this(new Component(html));
041     }
042 
043     private final static Id<Control> CONTROL = new Id<Control>();
044 
045     /**
046      * <p>Gets the {@link Control} widget associated with a component.</p>
047      * <p>If the specified component does not have an associated {@link Control} widget,
048      * this method will creates one based on that component and associate them.</p>
049      * @param e A component that may have a {@link Control} widget based on it.
050      * @return The {@link Control} widget associated with <tt>e</tt>.
051      * @since 1.0
052      */
053     public static Control get(Component e) {
054         Control c = ini(e).var(CONTROL);
055         return Js.be(c) ? c : new Control(e);
056     }
057 
058     /**
059      * <p>Constructs a control widget.</p>
060      * @param e The underlying component for the widget.
061      * @since 1.0
062      */
063     protected Control(Component e) {
064         super(e);
065         addClasses();
066         if (Js.not(ini(e).var(CONTROL))) {
067             ini(e).var(CONTROL, this);
068             Component.addClass(e, ROUND_CORNER_ALL);
069         }
070         addClasses();
071         if (Js.be(Component.getRendered(e, this))) {
072             init();
073         }
074     }
075 
076     /**
077      * <p>Helps subclasses to cache the controls of a super type.</p>
078      * @param t A control of a subclass.
079      * @param s A control of a superclass.
080      * @param id An {@link Id} for <tt>t</tt> to cache <tt>s</tt>.
081      * @since 1.0
082      */
083     protected static final <S extends Control, T extends S> void sub(S s, T t, Id<T> id) {
084         if (Js.not(ini(s).var(id))) {
085             ini(s).var(id, t);
086         }
087     }
088 
089     /**
090      * <p>Performs an action on the rendering event.</p>
091      * <p>This method creates {@link jsx.ui.css.Pseudo} widgets to associate the browser "focus" 
092      * and "blur" events to the "focus" and "blur" pseudo selectors respectively over the 
093      * underlying HTML element.</p>
094      * @since 1.0
095      */
096     protected void init() {
097         Component c = unwrap();
098         c.pseudo(FOCUS, "focus").attach(c, "focus", "blur");
099         c.pseudo(HOVER, "hover").attach(c, "mouseover", "mouseout");
100     }
101 
102     /**
103      * <p>Performs an action on the dispatched event.</p>
104      * <p>This method simply {@link #init()} this widget and then stops listening to {@link Render} events.</p>
105      * @param evt The event dispatched to this listener.
106      * @since 1.0
107      */
108     public void onEvent(Render evt) {
109         init();
110         unwrap().removeListener(Render.class, this);
111     }
112 }