Package org.sf.feeling.swt.win32.extension.widgets

Source Code of org.sf.feeling.swt.win32.extension.widgets.CButton

package org.sf.feeling.swt.win32.extension.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Pattern;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.sf.feeling.swt.win32.extension.graphics.GraphicsUtil;
import org.sf.feeling.swt.win32.extension.widgets.theme.GeneralThemeRender;
import org.sf.feeling.swt.win32.extension.widgets.theme.GlossyThemeRender;
import org.sf.feeling.swt.win32.extension.widgets.theme.OfficeThemeRender;
import org.sf.feeling.swt.win32.extension.widgets.theme.ThemeRender;
import org.sf.feeling.swt.win32.internal.extension.graphics.GCExtension;

public class CButton extends CAbstractButton {

  private static final int SUBMENUWIDTH = 11;

  private static final int HORIZON_MARGIN = 5, VERTICAL_MARGIN = 2;

  private static final int DRAW_FLAGS = SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;

  public void setTheme(ThemeRender theme) {
    if (isDisposed()) return;
    if (!GraphicsUtil.checkGdip() && theme instanceof GlossyThemeRender) return;
    this.theme = theme;
  }

  public CButton(Composite parent, int style, ThemeRender theme) {
    super(parent, style);
    setTheme(theme);
  
    addPaintListener(new PaintListener() {
      public void paintControl(PaintEvent e) {
        onPaint(e);
      }
    });
    addMouseMoveListener(new MouseMoveListener() {
      public void mouseMove(MouseEvent e) {
        handleMouseMoveEvent(new Point(e.x, e.y));
      }
    });

    addMouseTrackListener(new MouseTrackAdapter() {
      @SuppressWarnings("unused")
      public void mouseExit(MouseEvent e) {
        menuTracked = false;
        selected = false;
        redraw();
      }
    });

    addMouseListener(new MouseAdapter() {
      @SuppressWarnings("unused")
      public void mouseDown(MouseEvent e) {
        if(!isEnabled()) return;
        if (!selected) {
          selected = true;
          redraw();
        }
      }
      @SuppressWarnings("unused")
      public void mouseUp(MouseEvent e) {
        if(!isEnabled()) return;
        if (selected) {
          if (isEnabled()) {
            Event event = new Event();
            event.widget = CButton.this;
            event.data = this;
            event.type = SWT.SELECTED;
            fireSelectionEvent(event);
            Display.getDefault().asyncExec(new Runnable() {
              public void run() {
                redraw();
              }
            });
          }
          selected = false;
          redraw();
        }
      }
    });
  }

  private void onPaint(PaintEvent e) {
    drawSingleCommand(e.gc);
  }

