001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Dmitry A. Durnev
019: * @version $Revision$
020: */package org.apache.harmony.awt.theme;
021:
022: import java.awt.Color;
023: import java.awt.Dimension;
024: import java.awt.Graphics;
025: import java.awt.Point;
026: import java.awt.Polygon;
027: import java.awt.Rectangle;
028: import java.awt.SystemColor;
029: import java.awt.image.BufferedImage;
030:
031: import org.apache.harmony.awt.state.ScrollbarState;
032:
033: /**
034: * Implementation of Scrollbar's default visual style
035: */
036: public class DefaultScrollbar extends DefaultStyle {
037: static final int BUTTON_SIZE = 15;
038: static final int MIN_SLIDER_SIZE = 7;
039:
040: static final int NORTH = 1;
041: static final int EAST = 3;
042: static final int SOUTH = 5;
043: static final int WEST = 7;
044:
045: private static final Color trackHighlightColor = SystemColor.controlDkShadow;;
046: private static final Color arrowColor = Color.BLACK;
047: private static final Color focusColor = SystemColor.controlDkShadow;
048:
049: public static void draw(Graphics g, ScrollbarState s) {
050: Dimension size = s.getSize();
051: Color bkColor = s.isBackgroundSet() ? s.getBackground()
052: : SystemColor.scrollbar;
053: g.setColor(bkColor);
054: g.fillRect(0, 0, size.width, size.height);
055:
056: boolean vertical = s.isVertical();
057:
058: Rectangle btn1Rect = s.getDecreaseRect();
059: if (btn1Rect == null) {
060: return;
061: }
062: Rectangle btn2Rect = s.getIncreaseRect();
063: if (btn2Rect == null) {
064: return;
065: }
066: int dir1 = (vertical ? NORTH : WEST);
067: int dir2 = (vertical ? SOUTH : EAST);
068: boolean btn1Pressed = s.isDecreasePressed();
069: boolean btn2Pressed = s.isIncreasePressed();
070:
071: g.translate(btn1Rect.x, btn1Rect.y);
072: paintArrowButton(g, dir1, btn1Rect.width, btn1Rect.height,
073: btn1Pressed, s.isEnabled());
074: g.translate(-btn1Rect.x, -btn1Rect.y);
075: g.translate(btn2Rect.x, btn2Rect.y);
076: paintArrowButton(g, dir2, btn2Rect.width, btn2Rect.height,
077: btn2Pressed, s.isEnabled());
078: g.translate(-btn2Rect.x, -btn2Rect.y);
079: drawSlider(g, s);
080: paintHighlight(g, s);
081: }
082:
083: private static void paintFocus(Graphics g, Rectangle sliderRect) {
084: sliderRect.grow(-2, -2);
085: BufferedImage img = new BufferedImage(sliderRect.width,
086: sliderRect.height, BufferedImage.TYPE_INT_ARGB);
087: for (int x = 0; x < sliderRect.width; x++) {
088: for (int y = x & 1; y < sliderRect.height; y += 2) {
089: img.setRGB(x, y, focusColor.getRGB());
090: }
091: }
092: g.drawImage(img, sliderRect.x, sliderRect.y, null);
093:
094: }
095:
096: private static void paintHighlight(Graphics g, ScrollbarState s) {
097: Color oldColor = g.getColor();
098: g.setColor(trackHighlightColor);
099: switch (s.getHighlight()) {
100: case ScrollbarState.NO_HIGHLIGHT:
101: break;
102: case ScrollbarState.INCREASE_HIGHLIGHT:
103: paintIncreaseHighlight(g, s);
104: break;
105: case ScrollbarState.DECREASE_HIGHLIGHT:
106: paintDecreaseHighlight(g, s);
107: break;
108: }
109: g.setColor(oldColor);
110:
111: }
112:
113: private static void paintDecreaseHighlight(Graphics g,
114: ScrollbarState s) {
115: Rectangle r = s.getUpperTrackBounds();
116: g.fillRect(r.x, r.y, r.width, r.height);
117:
118: }
119:
120: private static void paintIncreaseHighlight(Graphics g,
121: ScrollbarState s) {
122: Rectangle r = s.getLowerTrackBounds();
123: g.fillRect(r.x, r.y, r.width, r.height);
124:
125: }
126:
127: private static void drawSlider(Graphics g, ScrollbarState s) {
128: if (!s.isEnabled()) {
129: return;
130: }
131: Rectangle sliderRect = s.getSliderRect();
132: if ((sliderRect == null) || sliderRect.isEmpty()) {
133: return;
134: }
135: g.translate(sliderRect.x, sliderRect.y);
136:
137: DefaultButton.drawButtonFrame(g, sliderRect, false);
138: g.translate(-sliderRect.x, -sliderRect.y);
139: if (s.isFocused()) {
140: paintFocus(g, new Rectangle(sliderRect));
141: }
142:
143: }
144:
145: public static void calculate(ScrollbarState s) {
146: int dim1 = BUTTON_SIZE + 1;
147: int dim2 = 3 * dim1 + 2;
148: Dimension scrollbarSize = (s.isVertical() ? new Dimension(dim1,
149: dim2) : new Dimension(dim2, dim1));
150: s.setDefaultMinimumSize(scrollbarSize);
151: }
152:
153: static void paintArrowButton(final Graphics g, int dir, int w,
154: int h, boolean pressed, boolean enabled) {
155:
156: DefaultButton.drawButtonFrame(g, new Rectangle(0, 0, w, h),
157: pressed);
158: boolean vert = (dir == NORTH) || (dir == SOUTH);
159: int w1 = Math.min(w, BUTTON_SIZE + 1);
160: int h1 = Math.min(h, BUTTON_SIZE + 1);
161: int arrowW = vert ? w1 / 2 : w1 / 3;
162: int arrowH = vert ? h1 / 3 : h1 / 2;
163: int x = (w - arrowW) / 2;
164: int y = (h - arrowH) / 2;
165: paintTriangle(g, x, y, arrowW, arrowH, dir, enabled);
166: }
167:
168: static void paintTriangle(final Graphics g, final int x,
169: final int y, final int w, final int h, final int direction,
170: final boolean isEnabled) {
171: Color oldColor = g.getColor();
172:
173: int xCenter = x + w / 2;
174: int xMax = x + w;
175: int yMax = y + h;
176: int yCenter = y + h / 2;
177: switch (direction) {
178: case NORTH:
179: paintTriangle(g, new int[] { xMax, x, xCenter }, new int[] {
180: yMax, yMax, y }, isEnabled);
181: break;
182: case SOUTH:
183: paintTriangle(g, new int[] { xMax, xCenter, x }, new int[] {
184: y, yMax, y }, isEnabled);
185: break;
186: case WEST:
187: paintTriangle(g, new int[] { xMax, xMax, x }, new int[] {
188: y, yMax, yCenter }, isEnabled);
189: break;
190: case EAST:
191: paintTriangle(g, new int[] { x, xMax, x }, new int[] {
192: yMax, yCenter, y }, isEnabled);
193: break;
194: }
195:
196: g.setColor(oldColor);
197: }
198:
199: private static void paintTriangle(final Graphics g, final int[] x,
200: final int[] y, final boolean isEnabled) {
201:
202: g.setColor(isEnabled ? arrowColor : SystemColor.controlShadow);
203: g.fillPolygon(new Polygon(x, y, x.length));
204: if (!isEnabled) {
205: g.setColor(SystemColor.controlHighlight);
206: int x1 = x[0] + 1;
207: int y1 = y[0] + 1;
208: int x2 = x[1] + 1;
209: int y2 = y[1] + 1;
210: g.drawLine(x1, y1, x2, y2);
211: }
212:
213: }
214:
215: private static int getSize(Dimension dim, boolean vert) {
216: return (vert ? dim.height : dim.width);
217: }
218:
219: public static void layout(ScrollbarState s) {
220: Dimension size = s.getSize();
221: Rectangle buttonRect = new Rectangle(new Point(0, 0), size);
222: boolean vert = s.isVertical();
223:
224: if (vert) {
225: buttonRect.height = Math.min(BUTTON_SIZE, size.height / 2);
226: } else {
227: buttonRect.width = Math.min(BUTTON_SIZE, size.width / 2);
228: }
229:
230: Rectangle dnButtonRect = new Rectangle(buttonRect);
231: if (vert) {
232: dnButtonRect.y = size.height - dnButtonRect.height;
233: } else {
234: dnButtonRect.x = size.width - dnButtonRect.width;
235: }
236: s.setIncreaseRect(dnButtonRect);
237: s.setDecreaseRect(buttonRect);
238: layoutSlider(s);
239:
240: }
241:
242: private static void layoutSlider(ScrollbarState s) {
243: boolean vertical = s.isVertical();
244: Dimension btnSize = s.getIncreaseRect().getSize();
245: int buttonSize = getSize(btnSize, vertical);
246: int size = getSize(s.getSize(), vertical);
247: float scrollSize = calculateTrackBounds(s);
248: if ((int) scrollSize < MIN_SLIDER_SIZE) {
249: // don't draw slider if there's not enough space
250: s.setSliderRect(new Rectangle());
251: return;
252: }
253: float scale = scrollSize / s.getScrollSize();
254: int sliderSize = Math.max(MIN_SLIDER_SIZE, Math.round(s
255: .getSliderSize()
256: * scale));
257: int sliderPos = buttonSize
258: + Math.round(s.getSliderPosition() * scale);
259: sliderPos = Math.min(sliderPos, size - buttonSize
260: - MIN_SLIDER_SIZE);
261: int sliderPosX = 0, sliderPosY = 0;
262: if (vertical) {
263: sliderPosY = sliderPos;
264: } else {
265: sliderPosX = sliderPos;
266: }
267: int w = vertical ? btnSize.width : sliderSize;
268: int h = vertical ? sliderSize : btnSize.height;
269:
270: Rectangle sliderRect = new Rectangle(sliderPosX, sliderPosY, w,
271: h);
272: s.setSliderRect(sliderRect);
273: setUpperTrack(s);
274: setLowerTrack(s);
275:
276: }
277:
278: private static void setLowerTrack(ScrollbarState s) {
279: boolean v = s.isVertical();
280: Rectangle sliderRect = s.getSliderRect();
281: Rectangle trackRect = s.getTrackBounds();
282: int trackWidth = trackRect.width;
283: int trackHeight = trackRect.height;
284: int sliderPosX = sliderRect.x;
285: int sliderPosY = sliderRect.y;
286: int thumbRight = sliderPosX + sliderRect.width;
287: int thumbBottom = sliderPosY + sliderRect.height;
288:
289: Rectangle incrRect = s.getIncreaseRect();
290: int x = (v ? 0 : thumbRight + 1);
291: int y = (v ? thumbBottom + 1 : 0);
292: int w = (v ? trackWidth : trackWidth - thumbRight
293: + incrRect.width);
294: int h = (v ? trackHeight - thumbBottom + incrRect.height
295: : trackHeight - 1);
296: s.setLowerTrackBounds(new Rectangle(x, y, w, h));
297:
298: }
299:
300: private static void setUpperTrack(ScrollbarState s) {
301: Rectangle trackBounds = s.getTrackBounds();
302: int trackWidth = trackBounds.width;
303: int trackHeight = trackBounds.height;
304: int decrButtonWidth = s.getDecreaseRect().width;
305: int decrButtonHeight = s.getDecreaseRect().height;
306: Rectangle sliderRect = s.getSliderRect();
307: int sliderPosX = sliderRect.x;
308: int sliderPosY = sliderRect.y;
309: boolean v = s.isVertical();
310: int x = (v ? 0 : trackBounds.x);
311: int y = (v ? trackBounds.y : 0);
312: int w = (v ? trackWidth : sliderPosX - decrButtonWidth);
313: int h = (v ? sliderPosY - decrButtonHeight : trackHeight - 1);
314: s.setUpperTrackBounds(new Rectangle(x, y, w, h));
315:
316: }
317:
318: private static float calculateTrackBounds(ScrollbarState s) {
319: Dimension scrollbarSize = s.getSize();
320: Dimension btnSize = s.getIncreaseRect().getSize();
321: boolean vertical = s.isVertical();
322: int size = getSize(scrollbarSize, vertical);
323: int buttonSize = getSize(btnSize, vertical);
324: double scrollSize = size - 2. * buttonSize;
325: s.setTrackSize((int) scrollSize);
326: int btnWidth = btnSize.width;
327: int btnHeight = btnSize.height;
328: int trackX = vertical ? 0 : buttonSize;
329: int trackY = vertical ? buttonSize : 0;
330: int trackW = vertical ? btnWidth : (int) scrollSize;
331: int trackH = vertical ? (int) scrollSize : btnHeight;
332: s.setTrackBounds(new Rectangle(trackX, trackY, trackW, trackH));
333: return (float) scrollSize;
334: }
335: }
|