29f2fb6fca0e640b53ab1f55a400457b989c133c
[jalviewjs.git] / site / j2s / swingjs / plaf / JSMenuItemUI.java
1 package swingjs.plaf;
2
3 //import jsjava.awt.FontMetrics;
4 import jsjava.awt.event.MouseMotionListener;
5 import jsjavax.swing.AbstractButton;
6 import jsjavax.swing.LookAndFeel;
7 import jsjavax.swing.UIManager;
8 import swingjs.api.DOMNode;
9 import jsjavax.swing.plaf.UIResource;
10 /**
11  * SWingJS implementation of stateful user interface for buttons. 
12  * Modeled after javax.swing.plaf.basic.BasicButtonUI.java (commented out below).
13  * 
14  * @author Bob Hanson
15  *
16  */
17 public class JSMenuItemUI extends JSButtonUI {
18
19         
20         /**
21          * the radio or check-box or simple button
22          * 
23          */
24         protected DOMNode domBtn;
25
26         @Override
27         public DOMNode getDOMObject() {
28                 if (domNode == null)
29                         domBtn = enableNode = valueNode = domNode = createDOMObject("input", id,
30                                         "type", "button");
31                 setCssFont(DOMNode.setAttr(domNode, "value", ((AbstractButton) c).getText()),
32                                 c.getFont());
33                 return domNode;
34         }
35
36         /**
37          * validate a button press -- with a simple button, this is just TRUE.
38          * This is needed because sometimes the area near the button is pressed
39          * but not the actual button.
40          * @param isRelease TODO
41          * 
42          * @return true if the HTML5 button was actually pressed
43          */
44   boolean verifyButtonClick(boolean isRelease) {
45                 return true;
46         }
47
48
49         // from BasicButtonUI
50         
51         protected void installJSUI() {
52                 installDefaults((AbstractButton) c);
53                 installListeners((AbstractButton) c);
54                 installKeyboardActions((AbstractButton) c);
55         }
56   
57         protected void uninstallJSUI() {
58                 uninstallKeyboardActions((AbstractButton) c);
59                 uninstallListeners((AbstractButton) c);
60                 //uninstallDefaults((AbstractButton) c);
61         }
62         
63         protected void installListeners(AbstractButton b) {
64                 JSButtonListener listener = new JSButtonListener(b);
65                 if (listener != null) {
66                         b.addMouseListener(listener);
67                         b.addMouseMotionListener(listener);
68                         b.addFocusListener(listener);
69       b.addPropertyChangeListener(listener);
70                         b.addChangeListener(listener);
71                 }
72         }
73
74         protected void uninstallListeners(AbstractButton b) {
75                 JSButtonListener listener = getButtonListener(b);
76                 if (listener != null) {
77                         b.removeMouseListener(listener);
78                         b.removeMouseMotionListener(listener);
79                         b.removeFocusListener(listener);
80                         b.removeChangeListener(listener);
81                         b.removePropertyChangeListener(listener);
82                 }
83         }
84
85         protected void installKeyboardActions(AbstractButton b) {
86                 JSButtonListener listener = getButtonListener(b);
87                 if (listener != null) {
88                         listener.installKeyboardActions(b);
89                 }
90         }
91         
92   protected void uninstallKeyboardActions(AbstractButton b) {
93       JSButtonListener listener = getButtonListener(b);
94       if(listener != null) {
95           listener.uninstallKeyboardActions(b);
96       }
97   }
98
99   // SwingJS -- this is interesting, as it summarizes everything we will need
100   // to implement, ultimately. SwingUtilities.layoutCompoundLabel
101   // details what we are going to have to do somewhere. 
102   
103 //      private String layout(AbstractButton b, FontMetrics fm, int width, int height) {
104 //              Insets i = b.getInsets();
105 //              viewRect.x = i.left;
106 //              viewRect.y = i.top;
107 //              viewRect.width = width - (i.right + viewRect.x);
108 //              viewRect.height = height - (i.bottom + viewRect.y);
109 //
110 //              textRect.x = textRect.y = textRect.width = textRect.height = 0;
111 //              iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
112 //
113 //              // layout the text and icon
114 //              return SwingUtilities.layoutCompoundLabel(b, fm, b.getText(), b.getIcon(),
115 //                              b.getVerticalAlignment(), b.getHorizontalAlignment(),
116 //                              b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect,
117 //                              iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap());
118 //              return null;
119 //      }
120
121
122 //  // Visual constants
123 //  // NOTE: This is not used or set any where. Were we allowed to remove
124 //  // fields, this would be removed.
125 //  protected int defaultTextIconGap;
126 //
127   /** Amount to offset text, the value of this comes from
128    defaultTextShiftOffset once setTextShiftOffset has been invoked.
129    */
130   protected int shiftOffset = 0;
131         
132   /** Value that is set in shiftOffset once setTextShiftOffset has been
133    invoked. The value of this comes from the defaults table.
134    */
135   protected int defaultTextShiftOffset;
136 //
137 //protected String propertyPrefix = "Button.";
138 //  
139 //  private static final Object BASIC_BUTTON_UI_KEY = new Object();
140 //
141 //  // ********************************
142 //  //          Create PLAF
143 //  // ********************************
144 //  public static ComponentUI createUI(JComponent c) {
145 //      AppContext appContext = AppContext.getAppContext();
146 //      BasicButtonUI buttonUI = 
147 //              (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);
148 //      if (buttonUI == null) {
149 //          buttonUI = new BasicButtonUI();
150 //          appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);
151 //      }
152 //      return buttonUI;
153 //  }
154 //
155   protected String getPropertyPrefix() {
156       return "Button.";
157   }
158 //
159 //
160 //  // ********************************
161 //  //          Install PLAF
162 //  // ********************************
163 //  public void installUI(JComponent c) {
164 //      installDefaults((AbstractButton) c);
165 //      installListeners((AbstractButton) c);
166 //      installKeyboardActions((AbstractButton) c);
167 //      BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());
168 //  }
169 //
170   protected void installDefaults(AbstractButton b) {
171       // load shared instance defaults
172       String pp = getPropertyPrefix();
173
174       defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
175
176 //      // set the following defaults on the button
177 //      if (b.isContentAreaFilled()) {
178 //          LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
179 //      } else {
180 //          LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
181 //      }
182
183       if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {
184           b.setMargin(UIManager.getInsets(pp + "margin"));
185       }
186
187       LookAndFeel.installColorsAndFont(b, pp + "background",
188                                        pp + "foreground", pp + "font");
189 //      LookAndFeel.installBorder(b, pp + "border");
190 //
191 //      Object rollover = UIManager.get(pp + "rollover");
192 //      if (rollover != null) {
193 //          LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
194 //      }
195       LookAndFeel.installProperty(b, "iconTextGap", new Integer(4));
196   }
197 //
198 //  protected void installListeners(AbstractButton b) {
199 //      JSButtonListener listener = createButtonListener(b);
200 //      if(listener != null) {
201 //          b.addMouseListener(listener);
202 //          b.addMouseMotionListener(listener);
203 //          b.addFocusListener(listener);
204 //          b.addPropertyChangeListener(listener);
205 //          b.addChangeListener(listener);
206 //      }
207 //  }
208 //
209 //  protected void installKeyboardActions(AbstractButton b){
210 //      JSButtonListener listener = getButtonListener(b);
211 //
212 //      if(listener != null) {
213 //          listener.installKeyboardActions(b);
214 //      }
215 //  }
216 //
217 //
218 //  // ********************************
219 //  //         Uninstall PLAF
220 //  // ********************************
221 //  public void uninstallUI(JComponent c) {
222 //      uninstallKeyboardActions((AbstractButton) c);
223 //      uninstallListeners((AbstractButton) c);
224 //      uninstallDefaults((AbstractButton) c);
225 //      BasicHTML.updateRenderer(c, "");
226 //  }
227 //
228 //  protected void uninstallKeyboardActions(AbstractButton b) {
229 //      JSButtonListener listener = getButtonListener(b);
230 //      if(listener != null) {
231 //          listener.uninstallKeyboardActions(b);
232 //      }
233 //  }
234 //
235 //  protected void uninstallListeners(AbstractButton b) {
236 //      JSButtonListener listener = getButtonListener(b);
237 //      if(listener != null) {
238 //          b.removeMouseListener(listener);
239 //          b.removeMouseMotionListener(listener);
240 //          b.removeFocusListener(listener);
241 //          b.removeChangeListener(listener);
242 //          b.removePropertyChangeListener(listener);
243 //      }
244 //  }
245 //
246 //  protected void uninstallDefaults(AbstractButton b) {
247 //      LookAndFeel.uninstallBorder(b);
248 //  }
249 //
250 //  // ********************************
251 //  //        Create Listeners
252 //  // ********************************
253 //  protected JSButtonListener createButtonListener(AbstractButton b) {
254 //      return new JSButtonListener(b);
255 //  }
256 //
257 //  public int getDefaultTextIconGap(AbstractButton b) {
258 //      return defaultTextIconGap;
259 //  }
260 //
261 //  /* These rectangles/insets are allocated once for all
262 //   * ButtonUI.paint() calls.  Re-using rectangles rather than
263 //   * allocating them in each paint call substantially reduced the time
264 //   * it took paint to run.  Obviously, this method can't be re-entered.
265 //   */
266 //  private static Rectangle viewRect = new Rectangle();
267 //  private static Rectangle textRect = new Rectangle();
268 //  private static Rectangle iconRect = new Rectangle();
269 //
270 //  // ********************************
271 //  //          Paint Methods
272 //  // ********************************
273 //
274 //  public void paint(Graphics g, JComponent c)
275 //  {
276 //      AbstractButton b = (AbstractButton) c;
277 //      ButtonModel model = b.getModel();
278 //
279 //      String text = layout(b, SwingUtilities2.getFontMetrics(b, g),
280 //             b.getWidth(), b.getHeight());
281 //
282 //      clearTextShiftOffset();
283 //
284 //      // perform UI specific press action, e.g. Windows L&F shifts text
285 //      if (model.isArmed() && model.isPressed()) {
286 //          paintButtonPressed(g,b);
287 //      }
288 //
289 //      // Paint the Icon
290 //      if(b.getIcon() != null) {
291 //          paintIcon(g,c,iconRect);
292 //      }
293 //
294 //      if (text != null && !text.equals("")){
295 //          View v = (View) c.getClientProperty(BasicHTML.propertyKey);
296 //          if (v != null) {
297 //              v.paint(g, textRect);
298 //          } else {
299 //              paintText(g, b, textRect, text);
300 //          }
301 //      }
302 //
303 //      if (b.isFocusPainted() && b.hasFocus()) {
304 //          // paint UI specific focus
305 //          paintFocus(g,b,viewRect,textRect,iconRect);
306 //      }
307 //  }
308 //
309 //  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){
310 //          AbstractButton b = (AbstractButton) c;
311 //          ButtonModel model = b.getModel();
312 //          Icon icon = b.getIcon();
313 //          Icon tmpIcon = null;
314 //
315 //          if(icon == null) {
316 //             return;
317 //          }
318 //
319 //          Icon selectedIcon = null;
320 //
321 //          /* the fallback icon should be based on the selected state */
322 //          if (model.isSelected()) {
323 //              selectedIcon = (Icon) b.getSelectedIcon();
324 //              if (selectedIcon != null) {
325 //                  icon = selectedIcon;
326 //              }
327 //          }
328 //
329 //          if(!model.isEnabled()) {
330 //              if(model.isSelected()) {
331 //                 tmpIcon = (Icon) b.getDisabledSelectedIcon();
332 //                 if (tmpIcon == null) {
333 //                     tmpIcon = selectedIcon;
334 //                 }
335 //              }
336 //
337 //              if (tmpIcon == null) {
338 //                  tmpIcon = (Icon) b.getDisabledIcon();
339 //              }
340 //          } else if(model.isPressed() && model.isArmed()) {
341 //              tmpIcon = (Icon) b.getPressedIcon();
342 //              if(tmpIcon != null) {
343 //                  // revert back to 0 offset
344 //                  clearTextShiftOffset();
345 //              }
346 //          } else if(b.isRolloverEnabled() && model.isRollover()) {
347 //              if(model.isSelected()) {
348 //                 tmpIcon = (Icon) b.getRolloverSelectedIcon();
349 //                 if (tmpIcon == null) {
350 //                     tmpIcon = selectedIcon;
351 //                 }
352 //              }
353 //
354 //              if (tmpIcon == null) {
355 //                  tmpIcon = (Icon) b.getRolloverIcon();
356 //              }
357 //          }
358 //
359 //          if(tmpIcon != null) {
360 //              icon = tmpIcon;
361 //          }
362 //
363 //          if(model.isPressed() && model.isArmed()) {
364 //              icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),
365 //                      iconRect.y + getTextShiftOffset());
366 //          } else {
367 //              icon.paintIcon(c, g, iconRect.x, iconRect.y);
368 //          }
369 //
370 //  }
371 //
372 //  /**
373 //   * As of Java 2 platform v 1.4 this method should not be used or overriden.
374 //   * Use the paintText method which takes the AbstractButton argument.
375 //   */
376 //  protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
377 //      AbstractButton b = (AbstractButton) c;
378 //      ButtonModel model = b.getModel();
379 //      FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
380 //      int mnemonicIndex = b.getDisplayedMnemonicIndex();
381 //
382 //      /* Draw the Text */
383 //      if(model.isEnabled()) {
384 //          /*** paint the text normally */
385 //          g.setColor(b.getForeground());
386 //          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
387 //                                        textRect.x + getTextShiftOffset(),
388 //                                        textRect.y + fm.getAscent() + getTextShiftOffset());
389 //      }
390 //      else {
391 //          /*** paint the text disabled ***/
392 //          g.setColor(b.getBackground().brighter());
393 //          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
394 //                                        textRect.x, textRect.y + fm.getAscent());
395 //          g.setColor(b.getBackground().darker());
396 //          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
397 //                                        textRect.x - 1, textRect.y + fm.getAscent() - 1);
398 //      }
399 //  }
400 //
401 //  /**
402 //   * Method which renders the text of the current button.
403 //   * <p>
404 //   * @param g Graphics context
405 //   * @param b Current button to render
406 //   * @param textRect Bounding rectangle to render the text.
407 //   * @param text String to render
408 //   * @since 1.4
409 //   */
410 //  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
411 //      paintText(g, (JComponent)b, textRect, text);
412 //  }
413 //
414 //  // Method signature defined here overriden in subclasses.
415 //  // Perhaps this class should be abstract?
416 //  protected void paintFocus(Graphics g, AbstractButton b,
417 //                            Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
418 //  }
419 //
420 //
421 //
422 //  protected void paintButtonPressed(Graphics g, AbstractButton b){
423 //  }
424 //
425 //  protected void clearTextShiftOffset(){
426 //      this.shiftOffset = 0;
427 //  }
428 //
429 //  protected void setTextShiftOffset(){
430 //      this.shiftOffset = defaultTextShiftOffset;
431 //  }
432 //
433 //  protected int getTextShiftOffset() {
434 //      return shiftOffset;
435 //  }
436 //
437 //  // ********************************
438 //  //          Layout Methods
439 //  // ********************************
440 //  public Dimension getMinimumSize(JComponent c) {
441 //      Dimension d = getPreferredSize(c);
442 //      View v = (View) c.getClientProperty(BasicHTML.propertyKey);
443 //      if (v != null) {
444 //          d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
445 //      }
446 //      return d;
447 //  }
448 //
449 //  public Dimension getPreferredSize(JComponent c) {
450 //      AbstractButton b = (AbstractButton)c;
451 //      return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());
452 //  }
453 //
454 //  public Dimension getMaximumSize(JComponent c) {
455 //      Dimension d = getPreferredSize(c);
456 //      View v = (View) c.getClientProperty(BasicHTML.propertyKey);
457 //      if (v != null) {
458 //          d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
459 //      }
460 //      return d;
461 //  }
462 //
463 //  /**
464 //   * Returns the baseline.
465 //   *
466 //   * @throws NullPointerException {@inheritDoc}
467 //   * @throws IllegalArgumentException {@inheritDoc}
468 //   * @see javax.swing.JComponent#getBaseline(int, int)
469 //   * @since 1.6
470 //   */
471 //  public int getBaseline(JComponent c, int width, int height) {
472 //      super.getBaseline(c, width, height);
473 //      AbstractButton b = (AbstractButton)c;
474 //      String text = b.getText();
475 //      if (text == null || "".equals(text)) {
476 //          return -1;
477 //      }
478 //      FontMetrics fm = b.getFontMetrics(b.getFont());
479 //      layout(b, fm, width, height);
480 //      return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),
481 //                                   textRect.width, textRect.height);
482 //  }
483 //
484 //  /**
485 //   * Returns an enum indicating how the baseline of the component
486 //   * changes as the size changes.
487 //   *
488 //   * @throws NullPointerException {@inheritDoc}
489 //   * @see javax.swing.JComponent#getBaseline(int, int)
490 //   * @since 1.6
491 //   */
492 //  public Component.BaselineResizeBehavior getBaselineResizeBehavior(
493 //          JComponent c) {
494 //      super.getBaselineResizeBehavior(c);
495 //      if (c.getClientProperty(BasicHTML.propertyKey) != null) {
496 //          return Component.BaselineResizeBehavior.OTHER;
497 //      }
498 //      switch(((AbstractButton)c).getVerticalAlignment()) {
499 //      case AbstractButton.TOP:
500 //          return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
501 //      case AbstractButton.BOTTOM:
502 //          return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
503 //      case AbstractButton.CENTER:
504 //          return Component.BaselineResizeBehavior.CENTER_OFFSET;
505 //      }
506 //      return Component.BaselineResizeBehavior.OTHER;
507 //  }
508 //
509 //  private String layout(AbstractButton b, FontMetrics fm,
510 //                        int width, int height) {
511 //      Insets i = b.getInsets();
512 //      viewRect.x = i.left;
513 //      viewRect.y = i.top;
514 //      viewRect.width = width - (i.right + viewRect.x);
515 //      viewRect.height = height - (i.bottom + viewRect.y);
516 //
517 //      textRect.x = textRect.y = textRect.width = textRect.height = 0;
518 //      iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
519 //
520 //      // layout the text and icon
521 //      return SwingUtilities.layoutCompoundLabel(
522 //          b, fm, b.getText(), b.getIcon(),
523 //          b.getVerticalAlignment(), b.getHorizontalAlignment(),
524 //          b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
525 //          viewRect, iconRect, textRect,
526 //          b.getText() == null ? 0 : b.getIconTextGap());
527 //  }
528 //
529 //  /**
530 //   * Returns the ButtonListener for the passed in Button, or null if one
531 //   * could not be found.
532 //   */
533 //  private JSButtonListener getButtonListener(AbstractButton b) {
534 //      MouseMotionListener[] listeners = b.getMouseMotionListeners();
535 //
536 //      if (listeners != null) {
537 //          for (int counter = 0; counter < listeners.length; counter++) {
538 //              if (listeners[counter] instanceof JSButtonListener) {
539 //                  return (JSButtonListener)listeners[counter];
540 //              }
541 //          }
542 //      }
543 //      return null;
544 //  }
545 //
546 //
547
548 }