  private void drawSingleCommand(GC gc) {
    if(font != null) gc.setFont(font);
    Rectangle drawRect = new Rectangle(1, 1, getSize().x - 2, getSize().y - 2);
    //button.getSize().y - 2
    if ((getStyle() & SWT.TOGGLE) != 0 && getSelection()) {
      if (theme instanceof GeneralThemeRender) {
        GeneralThemeRender themeRender = (GeneralThemeRender) theme;
        gc.setForeground(themeRender.getTool_item_check_selection_bg_normal1());
        gc.setBackground(themeRender.getTool_item_check_selection_bg_normal2());
        gc.fillGradientRectangle(drawRect.x, drawRect.y, drawRect.width, drawRect.height, true);
        gc.setForeground(themeRender.getTool_item_check_selection_fg_normal());
        gc.drawRectangle(drawRect);
      } else if (theme instanceof OfficeThemeRender) {
        OfficeThemeRender themeRender = (OfficeThemeRender) theme;
        Color[] colors = new Color[] {
            themeRender.getTool_item_outer_top_checked1(),
            themeRender.getTool_item_outer_top_checked2(),
            themeRender.getTool_item_outer_bottom_checked1(),
            themeRender.getTool_item_outer_bottom_checked2(),
            themeRender.getTool_item_inner_top_checked1(),
            themeRender.getTool_item_inner_top_checked2(),
            themeRender.getTool_item_inner_bottom_checked1(),
            themeRender.getTool_item_inner_bottom_checked2(),
            themeRender.getTool_item_border_checked(), };
        drawGradientBack(gc, drawRect, colors);
        drawGradientBorder(gc, drawRect, colors);
      } else if (theme instanceof GlossyThemeRender) {
        drawGlossyItem(gc, drawRect);
      }
    }

    if (theme instanceof GeneralThemeRender) {
      GeneralThemeRender themeRender = (GeneralThemeRender) theme;
      if (selected && isEnabled()) {
        if (menuTracked || (getMenu() != null && !canSelected())) {
          gc.setForeground(themeRender.getTool_item_showmenu_bg1());
          gc.setBackground(themeRender.getTool_item_showmenu_bg2());
          gc.fillGradientRectangle(drawRect.x, drawRect.y, drawRect.width,
              drawRect.height, true);
          gc.setForeground(themeRender.getTool_item_showmenu_fg());
          gc.drawRectangle(drawRect);
        } else {
          gc.setForeground(themeRender.getTool_item_bg_selected1());
          gc.setBackground(themeRender.getTool_item_bg_selected2());
          if (getMenu() != null) {
            Rectangle noneMenuRect = getNonMenuRect();
            gc.fillGradientRectangle(noneMenuRect.x, noneMenuRect.y,
                noneMenuRect.width, noneMenuRect.height, true);
            gc.setForeground(themeRender.getTool_item_bg_track1());
            gc.setBackground(themeRender.getTool_item_bg_track2());
            Rectangle menuRect = getMenuRect();
            gc.fillGradientRectangle(menuRect.x, menuRect.y, menuRect.width, menuRect.height, true);
          } else {
            gc.fillGradientRectangle(drawRect.x, drawRect.y, drawRect.width, drawRect.height, true);
          }
          gc.setForeground(themeRender.getTool_item_fg_selected());
          gc.drawRectangle(drawRect);

        }
      } else if ((getStyle() & SWT.TOGGLE) != 0 && getSelection() && isEnabled()) {
        gc.setForeground(themeRender.getTool_item_check_selection_bg_track1());
        gc.setBackground(themeRender.getTool_item_check_selection_bg_track2());
        gc.fillGradientRectangle(drawRect.x, drawRect.y, drawRect.width,
            drawRect.height, true);
        gc.setForeground(themeRender.getTool_item_check_selection_fg_track());
        gc.drawRectangle(drawRect);
      } else {
        gc.setForeground(themeRender.getTool_item_bg_track1());
        gc.setBackground(themeRender.getTool_item_bg_track2());
        gc.fillGradientRectangle(drawRect.x, drawRect.y, drawRect.width, drawRect.height, true);
        gc.setForeground(themeRender.getTool_item_fg_track());
        gc.drawRectangle(drawRect);
      }
    } else if (theme instanceof OfficeThemeRender) {
      OfficeThemeRender themeRender = (OfficeThemeRender) theme;
      Color[] colors = null;
      if (selected && isEnabled()) {
        if (menuTracked || (getMenu() != null && !canSelected())) {
          colors = new Color[] {
              themeRender.getTool_item_outer_top_showmenu_color1(),
              themeRender.getTool_item_outer_top_showmenu_color2(),
              themeRender.getTool_item_outer_bottom_showmenu_color1(),
              themeRender.getTool_item_outer_bottom_showmenu_color2(),
              themeRender.getTool_item_inner_top_showmenu_color1(),
              themeRender.getTool_item_inner_top_showmenu_color2(),
              themeRender.getTool_item_inner_bottom_showmenu_color1(),
              themeRender.getTool_item_inner_bottom_showmenu_color2(),
              themeRender.getTool_item_border_showmenu_color(), };
          drawGradientBack(gc, drawRect, colors);
          drawGradientBorder(gc, drawRect, colors);
        } else {
          colors = new Color[] { themeRender.getTool_item_outer_top_selected1(),
              themeRender.getTool_item_outer_top_selected2(),
              themeRender.getTool_item_outer_bottom_selected1(),
              themeRender.getTool_item_outer_bottom_selected2(),
              themeRender.getTool_item_inner_top_selected1(),
              themeRender.getTool_item_inner_top_selected2(),
              themeRender.getTool_item_inner_bottom_selected1(),
              themeRender.getTool_item_inner_bottom_selected2(),
              themeRender.getTool_item_border_selected(), };
          if (getMenu() != null) {
            drawGradientBack(gc, getNonMenuRect(), colors);
            colors = new Color[] {
                themeRender.getTool_item_outer_top_track1(),
                themeRender.getTool_item_outer_top_track2(),
                themeRender.getTool_item_outer_bottom_track1(),
                themeRender.getTool_item_outer_bottom_track2(),
                themeRender.getTool_item_inner_top_track1(),
                themeRender.getTool_item_inner_top_track2(),
                themeRender.getTool_item_inner_bottom_track1(),
                themeRender.getTool_item_inner_bottom_track2(),
                themeRender.getTool_item_border_track(), };
            drawGradientBack(gc, getMenuRect(), colors);
          } else {
            drawGradientBack(gc, drawRect, colors);
          }
          drawGradientBorder(gc, drawRect, colors);
        }
      } else if ((getStyle() & SWT.TOGGLE) != 0 && getSelection() && isEnabled()) {
        colors = new Color[] {
            themeRender.getTool_item_outer_top_checked_track1(),
            themeRender.getTool_item_outer_top_checked_track2(),
            themeRender.getTool_item_outer_bottom_checked_track1(),
            themeRender.getTool_item_outer_bottom_checked_track2(),
            themeRender.getTool_item_inner_top_checked_track1(),
            themeRender.getTool_item_inner_top_checked_track2(),
            themeRender.getTool_item_inner_bottom_checked_track1(),
            themeRender.getTool_item_inner_bottom_checked_track2(),
            themeRender.getTool_item_border_checked_track(), };
        drawGradientBack(gc, drawRect, colors);
        drawGradientBorder(gc, drawRect, colors);
      } else {
        colors = new Color[] { themeRender.getTool_item_outer_top_track1(),
            themeRender.getTool_item_outer_top_track2(),
            themeRender.getTool_item_outer_bottom_track1(),
            themeRender.getTool_item_outer_bottom_track2(),
            themeRender.getTool_item_inner_top_track1(),
            themeRender.getTool_item_inner_top_track2(),
            themeRender.getTool_item_inner_bottom_track1(),
            themeRender.getTool_item_inner_bottom_track2(),
            themeRender.getTool_item_border_track(), };
        drawGradientBack(gc, drawRect, colors);
        drawGradientBorder(gc, drawRect, colors);
      }
    } else if (theme instanceof GlossyThemeRender) {
      drawGlossyItem(gc, drawRect);
    }

    gc.setForeground(isEnabled() ? theme.getTool_item_fg() : theme.getTool_item_fg_disabled());
    drawImageAndText(gc);
  }

