001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.chameleon.layers;
028:
029: import com.sun.midp.chameleon.*;
030: import javax.microedition.lcdui.*;
031: import com.sun.midp.chameleon.skins.ScrollIndSkin;
032: import com.sun.midp.chameleon.skins.ScreenSkin;
033:
034: /**
035: * Basic layer containing the application area of the display. This layer
036: * contains the current Displayable contents, such as a Form or Canvas.
037: */
038: public class BodyLayer extends CLayer implements ScrollListener {
039:
040: /**
041: * The scroll indicator layer to notify of scroll settings
042: * in case not all content can fit on the menu.
043: */
044: protected ScrollIndLayer scrollInd;
045:
046: ChamDisplayTunnel tunnel;
047:
048: /**
049: * Create a new BodyLayer.
050: *
051: * @param tunnel BodyLayer needs a "tunnel" class to cross the package
052: * protection boundary and access methods inside the
053: * javax.microedition.lcdui package
054: */
055: public BodyLayer(ChamDisplayTunnel tunnel) {
056: this ((Image) null, -1, tunnel);
057: }
058:
059: /**
060: * Create a new BodyLayer with the given background image or color.
061: * If the image is null, the color will be used.
062: *
063: * @param bgImage a background image array to use to render the
064: * background of this layer
065: * @param bgColor a solid background fill color to use if the image
066: * background is null
067: * @param tunnel BodyLayer needs a "tunnel" class to cross the package
068: * protection boundary and access methods inside the
069: * javax.microedition.lcdui package
070: */
071: public BodyLayer(Image bgImage[], int bgColor,
072: ChamDisplayTunnel tunnel) {
073: super (bgImage, bgColor);
074: this .tunnel = tunnel;
075: this .visible = false;
076:
077: setScrollInd(ScrollIndLayer.getInstance(ScrollIndSkin.MODE));
078: }
079:
080: /**
081: * Create a new BodyLayer with the given background image or color.
082: * If the image is null, the color will be used.
083: *
084: * @param bgImage a single background image to use to render the
085: * background of this layer
086: * @param bgColor a solid background fill color to use if the image
087: * background is null
088: * @param tunnel BodyLayer needs a "tunnel" class to cross the package
089: * protection boundary and access methods inside the
090: * javax.microedition.lcdui package
091: */
092: public BodyLayer(Image bgImage, int bgColor,
093: ChamDisplayTunnel tunnel) {
094: super (bgImage, bgColor);
095: this .tunnel = tunnel;
096: this .visible = false;
097: setScrollInd(ScrollIndLayer.getInstance(ScrollIndSkin.MODE));
098: }
099:
100: /**
101: * Toggle the visibility state of this layer within its containing
102: * window.
103: *
104: * @param visible If true, this layer will be painted as part of its
105: * containing window, as well as receive events if it
106: * supports input.
107: */
108: public void setVisible(boolean visible) {
109: boolean oldVis = this .visible;
110: super .setVisible(visible);
111: if (oldVis != visible) {
112: if (scrollInd != null && !visible) {
113: scrollInd.setVisible(visible);
114: } else {
115: updateScrollIndicator();
116: }
117: }
118: }
119:
120: /**
121: * Add this layer's entire area to be marked for repaint. Any pending
122: * dirty regions will be cleared and the entire layer will be painted
123: * on the next repaint.
124: * TODO: need to be removed as soon as removeLayer algorithm
125: * takes into account layers interaction
126: */
127: public void addDirtyRegion() {
128: super .addDirtyRegion();
129: if (scrollInd != null) {
130: scrollInd.addDirtyRegion();
131: }
132: }
133:
134: /**
135: * Mark this layer as being dirty. By default, this would also mark the
136: * containing window (if there is one) as being dirty as well. However,
137: * this parent class behavior is overridden in BodyLayer so as to not
138: * mark the containing window and therefor not require a full
139: * Chameleon repaint when only the application area needs updating.
140: */
141: public void setDirty() {
142: setDirtyButNotNotifyOwner();
143: }
144:
145: /**
146: * Scrolling the contents according to the scrolling parameters.
147: * @param scrollType can be SCROLL_LINEUP, SCROLL_LINEDOWN, SCROLL_PAGEUP,
148: * SCROLL_PAGEDOWN or SCROLL_THUMBTRACK
149: * @param thumbPosition only valid when scrollType is SCROLL_THUMBTRACK
150: *
151: */
152: public void scrollContent(int scrollType, int thumbPosition) {
153: tunnel.callScrollContent(scrollType, thumbPosition);
154: }
155:
156: /**
157: * Called by CWindow to notify the layer that is has been
158: * added to the active stack.
159: */
160: public void addNotify() {
161: if (scrollInd != null && owner != null) {
162: if (owner.addLayer(scrollInd)) {
163: updateScrollIndicator();
164: }
165: }
166: }
167:
168: /**
169: * Called by CWindow to notify the layer that is has been
170: * removed from the active stack.
171: * @param owner an instance of CWindow this layer has been removed from
172: */
173: public void removeNotify(CWindow owner) {
174: if (scrollInd != null && owner != null) {
175: if (owner.removeLayer(scrollInd) && scrollInd.isVisible()) {
176: bounds[W] += scrollInd.bounds[W];
177: }
178: }
179: }
180:
181: public void setScrollInd(ScrollIndLayer newScrollInd) {
182: if (scrollInd != newScrollInd || scrollInd != null
183: && scrollInd.scrollable != this || scrollInd != null
184: && scrollInd.listener != this ) {
185: if (scrollInd != null) {
186: boolean vis = scrollInd.isVisible();
187: scrollInd.setScrollable(null);
188: scrollInd.setListener(null);
189:
190: if (owner != null) {
191: if (owner.removeLayer(scrollInd) && vis) {
192: bounds[W] += scrollInd.bounds[W];
193: addDirtyRegion();
194: }
195: }
196: }
197:
198: scrollInd = newScrollInd;
199: if (scrollInd != null) {
200: scrollInd.setScrollable(this );
201: scrollInd.setListener(this );
202:
203: if (owner != null) {
204: owner.addLayer(scrollInd);
205: }
206: }
207: }
208: updateScrollIndicator();
209: }
210:
211: /**
212: * Updates the scroll indicator.
213: */
214: public void updateScrollIndicator() {
215: tunnel.updateScrollIndicator();
216: }
217:
218: /**
219: * Set the current vertical scroll position and proportion.
220: *
221: * @param scrollPosition vertical scroll position.
222: * @param scrollProportion vertical scroll proportion.
223: * @return true if set vertical scroll occures
224: */
225: public boolean setVerticalScroll(int scrollPosition,
226: int scrollProportion) {
227: if (scrollInd != null) {
228: boolean wasVisible = scrollInd.isVisible();
229: scrollInd.setVerticalScroll(scrollPosition,
230: scrollProportion);
231: boolean scrollVisible = scrollInd.isVisible();
232:
233: if (wasVisible != scrollVisible) {
234: if (scrollVisible) {
235: scrollInd.setBounds();
236: }
237: int w = scrollInd.bounds[W];
238: bounds[W] += scrollVisible ? -w : +w;
239: addDirtyRegion();
240: return true;
241: }
242: }
243: return false;
244: }
245:
246: /**
247: * Paint the contents of this layer. This method is overridden from
248: * the parent class to use the package tunnel to call back into the
249: * javax.microedition.lcdui package and cause the current Displayable
250: * to paint its contents into the body of this layer.
251: *
252: * @param g the Graphics to paint to
253: */
254: protected void paintBody(Graphics g) {
255: if (tunnel != null) {
256: tunnel.callPaint(g);
257: }
258: }
259:
260: /**
261: * Update bounds of layer
262: *
263: * @param layers - current layer can be dependant on this parameter
264: */
265: public void update(CLayer[] layers) {
266: super .update(layers);
267:
268: bounds[W] = ScreenSkin.WIDTH;
269: bounds[H] = ScreenSkin.HEIGHT;
270:
271: if (layers[MIDPWindow.PTI_LAYER] != null
272: && layers[MIDPWindow.PTI_LAYER].isVisible()) {
273: bounds[H] -= layers[MIDPWindow.PTI_LAYER].bounds[H];
274: }
275: if (layers[MIDPWindow.TITLE_LAYER].isVisible()) {
276: bounds[Y] = layers[MIDPWindow.TITLE_LAYER].bounds[H];
277: bounds[H] -= layers[MIDPWindow.TITLE_LAYER].bounds[H];
278: } else {
279: bounds[Y] = 0;
280: }
281: if (layers[MIDPWindow.TICKER_LAYER].isVisible()) {
282: bounds[H] -= layers[MIDPWindow.TICKER_LAYER].bounds[H];
283: }
284: if (layers[MIDPWindow.BTN_LAYER].isVisible()) {
285: bounds[H] -= layers[MIDPWindow.BTN_LAYER].bounds[H];
286: }
287:
288: if (scrollInd != null) {
289: scrollInd.update(layers);
290: if (scrollInd.isVisible()) {
291: bounds[W] -= scrollInd.bounds[W];
292: }
293: }
294: }
295: }
|