001/* [{ 002Copyright 2007, 2008 Nicolas Carranza <nicarran at gmail.com> 003 004This file is part of jpen. 005 006jpen is free software: you can redistribute it and/or modify 007it under the terms of the GNU Lesser General Public License as published by 008the Free Software Foundation, either version 3 of the License, 009or (at your option) any later version. 010 011jpen is distributed in the hope that it will be useful, 012but WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014GNU Lesser General Public License for more details. 015 016You should have received a copy of the GNU Lesser General Public License 017along with jpen. If not, see <http://www.gnu.org/licenses/>. 018}] */ 019package jpen.provider.system; 020 021import java.awt.Component; 022import java.awt.event.MouseAdapter; 023import java.awt.event.MouseEvent; 024import java.awt.event.MouseListener; 025import java.awt.event.MouseMotionListener; 026import java.awt.event.MouseWheelEvent; 027import java.awt.event.MouseWheelListener; 028import java.awt.Point; 029import java.lang.ref.WeakReference; 030import java.util.Arrays; 031import java.util.Collection; 032import java.util.Collections; 033import java.util.List; 034import java.util.logging.Level; 035import java.util.logging.Logger; 036import jpen.PButton; 037import jpen.PButtonEvent; 038import jpen.PenDevice; 039import jpen.PenEvent; 040import jpen.PenManager; 041import jpen.PenProvider; 042import jpen.PLevel; 043import jpen.PLevelEvent; 044import jpen.provider.AbstractPenDevice; 045import jpen.PScroll; 046import jpen.PScrollEvent; 047 048@SuppressWarnings("deprecation") 049public final class MouseDevice 050 extends AbstractPenDevice { 051 private static final Logger L=Logger.getLogger(MouseDevice.class.getName()); 052 //static {L.setLevel(Level.ALL); } 053 054 private final MouseListener mouseL=new MouseAdapter() { 055 @Override 056 public void mousePressed(MouseEvent ev) { 057 scheduleMove(ev); 058 mouseButtonChanged(ev, true); 059 } 060 061 @Override 062 public void mouseReleased(MouseEvent ev) { 063 scheduleMove(ev); 064 mouseButtonChanged(ev, false); 065 } 066 }; 067 private final MouseMotionListener mouseMotionL=new MouseMotionListener(){ 068 //@Override 069 public void mouseMoved(MouseEvent ev) { 070 scheduleMove(ev); 071 } 072 //@Override 073 public void mouseDragged(MouseEvent ev) { 074 scheduleMove(ev); 075 } 076 }; 077 private final MouseWheelListener mouseWheelL=new MouseWheelListener(){ 078 //@Override 079 public void mouseWheelMoved(MouseWheelEvent ev) { 080 if(!getEnabled()) 081 return; 082 int value=ev.getWheelRotation(); 083 PScroll.Type type=PScroll.Type.DOWN; 084 if(value<0) { 085 type=PScroll.Type.UP; 086 value=-value; 087 } 088 if(ev.getScrollType()==ev.WHEEL_UNIT_SCROLL && ev.getScrollAmount()>0) // > 0 : is because windows bug workaround, sometimes it is 0. 089 value*=ev.getScrollAmount(); 090 getPenManager().scheduleScrollEvent(MouseDevice.this, ev.getWhen(), new PScroll(type.ordinal(), value)); 091 } 092 }; 093 private final SystemProvider systemProvider; 094 private WeakReference<Component> activeComponentRef; 095 096 MouseDevice(SystemProvider systemProvider) { 097 super(systemProvider); 098 this.systemProvider=systemProvider; 099 setEnabled(true); 100 } 101 102 //@Override 103 public String getName() { 104 return "Mouse"; 105 } 106 107 @Override 108 public boolean getUseFractionalMovements(){ 109 return false; 110 } 111 112 void setPaused(boolean paused) { 113 Component activeComponent=activeComponentRef==null? null:activeComponentRef.get(); 114 activeComponentRef=null; 115 if(activeComponent!=null){ 116 activeComponent.removeMouseListener(mouseL); 117 activeComponent.removeMouseMotionListener(mouseMotionL); 118 activeComponent.removeMouseWheelListener(mouseWheelL); 119 } 120 if(!paused){ 121 activeComponent=systemProvider.componentPenOwner.getActiveComponent(); 122 if(activeComponent!=null){ 123 activeComponent.addMouseListener(mouseL); 124 activeComponent.addMouseMotionListener(mouseMotionL); 125 activeComponent.addMouseWheelListener(mouseWheelL); 126 activeComponentRef=new WeakReference<Component>(activeComponent); 127 } 128 } 129 } 130 131 private void scheduleMove(MouseEvent ev){ 132 if(!getEnabled()) 133 return; 134 scheduleMove(ev.getWhen(), ev.getX(), ev.getY()); 135 } 136 137 private final PLevel[] changedLevelsA=new PLevel[2]; 138 private final List<PLevel> changedLevels=Arrays.asList(changedLevelsA); 139 140 private void scheduleMove(long time, int x, int y) { 141 changedLevelsA[0]=new PLevel(PLevel.Type.X.ordinal(), x); 142 changedLevelsA[1]=new PLevel(PLevel.Type.Y.ordinal(), y); 143 getPenManager().scheduleLevelEvent(this, time, changedLevels, false); 144 } 145 146 private void mouseButtonChanged(MouseEvent ev, boolean state) { 147 if(!getEnabled()) 148 return; 149 PButton.Type buttonType=getButtonType(ev.getButton()); 150 if(buttonType==null) 151 return; 152 if(L.isLoggable(Level.FINE)) 153 L.fine("scheduling button event: "+buttonType+", "+state); 154 getPenManager().scheduleButtonEvent(this, ev.getWhen(), new PButton(buttonType.ordinal(), state)); 155 } 156 157 private static PButton.Type getButtonType(int buttonNumber) { 158 switch(buttonNumber) { 159 case MouseEvent.BUTTON1: 160 return PButton.Type.LEFT; 161 case MouseEvent.BUTTON2: 162 return PButton.Type.CENTER; 163 case MouseEvent.BUTTON3: 164 return PButton.Type.RIGHT; 165 } 166 return null; 167 } 168}