  private void drawGradientBack(GC g, Rectangle rect, Color[] colors) {
    g.setAdvanced(true);
    Rectangle backRect = new Rectangle(rect.x, rect.y, rect.width + 1, rect.height + 1);
    Rectangle backRect1 = GraphicsUtil.inflate(backRect, -1, -1);
    int height = backRect1.height / 2;
    Rectangle rect1 = new Rectangle(backRect1.x, backRect1.y, backRect1.width, height);
    Rectangle rect2 = new Rectangle(backRect1.x, backRect1.y + height, backRect1.width,
        backRect1.height - height);

    g.setForeground(colors[0]);
    g.setBackground(colors[1]);
    g.fillGradientRectangle(rect1.x, rect1.y, rect1.width, rect1.height, true);

    g.setForeground(colors[2]);
    g.setBackground(colors[3]);
    g.fillGradientRectangle(rect2.x, rect2.y, rect2.width, rect2.height, true);

    Rectangle backRect2 = GraphicsUtil.inflate(backRect1, -1, -1);
    height = backRect2.height / 2;
    rect1 = new Rectangle(backRect2.x, backRect2.y, backRect2.width, height);
    rect2 = new Rectangle(backRect2.x, backRect2.y + height, backRect2.width,
        backRect2.height - height);

    g.setForeground(colors[4]);
    g.setBackground(colors[5]);
    g.fillGradientRectangle(rect1.x, rect1.y, rect1.width, rect1.height, true);

    g.setForeground(colors[6]);
    g.setBackground(colors[7]);
    g.fillGradientRectangle(rect2.x, rect2.y, rect2.width, rect2.height, true);

    g.setAdvanced(false);
  }

  private void drawGradientBorder(GC g, Rectangle rect, Color[] colors) {
    if (GraphicsUtil.checkGdip()) {
      g.setAdvanced(true);
      Rectangle backRect = new Rectangle(rect.x, rect.y, rect.width, rect.height);
      Path path = GraphicsUtil.createRoundPath(backRect, 2.0f);//1.2f
      g.setForeground(colors[8]);
      g.drawPath(path);
      path.dispose();
      g.setAdvanced(false);
    } else {
      g.setForeground(colors[8]);
      g.drawRectangle(rect);
    }
  }

