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

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

/*******************************************************************************
* Copyright (c) 2007 cnfree.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*  cnfree  - initial API and implementation
*******************************************************************************/
package org.sf.feeling.swt.win32.extension.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.Callback;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.sf.feeling.swt.win32.extension.Win32;
import org.sf.feeling.swt.win32.extension.widgets.theme.ThemeRender;
import org.sf.feeling.swt.win32.extension.widgets.theme.VS2005ThemeRender;
import org.sf.feeling.swt.win32.internal.extension.Extension;

public class PopupMenu extends MenuControl implements MenuHolder {

  private static final int KEY_LEFT = 16777219;

  private static final int KEY_RIGHT = 16777220;

  private static final int KEY_DOWN = 16777218;

  private static final int KEY_UP = 16777217;

  private Control control;

  private Listener listener;

  private Callback mouseCallback;

  private int newAddress;

  private int oldAddress;

  public PopupMenu(Control control, ThemeRender theme) {
    this(control, theme, true);
  }

  public PopupMenu(Control control, ThemeRender theme, boolean autoDetect) {
    super(null, theme);
    this.holder = this;
    this.control = control;
    isPopupMenu = true;
    if (autoDetect) {
      listener = new Listener() {
        public void handleEvent(Event event) {
          if (MenuHolderManager.getActiveHolder() != null
              && MenuHolderManager.getActiveHolder() != PopupMenu.this)
            return;
          open();
        }
      };
      control.addListener(SWT.MenuDetect, listener);
    }
    MenuHolderManager.registerHolder(this);
  }

  public PopupMenu(Control control) {
    this(control, true);
  }

  public PopupMenu(Control control, boolean autoDetect) {
    this(control, new VS2005ThemeRender(), autoDetect);
  }

  public void setMenu(CMenu menu) {
    this.menu = menu;
    MenuHolderManager.registryShortcut(this);
  }

  public void dispose() {
    hideMenu();
    if (!control.isDisposed())
      control.removeListener(SWT.MenuDetect, listener);
  }

  public void setLocation(Point location) {
    screenPos = location;
  }

  public void hideMenu() {
    super.hideMenu();
    screenPos = null;
  }

  public void open() {
    if (screenPos == null)
      screenPos = Display.getDefault().getCursorLocation();
    leftScreenPos = screenPos;
    popupRight = true;
    if (control == null || control.isDisposed())
      return;
    control.addDisposeListener(new DisposeListener() {

      public void widgetDisposed(DisposeEvent e) {
        dispose();
      }

    });
    final ShellListener shellListener = new ShellAdapter() {

      public void shellClosed(ShellEvent e) {
        hideMenu();
      }

      public void shellDeactivated(ShellEvent e) {
        hideMenu();
      }

      public void shellIconified(ShellEvent e) {
        hideMenu();
      }

    };
    control.getShell().addShellListener(shellListener);
    ignoreTaskbar = true;

    Event event = new Event();
    event.data = this;
    event.type = SWT.OPEN;
    menu.fireMenuEvent(event);

    createAndShowWindow();
    installMouseHook();
    shell.addDisposeListener(new DisposeListener() {

      public void widgetDisposed(DisposeEvent e) {
        if (!control.isDisposed())
          control.getShell().removeShellListener(shellListener);
      }

    });

    final Listener mouseDownListener = new Listener() {

      public void handleEvent(Event e) {
        if (shell == null || shell.isDisposed()) {
          Display.getDefault().removeFilter(SWT.MouseDown, this);
          return;
        }
        if (e.widget == null
            || e.widget.isDisposed()
            || checkMouseDownEvent(((Control) e.widget).toDisplay(
                e.x, e.y))) {
          hideMenu();
        }
      }
    };

    Display.getDefault().addFilter(SWT.MouseDown, mouseDownListener);

    final Listener keyDownListener = new Listener() {

      public void handleEvent(Event e) {
        if (shell == null || shell.isDisposed()) {
          Display.getDefault().removeFilter(SWT.KeyDown, this);
          e.doit = false;
          return;
        }
        KeyEvent ke = new KeyEvent(e);
        if ((ke.keyCode == SWT.ALT) || ke.keyCode == SWT.F10) {
          hideMenu();
          return;
        }
        getCurrentMenu().dealAltKeyEvent(ke);

        if (ke.keyCode == KEY_RIGHT && trackItemIndex > -1) {
          getCurrentMenu().subMenuSelected();
        }
        if (ke.keyCode == KEY_LEFT && trackItemIndex > -1) {
          getCurrentMenu().parentMenuSelected();
        }
        if (ke.keyCode == KEY_DOWN || ke.keyCode == KEY_UP) {
          if (ke.keyCode == KEY_DOWN)
            getCurrentMenu().downSelected();
          else
            getCurrentMenu().upSelected();
        }
        if (ke.keyCode == SWT.ESC) {
          if (getCurrentMenu().parentMenu == null)
            getCurrentMenu().hideMenu();
          else
            getCurrentMenu().parentMenuSelected();
        }
        if (ke.keyCode == SWT.CR) {
          getCurrentMenu().handleSelectedEvent();
        }
      }
    };
    Display.getDefault().addFilter(SWT.KeyDown, keyDownListener);

    shell.addDisposeListener(new DisposeListener() {

      public void widgetDisposed(DisposeEvent e) {
        Display.getDefault().removeFilter(SWT.MouseDown,
            mouseDownListener);
        Display.getDefault().removeFilter(SWT.KeyDown, keyDownListener);
        getShell().removeShellListener(shellListener);
      }

    });

  }

  MenuControl getCurrentMenu() {
    if (popupMenu != null && popupMenu.trackItemIndex != -1)
      return popupMenu.getCurrentMenu();
    else
      return this;
  }

  private void installMouseHook() {
    if (mouseCallback == null) {
      mouseCallback = new Callback(this, "MouseProc", 3);
      newAddress = mouseCallback.getAddress();
      if (newAddress == 0)
        SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
      int threadId = Extension.GetCurrentThreadId();
      oldAddress = Extension.SetWindowsHookEx(Win32.WH_MOUSE, newAddress,
          0, threadId);
      shell.addDisposeListener(new DisposeListener() {

        public void widgetDisposed(DisposeEvent e) {
          if (mouseCallback != null) {
            Extension.UnhookWindowsHookEx(oldAddress);
            mouseCallback.dispose();
            mouseCallback = null;
            newAddress = 0;
          }
        }

      });
    }
  }

  int MouseProc(int /* long */code, int /* long */wParam,
      int /* long */lParam) {
    int result = Extension.CallNextHookEx(oldAddress, code, wParam, lParam);
    if (code < 0)
      return result;
    switch (wParam) {
    case Win32.WM_NCLBUTTONDOWN:
    case Win32.WM_NCRBUTTONDOWN:
      hideMenu();
      break;
    }
    return result;
  }

  public Shell getShell() {
    if (control.isDisposed())
      return null;
    if (control instanceof Shell)
      return (Shell) control;
    return control.getShell();
  }

  public boolean isAcitve() {
    return shell != null && !shell.isDisposed();
  }
}
TOP

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

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.