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 Pavel Dolgov
019: * @version $Revision$
020: */package org.apache.harmony.awt.theme;
021:
022: import java.awt.Dimension;
023: import java.awt.Font;
024: import java.awt.FontMetrics;
025: import java.awt.Graphics;
026: import java.awt.Point;
027: import java.awt.SystemColor;
028:
029: import org.apache.harmony.awt.state.MenuItemState;
030: import org.apache.harmony.awt.state.MenuState;
031:
032: /**
033: * Implementation of Menu's default visual style
034: */
035:
036: public class DefaultMenu {
037:
038: static final int spacing = 3;
039: static final int verticalPadding = 2;
040: static final int separatorHeight = 4;
041: static final int separatorMargin = 1;
042:
043: public static void drawMenu(MenuState s, Graphics gr) {
044:
045: int w = s.getWidth(), h = s.getHeight();
046:
047: gr.setColor(SystemColor.menu);
048: gr.fillRect(0, 0, w, h);
049: gr.setColor(SystemColor.controlShadow);
050: gr.drawRect(0, 0, w - 1, h - 1);
051:
052: Font f = s.getFont();
053: FontMetrics fm = s.getFontMetrics(f);
054: int itemHeight = fm.getHeight();
055: int y = spacing;
056:
057: int leftMargin = itemHeight / 4;
058: int rightMargin = itemHeight / 4;
059: int checkMarkWidth = itemHeight;
060:
061: gr.setFont(f);
062: for (int index = 0; index < s.getItemCount(); index++) {
063:
064: MenuItemState is = s.getItem(index);
065: String label = is.getText();
066: if (!label.equals("-")) { //$NON-NLS-1$
067: int dy = verticalPadding * 2 + itemHeight;
068: y += dy;
069:
070: if (!is.isEnabled()) {
071: gr.setColor(SystemColor.textInactiveText);
072: } else if (index == s.getSelectedItemIndex()) {
073: gr.setColor(SystemColor.textHighlight);
074: gr.fillRect(spacing, y - dy, w - 2 * spacing, dy);
075: gr.setColor(SystemColor.textHighlightText);
076:
077: } else {
078: gr.setColor(SystemColor.menuText);
079: }
080:
081: gr.drawString(label, leftMargin + spacing
082: + checkMarkWidth, y - verticalPadding
083: - fm.getDescent());
084:
085: if (is.isMenu()) {
086: int sz = dy / 4;
087: int base = y - dy / 2 - 1;
088: int dx = w - spacing - rightMargin - sz - 2;
089: int px[] = new int[] { dx, dx + sz, dx };
090: int py[] = new int[] { base - sz, base, base + sz };
091: gr.fillPolygon(px, py, px.length);
092: }
093: if (is.isChecked()) {
094: int sz = dy / 6;
095: int dx = spacing + sz + leftMargin;
096: int base = y - verticalPadding - fm.getDescent();
097:
098: int px[] = new int[] { dx, dx - sz, dx - sz, dx,
099: dx + 2 * sz - 1, dx + 2 * sz - 1 };
100: int py[] = new int[] { base, base - sz,
101: base - 2 * sz, base - sz,
102: base - 3 * sz + 1, base - 2 * sz + 1 };
103: gr.fillPolygon(px, py, px.length);
104: }
105: } else {
106: // separator
107: int dy = verticalPadding * 2 + separatorHeight;
108: y += dy;
109: int base = y - dy / 2 - 1;
110: int margin = separatorMargin + spacing;
111: gr.setColor(SystemColor.controlShadow);
112: gr.drawLine(margin, base, w - margin - 1, base);
113: gr.setColor(SystemColor.controlHighlight);
114: gr.drawLine(margin, base + 1, w - margin - 1, base + 1);
115: }
116: }
117:
118: }
119:
120: public static Dimension calculateSize(MenuState s) {
121:
122: Font f = s.getFont();
123: FontMetrics fm = s.getFontMetrics(f);
124: int itemHeight = fm.getHeight();
125: int h = spacing;
126: int w = 0;
127:
128: int leftMargin = itemHeight / 4;
129: int rightMargin = itemHeight / 4;
130: int checkMarkWidth = itemHeight;
131: int arrowSpaceWidth = itemHeight + rightMargin;
132:
133: for (int index = 0; index < s.getItemCount(); index++) {
134:
135: int dx = 0, dy = 0;
136: MenuItemState is = s.getItem(index);
137: String label = is.getText();
138: if (!label.equals("-")) { //$NON-NLS-1$
139: dy = verticalPadding * 2 + itemHeight;
140: dx = fm.stringWidth(label);
141: } else {
142: // separator
143: dy = verticalPadding * 2 + separatorHeight;
144: dx = 2 * separatorMargin;
145: }
146: h += dy;
147: w = Math.max(w, dx);
148: is.setItemBounds(spacing, h - dy, w - 2 * spacing, dy);
149: }
150: h += spacing;
151: w += spacing + checkMarkWidth + leftMargin + rightMargin
152: + arrowSpaceWidth + spacing;
153:
154: for (int index = 0; index < s.getItemCount(); index++) {
155: MenuItemState is = s.getItem(index);
156: is.getItemBounds().width = w;
157: }
158:
159: return new Dimension(w, h);
160: }
161:
162: public static int getItemIndex(MenuState s, Point p) {
163:
164: if (p.x < spacing || p.x >= s.getWidth() - spacing) {
165: return -1;
166: }
167:
168: Font f = s.getFont();
169: FontMetrics fm = s.getFontMetrics(f);
170: int itemHeight = fm.getHeight();
171: int y = spacing;
172:
173: for (int index = 0; index < s.getItemCount(); index++) {
174:
175: String label = s.getItem(index).getText();
176: if (!label.equals("-")) { //$NON-NLS-1$
177: int dy = verticalPadding * 2 + itemHeight;
178: if ((p.y <= y + dy) && (p.y > y)) {
179: return index;
180: }
181: y += dy;
182: } else {
183: // separator
184: int dy = verticalPadding * 2 + separatorHeight;
185: y += dy;
186: }
187: }
188:
189: return -1;
190: }
191:
192: public static Point getItemLocation(MenuState s, int index) {
193: if (index < 0 || index >= s.getItemCount()) {
194: return new Point(-1, -1);
195: }
196:
197: Font f = s.getFont();
198: FontMetrics fm = s.getFontMetrics(f);
199: int itemHeight = fm.getHeight();
200: int y = spacing;
201:
202: for (int i = 0; i < index; i++) {
203:
204: String label = s.getItem(i).getText();
205: if (!label.equals("-")) { //$NON-NLS-1$
206: int dy = verticalPadding * 2 + itemHeight;
207: y += dy;
208: } else {
209: // separator
210: int dy = verticalPadding * 2 + separatorHeight;
211: y += dy;
212: }
213: }
214:
215: int margin = spacing + itemHeight / 4;
216:
217: Point location = s.getLocation();
218: Point result = new Point(location);
219: result.translate(s.getWidth() - margin, y - spacing);
220: // TODO: ajust position according to sumbenu size
221: return result;
222: }
223:
224: }
|