  private void drawGlossyItem(GC gc, Rectangle drawRect) {
    GlossyThemeRender themeRender = (GlossyThemeRender) theme;

    Rectangle outerBorder = new Rectangle(drawRect.x, drawRect.y, drawRect.width,
        drawRect.height);
    Rectangle innerBorder = GraphicsUtil.inflate(outerBorder, -1, -1);
    Rectangle glossy = new Rectangle(innerBorder.x, innerBorder.y, innerBorder.width,
        innerBorder.height / 2);
    Rectangle glow = GraphicsUtil.createRectangleFromLTRB(outerBorder.x, outerBorder.y
        + Math.round(outerBorder.height * .5f), outerBorder.x + outerBorder.width,
        outerBorder.y + outerBorder.height);

    gc.setBackground(themeRender.getMenu_control_item_bg_track());
    gc.fillRectangle(innerBorder);

    gc.setAntialias(SWT.ON);

    Pattern pattern = new Pattern(null, 0, glossy.y, 0, glossy.y + glossy.height,
        themeRender.getTool_item_bg_color1(), themeRender
        .getTool_item_bg_color1_alpha(), themeRender.getTool_item_bg_color2(),
        themeRender.getTool_item_bg_color2_alpha());
    Path path = new Path(null);
    path.addRectangle(glossy.x, glossy.y, glossy.width, glossy.height);
    gc.setBackgroundPattern(pattern);
    gc.fillPath(path);
    path.dispose();

    // draw border
    path = GraphicsUtil.createRoundRectangle(outerBorder, 2);
    gc.setForeground(themeRender.getTool_item_outer_border());
    gc.drawPath(path);
    path.dispose();

    if (selected && (menuTracked || (getMenu() != null && !canSelected())))   {
      path = GraphicsUtil.createTopRoundRectangle(innerBorder, 2);
      gc.setBackground(themeRender.getTool_item_bg_glossy_showMenu());
      gc.fillPath(path);
      path.dispose();

      path = GraphicsUtil.createTopRoundRectangle(innerBorder, 2);
      gc.setForeground(themeRender.getTool_item_bg_glossy_showMenu());
      gc.drawPath(path);
      path.dispose();
      gc.setAdvanced(false);
      return;
    } else if (selected && getMenu() != null) {
      pattern = new Pattern(null, 0, glossy.y, 0, glossy.y + glossy.height, themeRender
          .getTool_item_bg_glossy_selected1(), themeRender
          .getTool_item_bg_glossy_selected1_alpha(), themeRender
          .getTool_item_bg_glossy_selected2(), themeRender
          .getTool_item_bg_glossy_selected2_alpha());
      Rectangle nonMenuRect = getNonMenuRect();
      Rectangle nonMenuGlossy = new Rectangle(innerBorder.x, innerBorder.y,
          nonMenuRect.width - 1, innerBorder.height / 2);
      path = createTopLeftRoundRectangle(nonMenuGlossy, 2);
      gc.setBackgroundPattern(pattern);
      gc.fillPath(path);
      path.dispose();

      pattern = new Pattern(null, 0, glossy.y, 0, glossy.y + glossy.height, themeRender
          .getTool_item_bg_glossy_track1(), themeRender
          .getTool_item_bg_glossy_track1_alpha(), themeRender
          .getTool_item_bg_glossy_track2(), themeRender
          .getTool_item_bg_glossy_track2_alpha());

      Rectangle menuRect = getMenuRect();
      Rectangle menuGlossy = new Rectangle(menuRect.x, innerBorder.y,
          menuRect.width - 1, innerBorder.height / 2);
      path = createTopRightRoundRectangle(menuGlossy, 2);
      gc.setBackgroundPattern(pattern);
      gc.fillPath(path);
      path.dispose();

      Color innerBorderColor = themeRender.getTool_item_inner_border_selected();

      path = createLeftRoundPath(new Rectangle(innerBorder.x, innerBorder.y,
          nonMenuRect.width - 1, innerBorder.height), 2);
      gc.setForeground(innerBorderColor);
      gc.drawPath(path);
      path.dispose();

      innerBorderColor = themeRender.getTool_item_inner_border_track();

      path = createRightRoundPath(new Rectangle(menuRect.x, innerBorder.y,
          menuRect.width, innerBorder.height), 2);
      gc.setForeground(innerBorderColor);
      gc.drawPath(path);
      path.dispose();

      path = GraphicsUtil.createRoundRectangle(glow, 2);
      gc.setClipping(path);
      path.dispose();

      Color glowColor = themeRender.getTool_item_bg_glow_track();
      path = createBottomRadialPath(glow);
      float[] point = new float[2];
      float[] bounds = new float[4];
      path.getBounds(bounds);
      point[0] = (bounds[0] + bounds[0] + bounds[2]) / 2f;
      point[1] = (bounds[1] + bounds[1] + bounds[3]) / 2f;
      GCExtension extension = new GCExtension(gc);
      extension.fillGradientPath(path, point, glowColor, 255, new Color[] { glowColor },
          new int[] { 0 });
      path.dispose();
      gc.setClipping((Region) null);

      gc.setAdvanced(false);
      return;
    }

    if (!(selected)) pattern = new Pattern(null, 0, glossy.y, 0, glossy.y + glossy.height,
        themeRender.getTool_item_bg_glossy_track1(), themeRender
        .getTool_item_bg_glossy_track1_alpha(), themeRender
        .getTool_item_bg_glossy_track2(), themeRender
        .getTool_item_bg_glossy_track2_alpha());
    else
      pattern = new Pattern(null, 0, glossy.y, 0, glossy.y + glossy.height, themeRender
          .getTool_item_bg_glossy_selected1(), themeRender
          .getTool_item_bg_glossy_selected1_alpha(), themeRender
          .getTool_item_bg_glossy_selected2(), themeRender
          .getTool_item_bg_glossy_selected2_alpha());
    path = GraphicsUtil.createTopRoundRectangle(glossy, 2);
    gc.setBackgroundPattern(pattern);
    gc.fillPath(path);
    path.dispose();

    Color innerBorderColor = (selected)
    || ((getStyle() & SWT.TOGGLE) != 0 && getSelection()) ? themeRender
        .getTool_item_inner_border_selected() : themeRender
        .getTool_item_inner_border_track();

        path = GraphicsUtil.createRoundRectangle(innerBorder, 2);
        gc.setForeground(innerBorderColor);
        gc.drawPath(path);
        path.dispose();

        if (!((menuTracked || (getMenu() != null && !canSelected())) && selected)) {
          path = GraphicsUtil.createRoundRectangle(glow, 2);
          gc.setClipping(path);
          path.dispose();

          Color glowColor = themeRender.getTool_item_bg_glow_track();

          if ((getStyle() & SWT.TOGGLE) != 0 && getSelection()) {
            glowColor = themeRender.getTool_item_bg_checked_glow_track();
          }

          path = createBottomRadialPath(glow);
          float[] point = new float[2];
          float[] bounds = new float[4];
          path.getBounds(bounds);
          point[0] = (bounds[0] + bounds[0] + bounds[2]) / 2f;
          point[1] = (bounds[1] + bounds[1] + bounds[3]) / 2f;
          GCExtension extension = new GCExtension(gc);
          extension.fillGradientPath(path, point, glowColor, 255, new Color[] { glowColor },
              new int[] { 0 });
          path.dispose();
          gc.setClipping((Region) null);
        }
        gc.setAdvanced(false);
  }

