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 javax.microedition.lcdui;
028:
029: import com.sun.midp.log.Logging;
030: import com.sun.midp.log.LogChannels;
031: import com.sun.midp.chameleon.layers.ScrollBarLayer;
032: import com.sun.midp.chameleon.skins.ScreenSkin;
033:
034: /**
035: * This is the look &s; feel implementation for Screen.
036: */
037: class ScreenLFImpl extends DisplayableLFImpl {
038:
039: // ************************************************************
040: // public methods
041: // ************************************************************
042:
043: /**
044: * Override DisplayableLFImpl.lCallHide() to set local variables.
045: */
046: void lCallHide() {
047: // NOTE that resetToTop is also set to false
048: // Display.setCurrentItem() is called.
049: // Because of that just knowing current state of DisplayLF
050: // is not enough to set it properly in lCallShow.
051: // That is why it has to be updated in lCallHide and lCallFreeze
052: super .lCallHide();
053: }
054:
055: /**
056: * Override DisplayableLFImpl.lCallFreeze() to set local variables.
057: */
058: void lCallFreeze() {
059: if (state == SHOWN) {
060: resetToTop = false;
061: }
062: super .lCallFreeze();
063: }
064:
065: // ************************************************************
066: // package private methods
067: // ************************************************************
068:
069: /**
070: * Creates ScreenLF for the passed in screen.
071: * @param screen the Screen object associated with this look&feel
072: */
073: ScreenLFImpl(Screen screen) {
074:
075: super (screen);
076:
077: viewable = new int[4];
078: viewable[X] = 0;
079: viewable[Y] = 0;
080: viewable[WIDTH] = 0;
081: viewable[HEIGHT] = 0;
082: }
083:
084: /**
085: * Paint the contents of this Screen
086: *
087: * @param g the Graphics to paint to
088: * @param target the target Object of this repaint
089: */
090: public void uCallPaint(Graphics g, Object target) {
091: if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
092: Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI,
093: "Screen:Clip: " + g.getClipX() + "," + g.getClipY()
094: + "," + g.getClipWidth() + ","
095: + g.getClipHeight());
096: }
097: }
098:
099: /**
100: * Set the vertical scroll position and proportion
101: *
102: * @param scrollPosition The vertical scroll position to set on a
103: * scale of 0-100
104: * @param scrollProportion The vertical scroll proportion to set on
105: * a scale of 0-100. For example, if the viewport
106: * is 25 pixels high and the Displayable is 100
107: * pixels high, then the scroll proportion would
108: * be 25, since only 25% of the Displayable can
109: * be viewed at any one time. This proportion
110: * value can be used by implementations which
111: * render scrollbars to indicate scrollability
112: * to the user.
113: */
114: boolean setVerticalScroll(int scrollPosition, int scrollProportion) {
115: this .vScrollPosition = scrollPosition;
116: this .vScrollProportion = scrollProportion;
117:
118: if (lIsShown()) {
119: return currentDisplay.setVerticalScroll(scrollPosition,
120: scrollProportion);
121: }
122: return false;
123: }
124:
125: /**
126: * Get the current vertical scroll position
127: *
128: * @return int The vertical scroll position on a scale of 0-100
129: */
130: public int getVerticalScrollPosition() {
131: // SYNC NOTE: return of atomic value
132: return vScrollPosition;
133: }
134:
135: /**
136: * Get the current vertical scroll proportion
137: *
138: * @return ing The vertical scroll proportion on a scale of 0-100
139: */
140: public int getVerticalScrollProportion() {
141: // SYNC NOTE: return of atomic value
142: return vScrollProportion;
143: }
144:
145: /**
146: * Set the vertical scroll indicators for this Screen
147: */
148: void setVerticalScroll() {
149:
150: if (viewable[HEIGHT] <= viewport[HEIGHT]) {
151: setVerticalScroll(0, 100);
152: } else {
153: setVerticalScroll(
154: (viewable[Y] * 100 / (viewable[HEIGHT] - viewport[HEIGHT])),
155: (viewport[HEIGHT] * 100 / viewable[HEIGHT]));
156: }
157: }
158:
159: /**
160: * Paint an Item contained in this Screen. The Item requests a paint
161: * in its own coordinate space. Screen translates those coordinates
162: * into the overall coordinate space and schedules the repaint
163: *
164: * @param item the Item requesting the repaint
165: * @param x the x-coordinate of the origin of the dirty region
166: * @param y the y-coordinate of the origin of the dirty region
167: * @param w the width of the dirty region
168: * @param h the height of the dirty region
169: */
170: void lRequestPaintItem(Item item, int x, int y, int w, int h) {
171:
172: ItemLFImpl iLF = (ItemLFImpl) item.getLF();
173:
174: lRequestPaint(iLF.bounds[X] - viewable[X] + x, iLF.bounds[Y]
175: - viewable[Y] + y, w, h);
176: }
177:
178: /**
179: * Perform a page flip in the given direction. This method will
180: * attempt to scroll the view to show as much of the next page
181: * as possible.
182: *
183: * @param dir the direction of the flip, either DOWN or UP
184: */
185: protected void uScrollViewport(int dir) {
186: int newY = viewable[Y];
187: switch (dir) {
188: case Canvas.UP:
189: newY -= lGetHeight() - getScrollAmount();
190: if (newY < 0) {
191: newY = 0;
192: }
193: break;
194: case Canvas.DOWN:
195: newY += lGetHeight() - getScrollAmount();
196: int max = getMaxScroll();
197: if (newY > max) {
198: newY = max;
199: }
200: break;
201: default:
202: break;
203: }
204: viewable[Y] = newY;
205: }
206:
207: /**
208: * Perform a line scrolling in the given direction. This method will
209: * attempt to scroll the view to show next/previous line.
210: *
211: * @param dir the direction of the flip, either DOWN or UP
212: */
213: protected void uScrollByLine(int dir) {
214: int newY = viewable[Y];
215: if (dir == Canvas.UP) {
216: newY -= getScrollAmount();
217: if (newY < 0) {
218: newY = 0;
219: }
220: } else if (dir == Canvas.DOWN) {
221: newY += getScrollAmount();
222: int max = getMaxScroll();
223: if (newY > max) {
224: newY = max;
225: }
226: }
227: viewable[Y] = newY;
228: }
229:
230: /**
231: * Perform a scrolling at the given position.
232: * @param context position
233: */
234: protected void uScrollAt(int position) {
235: int max = getMaxScroll();
236: int newY = max * position / 100;
237: if (newY < 0) {
238: newY = 0;
239: } else if (newY > max) {
240: newY = max;
241: }
242: viewable[Y] = newY;
243: }
244:
245: /**
246: * The maximum amount of scroll needed to see all the contents
247: * @return get the maximum scroll amount
248: */
249: protected int getMaxScroll() {
250: return viewable[HEIGHT] - viewport[HEIGHT];
251: }
252:
253: /**
254: * This is the number of pixels left from the previous "page"
255: * when a page up or down occurs. The same value is used for line by
256: * line scrolling
257: * @return the number of pixels.
258: */
259: protected int getScrollAmount() {
260: return ScreenSkin.SCROLL_AMOUNT;
261: }
262:
263: /**
264: * Scroll content inside of the form.
265: * @param scrollType scrollType. Scroll type can be one of the following
266: * @see ScrollBarLayer.SCROLL_NONE
267: * @see ScrollBarLayer.SCROLL_PAGEUP
268: * @see ScrollBarLayer.SCROLL_PAGEDOWN
269: * @see ScrollBarLayer.SCROLL_LINEUP
270: * @see ScrollBarLayer.SCROLL_LINEDOWN or
271: * @see ScrollBarLayer.SCROLL_THUMBTRACK
272: * @param thumbPosition
273: */
274: public void uCallScrollContent(int scrollType, int thumbPosition) {
275: if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
276: Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI,
277: "Screen.uCallScrollContent scrollType="
278: + scrollType + " thumbPosition="
279: + thumbPosition);
280: }
281: int oldY = viewable[Y];
282:
283: switch (scrollType) {
284: case ScrollBarLayer.SCROLL_PAGEUP:
285: uScrollViewport(Canvas.UP);
286: break;
287: case ScrollBarLayer.SCROLL_PAGEDOWN:
288: uScrollViewport(Canvas.DOWN);
289: break;
290: case ScrollBarLayer.SCROLL_LINEUP:
291: uScrollByLine(Canvas.UP);
292: break;
293: case ScrollBarLayer.SCROLL_LINEDOWN:
294: uScrollByLine(Canvas.DOWN);
295: break;
296: case ScrollBarLayer.SCROLL_THUMBTRACK:
297: uScrollAt(thumbPosition);
298: break;
299: default:
300: break;
301: }
302: if (oldY != viewable[Y]) {
303: uRequestPaint();
304: setupScroll();
305: }
306: }
307:
308: /**
309: * all scroll actions should be handled through here.
310: *
311: */
312: void setupScroll() {
313: if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
314: Logging.report(Logging.INFORMATION,
315: LogChannels.LC_HIGHUI_FORM_LAYOUT,
316: "[F] >> in FormLFImpl - setupScroll "
317: + invalidScroll + "[F] >> viewable[Y] == "
318: + viewable[Y] + " lastScrollPosition] == "
319: + lastScrollPosition
320: + "[F] >> viewable[HEIGHT] == "
321: + viewable[HEIGHT] + " lastScrollSize == "
322: + lastScrollSize);
323: }
324:
325: // check if scroll moves, and if so, refresh scrollbars
326: if (!invalidScroll
327: && (viewable[Y] != lastScrollPosition || (lastScrollSize != 0 && viewable[HEIGHT]
328: + viewport[HEIGHT] != lastScrollSize))) {
329:
330: lastScrollPosition = viewable[Y];
331: lastScrollSize = viewport[HEIGHT] >= viewable[HEIGHT] ? 0
332: : viewable[HEIGHT] + viewport[HEIGHT];
333:
334: invalidScroll = true;
335: // IMPL_NOTE: mark Items for repaint. -au
336: }
337:
338: if (invalidScroll) {
339: if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
340: Logging.report(Logging.INFORMATION,
341: LogChannels.LC_HIGHUI_FORM_LAYOUT,
342: "[F] ## invalidScroll ");
343: }
344:
345: // draw the scrollbars
346: setVerticalScroll();
347:
348: invalidScroll = false;
349: }
350: }
351:
352: // **************************************************************
353:
354: // ************************************************************
355: // public member variables - NOT ALLOWED in this class
356: // ************************************************************
357:
358: // ************************************************************
359: // protected member variables - NOT ALLOWED in this class
360: // ************************************************************
361:
362: // ************************************************************
363: // package private member variables
364: // ************************************************************
365:
366: /**
367: * An array which holds the scroll location and
368: * the overall dimensions of the view being
369: * shown in the parent Displayable's viewport
370: * Note that the following is always true.
371: * 0 <= viewable[X] <= viewable[WIDTH] - viewport[WIDTH]
372: * 0 <= viewable[Y] <= viewable[HEIGHT] - viewport[HEIGHT]
373: */
374: int viewable[];
375:
376: /**
377: * Screens should automatically reset to the top of the when
378: * they are shown, except in cases where it is interrupted by
379: * a system menu or an off-screen editor - in which case it
380: * should be reshown exactly as it was.
381: */
382: boolean resetToTop = true;
383:
384: // ************************************************************
385: // private member variables
386: // ************************************************************
387:
388: /** The vertical scroll position */
389: private int vScrollPosition = 0;
390:
391: /** The vertical scroll proportion */
392: private int vScrollProportion = 100;
393:
394: /**
395: * Used in setupScroll in order to determine if scroll is needed
396: */
397: private int lastScrollPosition = -1;
398:
399: /**
400: * Used in setupScroll in order to determine if scroll is needed.
401: * The value has no meaning for the actual scroll size
402: */
403: private int lastScrollSize = -1;
404:
405: // ************************************************************
406: // Static initializer, constructor
407: // ************************************************************
408: }
|