001: /*
002: * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
003: * NETSCAPE COMMUNICATIONS CORPORATION
004: *
005: * Copyright (c) 1996 Netscape Communications Corporation.
006: * All Rights Reserved.
007: * Use of this Source Code is subject to the terms of the applicable
008: * license agreement from Netscape Communications Corporation.
009: *
010: * ==> MCW 07/97 <==
011: */
012: package graphical;
013:
014: import graphical.MouseOverTextField;
015:
016: import netscape.application.*;
017: import netscape.util.*;
018:
019: import com.indius.base.IBorderView;
020: import com.indius.grid.IGridRowEditView;
021: import com.indius.base.IntVector;
022: import com.indius.grid.SimpleGrid;
023:
024: /**
025: * MouseOverGridView extends IGridRowSelectView to implement:
026: * popup help for any cell
027: * "URL cell support, ie.e display as a "link"
028: */
029:
030: public class MouseOverGridView extends IGridRowEditView implements
031: Target {
032:
033: private int mouseRow;
034: private int mouseColumn;
035: private int cellRow;
036: private int cellColumn;
037:
038: private InternalWindow popupWindow;
039: private MouseOverTextField popupView;
040: private Font popupViewFont;
041: private Timer popupTimer;
042: private FontMetrics popupViewFontMetrics;
043: private boolean popupAlwaysFlag = true;
044: private int popupDelayValue = 1000;
045: private int popdownDelayValue = 3000;
046:
047: private int m_urlRow = -1;
048: private int m_urlColumn = -1;
049: private Color m_urlColor = Color.blue;
050:
051: private int m_dragRow = -1; // Drag row for drag feedback
052:
053: private int m_iconColumn = -1;
054: private Image m_normalIcon = null;
055: private Image m_selectedIcon = null;
056:
057: /**
058: * MouseOverGridView constructor, creates grid and initializes popup
059: * system.
060: */
061:
062: public MouseOverGridView(int x, int y, int w, int h) {
063: super (x, y, w, h);
064: popupWindow = new InternalWindow(Window.BLANK_TYPE, 0, 0, 0, 0);
065: popupWindow.setLayer(InternalWindow.POPUP_LAYER);
066:
067: popupViewFont = new Font("Helvetica", Font.PLAIN, 12);
068: popupViewFontMetrics = popupViewFont.fontMetrics();
069:
070: popupView = new MouseOverTextField(Messages.CMD_MOUSEDOWN, this );
071: popupView.setBackgroundColor(new Color(255, 255, 225));
072: popupView.setTextColor(Color.black);
073: popupView.setFont(popupViewFont);
074: popupView.setEditable(false);
075: popupWindow.addSubview(popupView);
076:
077: popupTimer = new Timer(this , "popupTimer", popupDelayValue);
078: }
079:
080: /**
081: * mouseDown - Mouse down event handler, destroy any popup window
082: */
083:
084: public boolean mouseDown(MouseEvent mouseEvent) {
085: hidePopup();
086: return super .mouseDown(mouseEvent);
087: }
088:
089: /**
090: * mouseMoved - Mouse move event handler, if mouse is over a new
091: * cell the popup function is called, otherwise the event is just
092: * passed on.
093: */
094:
095: public void mouseMoved(MouseEvent mouseEvent) {
096: super .mouseMoved(mouseEvent);
097:
098: if ((mouseEvent.y == mouseRow) && (mouseEvent.x == mouseColumn)) {
099: return;
100: }
101:
102: mouseRow = mouseEvent.y;
103: mouseColumn = mouseEvent.x;
104:
105: if (popdownDelayValue == 0) {
106: hidePopup();
107: }
108:
109: int r = locateRow(mouseRow, 0);
110: int c = locateColumn(mouseColumn, 0);
111:
112: if ((r == cellRow) && (c == cellColumn)) {
113: return;
114: }
115:
116: cellRow = r;
117: cellColumn = c;
118:
119: onMouseOverCell(cellRow, cellColumn, mouseRow, mouseColumn);
120: }
121:
122: /**
123: * onMouseOverCell - Mouse is over a grid cell. The current popup, if any,
124: * is removed. If there is no popup delay, the popup is displayed. Otherwise
125: * a timer is started.
126: */
127:
128: public void onMouseOverCell(int cellRow, int cellColumn,
129: int mouseRow, int mouseColumn) {
130: popupTimer.stop();
131:
132: if (popupDelayValue == 0) {
133: drawPopup();
134: } else {
135: popupTimer.setCommand("popupTimer");
136: popupTimer.setInitialDelay(popupDelayValue);
137: popupTimer.start();
138: }
139: }
140:
141: /**
142: * drawPopup - Get cell coordinates and check that the mouse is really over
143: * the cell. This is necessary as the grid locate functions return the last
144: * cell when the mouse is off the bottom of the grid. Stop the popup timer,
145: * if any. Get the contents of the cell and size it in the current font.
146: * Check that size exceeds cell size or that always popup is on. Size popup
147: * window and view for string and show the popup window. Start the popdown
148: * timer, if any.
149: */
150:
151: public void drawPopup() {
152: Rect cellRect = cellRect(cellRow, cellColumn);
153: popupWindow.hide();
154:
155: if (cellColumn == 0) {
156: return; // No popup over drag icon column
157: }
158:
159: if (cellRect.contains(mouseColumn, mouseRow) == false) {
160: cellRow = cellColumn = -1;
161: return;
162: }
163:
164: popupTimer.stop();
165:
166: Object popupValueObject = grid().getValue(cellRow, cellColumn);
167: String popupValueString = popupValueObject.toString();
168: Size popupValueSize = popupViewFontMetrics
169: .stringSize(popupValueString);
170:
171: if (popupAlwaysFlag == false) {
172: if ((popupValueSize.width < (cellRect.width - 7))
173: && (popupValueSize.height < cellRect.height)) {
174: hidePopup();
175: return;
176: }
177: }
178:
179: cellRect.width = popupValueSize.width + 10;
180: cellRect.height = popupValueSize.height + 5;
181:
182: convertRectToView(null, cellRect, cellRect);
183:
184: popupWindow.setBounds(cellRect);
185: popupWindow.show();
186: popupView.sizeTo(cellRect.width, cellRect.height);
187:
188: popupView.setStringValue(popupValueString);
189:
190: if (popdownDelayValue != 0) {
191: popupTimer.setCommand("popdownTimer");
192: popupTimer.setInitialDelay(popdownDelayValue);
193: popupTimer.start();
194: }
195: }
196:
197: /**
198: * hidePopup - Stop any timers. Hide the window. Reset current cell and row
199: * so that the mouse move handler detects a new cell.
200: */
201:
202: public void hidePopup() {
203: popupTimer.stop();
204:
205: popupWindow.hide();
206:
207: cellRow = cellColumn = -1;
208: }
209:
210: /**
211: * performCommand - Message handling for popup and popdown timers.
212: */
213:
214: public void performCommand(String command, Object arg) {
215: if ("popupTimer".equals(command)) {
216: drawPopup();
217: }
218:
219: if ("popdownTimer".equals(command)) {
220: hidePopup();
221: }
222:
223: if (Messages.CMD_MOUSEDOWN.equals(command)) {
224: deleteGridCellEditor(true);
225: unselectAll();
226: select(cellRow);
227: hidePopup();
228: }
229: }
230:
231: /**
232: * popupFont - Return the current font.
233: */
234:
235: public Font popupFont() {
236: return popupViewFont;
237: }
238:
239: /**
240: * setPopupFont - Set the current font.
241: */
242:
243: public void setPopupFont(Font font) {
244: popupViewFont = font;
245: popupViewFontMetrics = popupViewFont.fontMetrics();
246: }
247:
248: /**
249: * popupBackgroundColor - Return the current bacjground color.
250: */
251:
252: public Color popupBackgroundColor() {
253: return popupView.backgroundColor();
254: }
255:
256: /**
257: * setPopupBackgroundColor - Set the current background color.
258: */
259:
260: public void setPopupBackgroundColor(Color color) {
261: popupView.setBackgroundColor(color);
262: }
263:
264: /**
265: * popupTextColor - Return the current text color.
266: */
267:
268: public Color popupTextColor() {
269: return popupView.textColor();
270: }
271:
272: /**
273: * setPopupTextColor - Set the current text color.
274: */
275:
276: public void setPopupTextColor(Color color) {
277: popupView.setTextColor(color);
278: }
279:
280: /**
281: * popupAlways - Return the current state of the always popup flag.
282: */
283:
284: public boolean popupAlways() {
285: return popupAlwaysFlag;
286: }
287:
288: /**
289: * setPopupAlways - Set the current state of the always popup flag.
290: */
291:
292: public void setPopupAlways(boolean flag) {
293: popupAlwaysFlag = flag;
294: }
295:
296: /**
297: * popupDelay - Return the current popup delay, in milliseconds.
298: */
299: public int popupDelay() {
300: return popupDelayValue;
301: }
302:
303: /**
304: * setPopupDelay - Set the popup delay value, in milliseconds.
305: */
306:
307: public void setPopupDelay(int delay) {
308: popupDelayValue = delay;
309: }
310:
311: /**
312: * popdownDelay - Return the current popupdown delay, in milliseconds.
313: */
314:
315: public int popdownDelay() {
316: return popdownDelayValue;
317: }
318:
319: /**
320: * setPopdownDelay - Set the current popdown delay value, in milliseconds.
321: */
322:
323: public void setPopdownDelay(int delay) {
324: popdownDelayValue = delay;
325: }
326:
327: /**
328: * urlColumn - Return the current URL Column.
329: */
330:
331: public int urlColumn() {
332: return m_urlColumn;
333: }
334:
335: /**
336: * urlRow - Return the current URL Row.
337: */
338:
339: public int urlRow() {
340: return m_urlRow;
341: }
342:
343: /**
344: * setUrlColumn - Set the current URL column.
345: */
346:
347: public void setUrlColumn(int c) {
348: m_urlColumn = c;
349: }
350:
351: /**
352: * setUrlRow - Set the current URL row.
353: */
354:
355: public void setUrlRow(int r) {
356: m_urlRow = r;
357: }
358:
359: /**
360: * setUrlRowColumn - Set the current URL row/column.
361: */
362:
363: public void setUrlRowColumn(int r, int c) {
364: m_urlRow = r;
365: m_urlColumn = c;
366: }
367:
368: /**
369: * urlColor - Return the current URL Color.
370: */
371:
372: public Color urlColor() {
373: return m_urlColor;
374: }
375:
376: /**
377: * iconColumn - Return the current Icon column.
378: */
379:
380: public int iconColumn() {
381: return m_iconColumn;
382: }
383:
384: /**
385: * setIconColumn - Set the current Icon column.
386: */
387:
388: public void setIconColumn(int c) {
389: m_iconColumn = c;
390: }
391:
392: /**
393: * normalIcon - Return the normal Icon.
394: */
395:
396: public Image normalIcon() {
397: return m_normalIcon;
398: }
399:
400: /**
401: * setNormalIcon - Set the normal (unselected) Icon.
402: */
403:
404: public void setNormalIcon(Image icon) {
405: m_normalIcon = icon;
406: }
407:
408: /**
409: * selectedIcon - Return the selected Icon.
410: */
411:
412: public Image selectedIcon() {
413: return m_selectedIcon;
414: }
415:
416: /**
417: * setSelectedIcon - Set the selected Icon.
418: */
419:
420: public void setSelectedIcon(Image icon) {
421: m_selectedIcon = icon;
422: }
423:
424: /**
425: * setUrlColor - Set the current URL color.
426: */
427:
428: public void setUrlColor(Color color) {
429: m_urlColor = color;
430: }
431:
432: /**
433: * setDragRow - Set the current Drag over row.
434: * This is used for drag feedback.
435: */
436:
437: public void setDragRow(int r) {
438: m_dragRow = r;
439: }
440:
441: /**
442: * textColor override - Returns URL link color, if URL column.
443: */
444:
445: public Color textColor(int r, int c) {
446:
447: boolean urlCell = false;
448:
449: if (m_urlRow == -1) {
450: if (c == m_urlColumn) {
451: urlCell = true;
452: }
453: } else {
454: if ((r == m_urlRow) && (c == m_urlColumn)) {
455: urlCell = true;
456: }
457: }
458:
459: if (urlCell == true) {
460: return m_urlColor;
461: }
462:
463: return super .textColor(r, c);
464: }
465:
466: /**
467: * paintCellForeground override - Underlines URL link.
468: */
469: public void paintCellForeground(Graphics g, int r, int c, Rect rect) {
470: super .paintCellForeground(g, r, c, rect);
471:
472: boolean urlCell = false;
473:
474: if (m_urlRow == -1) {
475: if (c == m_urlColumn) {
476: urlCell = true;
477: }
478: } else {
479: if ((r == m_urlRow) && (c == m_urlColumn)) {
480: urlCell = true;
481: }
482: }
483:
484: if (urlCell == true) {
485: /*
486: * Draw the underline. There is a lot of fudging going on here
487: * as I don't know the location of the text within the cell
488: * rectangle.
489: */
490:
491: FontMetrics textMetrics = font().fontMetrics();
492: Rect ulRect = new Rect();
493:
494: ulRect.x = rect.x + 4;
495: ulRect.y = rect.y + textMetrics.ascent() + 3;
496: ulRect.width = Math
497: .min((rect.width - 3), (textMetrics
498: .stringWidth(grid().getValue(r, c)
499: .toString()) + 3));
500: ulRect.height = 2;
501: g.drawRect(ulRect);
502: return;
503: }
504:
505: if ((r == m_dragRow) && // Dragging over row
506: (c == m_iconColumn)) {
507: // Draw selected icon for drag feedback.
508: m_selectedIcon.drawCentered(g, rect);
509: return;
510: }
511:
512: if (c == m_iconColumn) {
513: // Draw selected or normal image based on selection state.
514: if (isSelected(r) == true) {
515: m_selectedIcon.drawCentered(g, rect);
516:
517: } else {
518: m_normalIcon.drawCentered(g, rect);
519: }
520:
521: return;
522: }
523: }
524:
525: /**
526: * paintCellBackground override - Fixes drag refresh not painting selected row
527: * background in the correct color.
528: */
529: public void paintCellBackground(Graphics g, int r, int c, Rect rect) {
530:
531: int srCount = selectedRowCount();
532:
533: if (srCount == 0) { // No selected rows!
534: super .paintCellBackground(g, r, c, rect);
535: return;
536: }
537:
538: IntVector sr = selectedRows();
539:
540: for (int i = 0; i < srCount; i++) { // Loop thru selected rows
541: if (selectedRow(i) == r) { // A selected row!
542: g.setColor(selectBackgroundColor());
543: g.fillRect(rect); // Draw selected color background
544: return;
545: }
546: }
547:
548: super .paintCellBackground(g, r, c, rect);
549: }
550:
551: /**
552: * onPressCell override - Invokes the browser with the contents of a
553: * URL link cell.
554: */
555: public void onPressCell(int r, int c) {
556:
557: boolean urlCell = false;
558:
559: if (m_urlRow == -1) {
560: if (c == m_urlColumn) {
561: urlCell = true;
562: }
563: } else {
564: if ((r == m_urlRow) && (c == m_urlColumn)) {
565: urlCell = true;
566: }
567: }
568:
569: if (urlCell == true) {
570: // Show URL in the RD_Viewer Navigator window. It will be created if
571: // it does not exist. Subsequent requests will use the existing window
572: // rather than keep creating new ones.
573: graphical.Header.showDocument(grid().getValue(r, c)
574: .toString(), "RD_Viewer");
575: }
576:
577: super.onPressCell(r, c);
578: }
579: }
|