  private Path createBottomRadialPath(Rectangle glow) {
    float[] bounds = new float[4];
    bounds[0] = glow.x;
    bounds[1] = glow.y;
    bounds[2] = glow.width;
    bounds[3] = glow.height;
    bounds[0] -= bounds[2] * .35f;
    bounds[1] -= bounds[3] * .15f;
    bounds[2] *= 1.7f;
    bounds[3] *= 2.3f;
    return GraphicsUtil.createEllipsePath(bounds);
  }

  /*
   * Three status: normal, hover(VS2003), disable.
   */
  private void drawImageAndText(GC gc) {
    gc.setAdvanced(false);
    Rectangle drawRect = getSelectRect();
    if (getMenu() != null) drawRect = new Rectangle(drawRect.x, drawRect.y, drawRect.width
        - SUBMENUWIDTH, drawRect.height);
    int left = drawRect.x;
    int top = drawRect.y;
    int right = drawRect.width + left;
    int bottom = drawRect.height + top;
    int length = gc.textExtent(getText(), DRAW_FLAGS).x;
    int height = gc.getFontMetrics().getHeight();
    int imageHight = image == null ? 0 : image.getImageData().height;
    int imageWidth = image == null ? 0 : image.getImageData().width;

    if (text != null && image != null) {
      if ((style & SWT.TOP) != 0) {
        int x = left + Math.round((drawRect.width - image.getImageData().width) / 2f);
        int y = top + Math.round((imageHight - image.getImageData().height) / 2f);
        gc.drawImage(image, x, y);
       
        gc.drawText(text,
            left + Math.round((drawRect.width - length) / 2f),
            top + imageHight + VERTICAL_MARGIN, DRAW_FLAGS);
       
      } else if ((style & SWT.BOTTOM) != 0) {
        int x = left + Math.round((drawRect.width - image.getImageData().width) / 2f);
        int y = bottom - imageHight + Math.round((imageHight - image.getImageData().height) / 2f);
        drawImage(gc, x, y);
       
        gc.drawText(text,
            left + Math.round((drawRect.width - length) / 2f),
            top + drawRect.height - imageHight - VERTICAL_MARGIN - height, DRAW_FLAGS);
      } else if ((style & SWT.RIGHT) != 0) {
        gc.drawText(text,
            right - imageWidth - HORIZON_GAP - length,
            top + Math.round((drawRect.height - height) / 2f), DRAW_FLAGS);
       
        int x = (right - imageWidth) + (imageWidth - image.getImageData().width) / 2;
        int y = top + (drawRect.height - image.getImageData().height) / 2;
        drawImage(gc, x, y);
      } else {
        int x = left + (imageWidth - image.getImageData().width) / 2;
        int y = top + (drawRect.height - image.getImageData().height) / 2;
        drawImage(gc, x, y);
       
        gc.drawText(text, left + HORIZON_GAP + imageWidth,
            top + Math.round((drawRect.height - height) / 2f), DRAW_FLAGS);
      }
    } else {
      if (text != null) {
        gc.drawText(text,
            left + Math.round((drawRect.width - length) / 2f) - 1,
            top - 1 + Math.round((drawRect.height - height) / 2f), DRAW_FLAGS);
      } else if (image != null) {
        int x = left + Math.round((drawRect.width - image.getImageData().width) / 2f);
        int y = top + Math.round((drawRect.height - image.getImageData().height) / 2f);
        drawImage(gc, x, y);
      }
    }

    if (getMenu() == null) return;
    Rectangle menuRect = getMenuRect();
    gc.setAdvanced(false);
    if (isEnabled()) {
      gc.setBackground(theme.getTool_item_arrow_bg_track());
    } else {
      gc.setBackground(theme.getTool_item_arrow_bg_disabled());
    }
    GraphicsUtil.drawArrow(gc, menuRect, SWT.DOWN);

    if (!(theme instanceof OfficeThemeRender)) {
      if (theme instanceof GeneralThemeRender) {
        gc.setForeground(((GeneralThemeRender) theme).getTool_item_check_separater_color());
      } else if (theme instanceof GlossyThemeRender) {
        gc.setForeground(((GlossyThemeRender) theme).getTool_item_check_separater_color());
      }
      gc.drawLine(menuRect.x, menuRect.y + 1, menuRect.x, menuRect.y + menuRect.height - 1);
      return;
    }
   
    if (selected) return;

    gc.setForeground(((OfficeThemeRender) theme).getTool_item_check_separater_drakcolor());
    gc.drawLine(menuRect.x, menuRect.y + 1, menuRect.x, menuRect.y + menuRect.height - 1);
    gc.setForeground(((OfficeThemeRender) theme).getTool_item_check_separater_lightcolor());
    gc.drawLine(menuRect.x + 1, menuRect.y + 1, menuRect.x + 1, menuRect.y + menuRect.height - 1);
  }

