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.Function;
023 import js.Id;
024 import js.Initializer;
025 import js.Js;
026 import js.ObjectLike;
027 import js.Static;
028 import js.Var;
029 import jsx.TaskManager;
030 import jsx.client.Browser;
031 import jsx.client.Win;
032 import jsx.dom.Elements;
033 import jsx.dom.Styles;
034 import jsx.event.Handle;
035 import jsx.ui.event.OnResize;
036 import jsx.ui.event.Resize;
037 import jsx.ui.event.Style;
038 
039 /**
040  * <p>Defines the view port of the current HTML document.</p>
041  * <p>A view port is a {@link Box} that fits the HTML <tt>&lt;body&gt;</tt> element.</p>
042  * 
043  * @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>
044  */
045 public final class Viewport extends Box<Widget>
046 {
047     /**
048      * <p>Gets the view port of the current HTML document.</p>
049      * @return The view port. If it does not exist, creates one and returns 
050      * it.
051      * @since 1.0
052      */
053     public static final Viewport get() {
054         return SINGLETON.var();
055     }
056 
057     /**
058      * <p>Hides <tt>overflow</tt> of the underlying HTML element of the view port.</p>
059      * <p>If running in JS Simulation mode and IE, this method sets the <tt>overflow</tt> 
060      * style of the underlying HTML element of the view port to "hidden". 
061      * It is useful to remove the right scroll bar of the browser window for IE.</p>
062      * @since 1.0
063      */
064     public static final void hideOverflow() {
065         if (!Js.debug() || Browser.canInsertHTML) {
066             ObjectLike p = new Initializer().var();
067             Styles.overflow(p, "hidden");
068             Elements.applyStyle(
069                     Component.getHTMLElement(get().unwrap()),
070                     p
071             ); 
072         }
073     }
074 
075     private static Var<Viewport> SINGLETON = new Static<Viewport>(
076             new Var<Viewport>() {
077                 @Override
078                 public Viewport var() {
079                     return new Viewport(Component.body());
080                 }
081             }
082     );
083 
084     private Viewport(final Component e) {
085         super(e);
086     }
087 
088     private static class View extends Container implements OnResize
089     {
090         private View(Component e) {
091             super(e);
092             fit(e);
093             addListener(Resize.class, this);
094             new Handle(
095                     Js.win(),
096                     "resize",
097                     new Function<Void>() {
098                         @Override
099                         protected Void function(Object jsthis, Call<Void> callee) {
100                             fire(new Resize(), DISPATCHER.var());
101                             return null;
102                         }
103                     }.var(),
104                     false
105             ).attach();
106         }
107 
108         public void onEvent(Resize evt) {
109             fit(unwrap());
110             unwrap().exec(new Style());
111         }
112 
113         private final static Var<TaskManager> DISPATCHER = new Static<TaskManager>(
114                 new Var<TaskManager>() {
115                     @Override
116                     public TaskManager var() {
117                         return new TaskManager();
118                     }
119                 }
120         );
121 
122         private static final void fit(Component e) {
123             ObjectLike p = new Initializer().var();
124             Styles.width (p, Styles.px(Win.clientWidth ()));
125             Styles.height(p, Styles.px(Win.clientHeight()));
126             Component.applyStyle(e, p);
127         }
128     }
129 
130     private final static Id<Container> VIEW = new Id<Container>();
131 
132     /**
133      * <p>Gets the container for the system view port.</p>
134      * @return The container for the system view port.
135      * @since 1.0
136      */
137     public final Container getContainer() {
138         Container v = ini(this).var(VIEW);
139         if (Js.not(v)) {
140             Component c = Component.div();
141             Component.appendChild(unwrap(), c);
142             v = new View(c);
143             ini(this).var(VIEW, v);
144         }
145         return v;
146     }
147 }