  private static final int VERTICAL_GAP = 3;

  private static final int HORIZON_GAP = 2;

  private Rectangle getSelectRect() {
    Rectangle bound = new Rectangle(1, 1, getSize().x - 1, getSize().y - 1);
    Rectangle selectRect = new Rectangle(bound.x, bound.y, bound.width, bound.height);
    selectRect.height -= (2 * 2 + 1);
    selectRect.width -= (2 * 1 + 1);
    selectRect.x += HORIZON_GAP;
    selectRect.y += VERTICAL_GAP;
    return selectRect;
  }

  private Rectangle getMenuRect() {
    Rectangle bound = new Rectangle(1, 1, getSize().x - 2, getSize().y - 2);
    int menuLeft = getSelectRect().x + getSelectRect().width - SUBMENUWIDTH;
    int menuRight = bound.x + bound.width;
    Rectangle menuRect = new Rectangle(menuLeft, bound.y, menuRight - menuLeft,
        bound.height);
    return menuRect;
  }

  private Rectangle getNonMenuRect() {
    Rectangle bound = new Rectangle(1, 1, getSize().x - 2, getSize().y - 2);
    int left = bound.x;
    int right = getSelectRect().x + getSelectRect().width + 3 - SUBMENUWIDTH;
    Rectangle menuRect = new Rectangle(left, bound.y, right - left, bound.height);
    return menuRect;
  }

  private void drawImage(GC gc, int x, int y) {
    if (image == null) return;
    if (!isEnabled()) {
      // Draw a image disabled
      Image disableImage = new Image(null, image, SWT.IMAGE_DISABLE);
      gc.drawImage(disableImage, x, y);
      disableImage.dispose();
      return;
    }

    if (!selected && (theme.isShowToolImageShadow() && GraphicsUtil.checkGdip())) {
      ImageData shadowImage = image.getImageData();
      PaletteData palette = new PaletteData(new RGB[] { new RGB(0, 0, 0), new RGB(154, 156, 146) });
      ImageData data = new ImageData(shadowImage.width, shadowImage.height, 1, palette);
      data.transparentPixel = shadowImage.transparentPixel;
      if (shadowImage.getTransparencyType() == SWT.TRANSPARENCY_PIXEL) {
        for (int pixelX = 0; pixelX < shadowImage.width; pixelX++) {
          for (int pixelY = 0; pixelY < shadowImage.width; pixelY++) {
            int dstPixel = shadowImage.getPixel(pixelX, pixelY);
            if (dstPixel != shadowImage.transparentPixel) {
              data.setPixel(pixelX, pixelY, 1);
            } else {
              data.setPixel(pixelX, pixelY, 0);
            }
          }
        }

        gc.setAdvanced(true);

        Image tempImage = new Image(gc.getDevice(), data);
        gc.drawImage(tempImage, x + 1, y + 1);
        tempImage.dispose();
        gc.setAdvanced(false);
        gc.drawImage(image, x - 1, y - 1);
        return;
      }
      gc.drawImage(image, x, y);
      return;
    }

    if (!GraphicsUtil.checkGdip() || !theme.isShowToolImageShadow()) {
      gc.drawImage(image, x, y);
      return;
    }

    RGB[] rgbs = image.getImageData().palette.getRGBs();
    if (rgbs == null) return;

    for (int i = 0; i < rgbs.length; i++) {
      RGB rgb = rgbs[i];
      rgb.red = (rgb.red + 76) - (((rgb.red + 32) / 64) * 19);
      rgb.green = (rgb.green + 76) - (((rgb.green + 32) / 64) * 19);
      rgb.blue = (rgb.blue + 76) - (((rgb.blue + 32) / 64) * 19);
    }

    ImageData shadowImage = image.getImageData();
    ImageData data = new ImageData(shadowImage.width,
        shadowImage.height, shadowImage.depth, new PaletteData(rgbs));
    data.transparentPixel = shadowImage.transparentPixel;

    for (int pixelX = 0; pixelX < shadowImage.width; pixelX++) {
      for (int pixelY = 0; pixelY < shadowImage.width; pixelY++) {
        int dstPixel = shadowImage.getPixel(pixelX, pixelY);
        if (dstPixel != shadowImage.transparentPixel) {
          data.setPixel(pixelX, pixelY, dstPixel);
        } else {
          data.setPixel(pixelX, pixelY, shadowImage.transparentPixel);
        }
      }
    }
    Image fadedImage = new Image(null, data);
    gc.drawImage(fadedImage, x, y);
    fadedImage.dispose();

  }

  private Path createTopLeftRoundRectangle(Rectangle rectangle, int radius) {
    Path path = new Path(null);

    int l = rectangle.x;
    int t = rectangle.y;
    int w = rectangle.width;
    int h = rectangle.height;
    int d = radius << 1;

    path.addArc(l, t, d, d, -180, -90); // topleft
    path.lineTo(l + radius, t);
    path.lineTo(l + w, t);
    path.lineTo(l + w, t + h);
    path.lineTo(l, t + h);
    path.lineTo(l, t + radius);
    path.close();

    return path;
  }

  private Path createTopRightRoundRectangle(Rectangle rectangle, int radius) {
    Path path = new Path(null);

    int l = rectangle.x;
    int t = rectangle.y;
    int w = rectangle.width;
    int h = rectangle.height;
    int d = radius << 1;

    path.moveTo(l, t); // topleft
    path.lineTo(l + w - radius, t);
    path.addArc(l + w - d, t, d, d, -270, -90); // topright
    path.lineTo(l + w, t + radius);
    path.lineTo(l + w, t + h);
    path.lineTo(l, t + h);
    path.lineTo(l, t);
    path.close();

    return path;
  }

  public static Path createLeftRoundPath(Rectangle rectangle, int radius) {
    Path path = new Path(null);

    int l = rectangle.x;
    int t = rectangle.y;
    int w = rectangle.width;
    int h = rectangle.height;
    int d = radius << 1;

    path.moveTo(l + w, t);
    path.lineTo(l + radius, t);
    path.addArc(l, t, d, d, 90, 90);

    path.lineTo(l, t + radius);
    path.lineTo(l, t + h - radius);
    path.addArc(l, t + h - d, d, d, 180, 90);
    path.lineTo(l + radius, t + h);
    path.lineTo(l + w, t + h);

    return path;
  }

  public static Path createRightRoundPath(Rectangle rectangle, int radius) {
    Path path = new Path(null);

    int l = rectangle.x;
    int t = rectangle.y;
    int w = rectangle.width;
    int h = rectangle.height;
    int d = radius << 1;

    path.moveTo(l, t);
    path.lineTo(l + w - radius, t);
    path.addArc(l + w - d, t, d, d, -270, -90);
    path.lineTo(l + w, t + radius);
    path.lineTo(l + w, t + h - radius);
    path.addArc(l + w - d, t + h - d, d, d, 0, -90);
    path.lineTo(l + w - radius, t + h);
    path.lineTo(l, t + h); // top

    return path;
  }


  private Point recalculate() {
    GC gc = new GC(this);
    int BREADTH_GAP = (gc.getFontMetrics().getHeight() / 3) + 1;
    int rowHeight = gc.getFontMetrics().getHeight() + BREADTH_GAP * 2 + BREADTH_GAP/2;
    if ((style & SWT.TOP) != 0 || (style & SWT.BOTTOM) != 0) {
      if (image != null) rowHeight += image.getImageData().height;
      rowHeight += 2 * VERTICAL_MARGIN;
    } else {
      if (image != null) rowHeight =
        (image.getImageData().height > rowHeight ? image.getImageData().height : rowHeight);
    }

    int cellLength = 0;
    int cellMinLength = HORIZON_MARGIN * 3 + HORIZON_MARGIN/2;
    if (getText() == null) {
      cellLength = cellMinLength;
      if (image != null) cellLength += image.getImageData().width;
    } else if (image == null) {
      cellLength = cellMinLength + gc.textExtent(getText(), DRAW_FLAGS).x;
    } else {
      if ((style & SWT.TOP) == 0 && (style & SWT.BOTTOM) == 0) {
        cellLength = cellMinLength + gc.textExtent(getText(), DRAW_FLAGS).x
        + HORIZON_MARGIN;
        if (image != null) cellLength += image.getImageData().width;
      } else {
        cellLength = gc.textExtent(getText(), DRAW_FLAGS).x;
        if (image != null) {
          cellLength = cellLength < image.getImageData().width ? image.getImageData().width : cellLength;
        } else {
          cellLength = cellLength < image.getImageData().width ? image.getImageData().width : cellLength;
        }
        cellLength += (cellMinLength);
      }
    }
    if (getMenu() != null) cellLength += SUBMENUWIDTH;
    gc.dispose();
    return new Point(cellLength, rowHeight);
  }

  private void handleMouseMoveEvent(Point screenPos) {
    if (!new Rectangle(0, 0, getBounds().width, getBounds().height).contains(screenPos)) {
      if (menuTracked || selected) {
        menuTracked = false;
        selected = false;
        redraw();
      }
      return;
    }

    if (isShowMenu() || getMenu() == null) return;

    if (getMenuRect().contains(screenPos)) {
      if (!menuTracked) {
        menuTracked = true;
        redraw();
      }
      return;
    }

    if (!menuTracked) return;
    menuTracked = false;
    redraw();
  }
 
  @SuppressWarnings("unused")
  public Point computeSize(int wHint, int hHint, boolean changed) {
    return computeSize(wHint, hHint);
  }
 
  public Point computeSize(int wHint, int hHint) {
    checkWidget();
    Point size = recalculate();
    int width = size.x;
    int height = size.y;
    if (wHint != SWT.DEFAULT) width = wHint;
    if (hHint != SWT.DEFAULT) height = hHint;
    int border = getBorderWidth();
    width += border * 2;
    height += border * 2;
    return new Point(width, height);
  }

}
TOP

Related Classes of org.sf.feeling.swt.win32.extension.widgets.CButton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.