| <component name="ChangeListManager"> | ||
| <list default="true" id="be1819c5-28d3-4984-9634-0b266734e13c" name="Default Changelist" comment=""> | ||
| - <change afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/ImageComponent.java" afterDir="false" /> | ||
| - <change afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/KeyState.java" afterDir="false" /> | ||
| + <change afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/HardwareSwitches.java" afterDir="false" /> | ||
| <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||
| - <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/AppImage.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/AppImage.java" afterDir="false" /> | ||
| + <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/AppImage.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/SvgRasterizer.java" afterDir="false" /> | ||
| <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/EventFrame.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/EventFrame.java" afterDir="false" /> | ||
| + <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/ImageComponent.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/ImageComponent.java" afterDir="false" /> | ||
| + <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/KeyState.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/HardwareState.java" afterDir="false" /> | ||
| <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/KmCaster.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/KmCaster.java" afterDir="false" /> | ||
| - <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/Key.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/Key.java" afterDir="false" /> | ||
| + <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/Key.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/SwitchName.java" afterDir="false" /> | ||
| <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/KeyboardListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/KeyboardListener.java" afterDir="false" /> | ||
| + <change beforePath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/KeyboardModifier.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/com/whitemagicsoftware/kmcaster/listeners/KeyboardModifier.java" afterDir="false" /> | ||
| </list> | ||
| <option name="SHOW_DIALOG" value="false" /> | ||
| </state> | ||
| <state x="707" y="657" width="431" height="302" key="#com.intellij.refactoring.move.moveInner.MoveInnerDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594958994663" /> | ||
| - <state x="567" y="28" width="711" height="1526" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1594954562308"> | ||
| + <state x="567" y="28" width="711" height="1526" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1594967090738"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state x="567" y="28" width="711" height="1526" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594954562308" /> | ||
| + <state x="567" y="28" width="711" height="1526" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594967090738" /> | ||
| <state x="659" y="559" width="526" height="497" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1594880960290"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| <state x="659" y="559" width="526" height="497" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594880960290" /> | ||
| <state x="710" y="704" width="425" height="207" key="DetectedRootsChooserDialog" timestamp="1594872764235"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| <state x="710" y="704" width="425" height="207" key="DetectedRootsChooserDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594872764235" /> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.bottom" timestamp="1594963811114"> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.bottom" timestamp="1594967617575"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.bottom/0.28.2560.1529@0.28.2560.1529" timestamp="1594963811114" /> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.center" timestamp="1594963811113"> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.bottom/0.28.2560.1529@0.28.2560.1529" timestamp="1594967617575" /> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.center" timestamp="1594967617574"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.center/0.28.2560.1529@0.28.2560.1529" timestamp="1594963811113" /> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.left" timestamp="1594963811113"> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.center/0.28.2560.1529@0.28.2560.1529" timestamp="1594967617574" /> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.left" timestamp="1594967617574"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.left/0.28.2560.1529@0.28.2560.1529" timestamp="1594963811113" /> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.right" timestamp="1594963811113"> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.left/0.28.2560.1529@0.28.2560.1529" timestamp="1594967617574" /> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.right" timestamp="1594967617575"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state width="1479" height="330" key="GridCell.Tab.0.right/0.28.2560.1529@0.28.2560.1529" timestamp="1594963811113" /> | ||
| + <state width="1479" height="330" key="GridCell.Tab.0.right/0.28.2560.1529@0.28.2560.1529" timestamp="1594967617575" /> | ||
| <state width="1479" height="406" key="GridCell.Tab.1.bottom" timestamp="1594959771008"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| <state x="833" y="545" width="586" height="502" key="find.popup/0.28.2560.1529@0.28.2560.1529" timestamp="1594949350582" /> | ||
| - <state x="589" y="382" width="672" height="677" key="run.anything.popup" timestamp="1594954728874"> | ||
| + <state x="915" y="547" width="415" height="496" key="refactoring.ChangeSignatureDialog" timestamp="1594967617639"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state x="589" y="382" width="672" height="677" key="run.anything.popup/0.28.2560.1529@0.28.2560.1529" timestamp="1594954728874" /> | ||
| - <state x="589" y="477" width="672" height="678" key="search.everywhere.popup" timestamp="1594956705885"> | ||
| + <state x="915" y="547" width="415" height="496" key="refactoring.ChangeSignatureDialog/0.28.2560.1529@0.28.2560.1529" timestamp="1594967617639" /> | ||
| + <state x="589" y="382" width="672" height="677" key="run.anything.popup" timestamp="1594967368555"> | ||
| <screen x="0" y="28" width="2560" height="1529" /> | ||
| </state> | ||
| - <state x="589" y="477" width="672" height="678" key="search.everywhere.popup/0.28.2560.1529@0.28.2560.1529" timestamp="1594956705885" /> | ||
| + <state x="589" y="382" width="672" height="677" key="run.anything.popup/0.28.2560.1529@0.28.2560.1529" timestamp="1594967368555" /> | ||
| + <state x="589" y="477" width="672" height="678" key="search.everywhere.popup" timestamp="1594965859325"> | ||
| + <screen x="0" y="28" width="2560" height="1529" /> | ||
| + </state> | ||
| + <state x="589" y="477" width="672" height="678" key="search.everywhere.popup/0.28.2560.1529@0.28.2560.1529" timestamp="1594965859325" /> | ||
| </component> | ||
| </project> | ||
| -/* | ||
| - * Copyright 2020 White Magic Software, Ltd. | ||
| - * | ||
| - * All rights reserved. | ||
| - * | ||
| - * Redistribution and use in source and binary forms, with or without | ||
| - * modification, are permitted provided that the following conditions are met: | ||
| - * | ||
| - * o Redistributions of source code must retain the above copyright | ||
| - * notice, this list of conditions and the following disclaimer. | ||
| - * | ||
| - * o Redistributions in binary form must reproduce the above copyright | ||
| - * notice, this list of conditions and the following disclaimer in the | ||
| - * documentation and/or other materials provided with the distribution. | ||
| - * | ||
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| - */ | ||
| -package com.whitemagicsoftware.kmcaster; | ||
| - | ||
| -import com.kitfox.svg.SVGDiagram; | ||
| -import com.kitfox.svg.SVGException; | ||
| -import com.kitfox.svg.SVGUniverse; | ||
| - | ||
| -import javax.swing.*; | ||
| -import java.awt.*; | ||
| -import java.awt.geom.AffineTransform; | ||
| -import java.awt.image.BufferedImage; | ||
| -import java.net.URL; | ||
| -import java.util.Map; | ||
| - | ||
| -import static com.whitemagicsoftware.kmcaster.KmCaster.rethrow; | ||
| -import static java.awt.RenderingHints.*; | ||
| -import static java.awt.image.BufferedImage.TYPE_INT_ARGB; | ||
| -import static java.lang.String.format; | ||
| - | ||
| -/** | ||
| - * Responsible for loading vector graphics representations of application | ||
| - * images. The images provide an on-screen interface that indicate to the user | ||
| - * what key or mouse events are being triggered. | ||
| - */ | ||
| -public class AppImage { | ||
| - public final static Map<Object, Object> RENDERING_HINTS = Map.of( | ||
| - KEY_ANTIALIASING, | ||
| - VALUE_ANTIALIAS_ON, | ||
| - KEY_ALPHA_INTERPOLATION, | ||
| - VALUE_ALPHA_INTERPOLATION_QUALITY, | ||
| - KEY_COLOR_RENDERING, | ||
| - VALUE_COLOR_RENDER_QUALITY, | ||
| - KEY_DITHERING, | ||
| - VALUE_DITHER_DISABLE, | ||
| - KEY_FRACTIONALMETRICS, | ||
| - VALUE_FRACTIONALMETRICS_ON, | ||
| - KEY_INTERPOLATION, | ||
| - VALUE_INTERPOLATION_BICUBIC, | ||
| - KEY_RENDERING, | ||
| - VALUE_RENDER_QUALITY, | ||
| - KEY_STROKE_CONTROL, | ||
| - VALUE_STROKE_PURE, | ||
| - KEY_TEXT_ANTIALIASING, | ||
| - VALUE_TEXT_ANTIALIAS_ON | ||
| - ); | ||
| - | ||
| - private final static String IMAGES = "/images"; | ||
| - private final static String IMAGES_KEY = IMAGES + "/key"; | ||
| - private final static String IMAGES_MOUSE = IMAGES + "/mouse"; | ||
| - | ||
| - public static final AppImage MOUSE_REST = mouseImage( "0" ); | ||
| - public static final AppImage MOUSE_LEFT = mouseImage( "1" ); | ||
| - public static final AppImage MOUSE_CHORD = mouseImage( "2" ); | ||
| - public static final AppImage MOUSE_RIGHT = mouseImage( "3" ); | ||
| - public static final AppImage MOUSE_LR = mouseImage( "1-3" ); | ||
| - public static final AppImage KEY_UP_SHIFT = keyUpImage( "long" ); | ||
| - public static final AppImage KEY_UP_ALT = keyUpImage( "medium" ); | ||
| - public static final AppImage KEY_UP_CTRL = keyUpImage( "medium" ); | ||
| - public static final AppImage KEY_UP_REGULAR = keyUpImage( "short" ); | ||
| - public static final AppImage KEY_DN_SHIFT = keyDnImage( "long" ); | ||
| - public static final AppImage KEY_DN_ALT = keyDnImage( "medium" ); | ||
| - public static final AppImage KEY_DN_CTRL = keyDnImage( "medium" ); | ||
| - public static final AppImage KEY_DN_REGULAR = keyDnImage( "short" ); | ||
| - | ||
| - private static AppImage mouseImage( final String prefix ) { | ||
| - return createImage( format( "%s/%s", IMAGES_MOUSE, prefix ) ); | ||
| - } | ||
| - | ||
| - private static AppImage keyImage( final String state, final String prefix ) { | ||
| - return createImage( format( "%s/%s/%s", IMAGES_KEY, state, prefix ) ); | ||
| - } | ||
| - | ||
| - private static AppImage keyUpImage( final String prefix ) { | ||
| - return keyImage( "up", prefix ); | ||
| - } | ||
| - | ||
| - private static AppImage keyDnImage( final String prefix ) { | ||
| - return keyImage( "dn", prefix ); | ||
| - } | ||
| - | ||
| - private static AppImage createImage( final String path ) { | ||
| - return new AppImage( format( "%s.svg", path ) ); | ||
| - } | ||
| - | ||
| - private final SVGUniverse mRenderer = new SVGUniverse(); | ||
| - private final String mPath; | ||
| - | ||
| - /** | ||
| - * Constructs an enumerated type that represents the different types of | ||
| - * images shown when keyboard and mouse events are triggered. | ||
| - * | ||
| - * @param path File name, including directory, to load. | ||
| - */ | ||
| - private AppImage( final String path ) { | ||
| - mPath = path; | ||
| - } | ||
| - | ||
| - public Image toImage( final Dimension dstDim ) { | ||
| - final var diagram = loadDiagram(); | ||
| - final var diaWidth = diagram.getWidth(); | ||
| - final var diaHeight = diagram.getHeight(); | ||
| - final var srcDim = new Dimension( (int) diaWidth, (int) diaHeight ); | ||
| - | ||
| - final var scaledDim = scale( srcDim, dstDim ); | ||
| - final var w = (int) scaledDim.getWidth(); | ||
| - final var h = (int) scaledDim.getHeight(); | ||
| - | ||
| - final var image = new BufferedImage( w, h, TYPE_INT_ARGB ); | ||
| - | ||
| - try { | ||
| - final Graphics2D g = image.createGraphics(); | ||
| - g.setRenderingHints( RENDERING_HINTS ); | ||
| - | ||
| - final AffineTransform transform = g.getTransform(); | ||
| - transform.setToScale( w / diaWidth, h / diaHeight ); | ||
| - | ||
| - g.setTransform( transform ); | ||
| - diagram.render( g ); | ||
| - g.dispose(); | ||
| - } catch( final SVGException e ) { | ||
| - rethrow( e ); | ||
| - } | ||
| - | ||
| - return image; | ||
| - } | ||
| - | ||
| - private SVGDiagram loadDiagram() { | ||
| - final var url = getResourceUrl(); | ||
| - return applySettings( mRenderer.getDiagram( mRenderer.loadSVG( url ) ) ); | ||
| - } | ||
| - | ||
| - private SVGDiagram applySettings( final SVGDiagram diagram ) { | ||
| - diagram.setIgnoringClipHeuristic( true ); | ||
| - return diagram; | ||
| - } | ||
| - | ||
| - private URL getResourceUrl() { | ||
| - return AppImage.class.getResource( getPath() ); | ||
| - } | ||
| - | ||
| - private String getPath() { | ||
| - return mPath; | ||
| - } | ||
| - | ||
| - private Dimension scale( final Dimension src, final Dimension dst ) { | ||
| - final var srcWidth = src.getWidth(); | ||
| - final var srcHeight = src.getHeight(); | ||
| - final var dstHeight = dst.getHeight(); | ||
| - | ||
| - var newWidth = srcWidth; | ||
| - var newHeight = srcHeight; | ||
| - | ||
| - if( newHeight < dstHeight ) { | ||
| - newHeight = dstHeight; | ||
| - newWidth = (newHeight * srcWidth) / srcHeight; | ||
| - } | ||
| - | ||
| - return new Dimension( (int) newWidth, (int) newHeight ); | ||
| - } | ||
| -} | ||
| import com.whitemagicsoftware.kmcaster.listeners.FrameDragListener; | ||
| -import com.whitemagicsoftware.kmcaster.listeners.Key; | ||
| import javax.swing.*; | ||
| import java.awt.*; | ||
| import java.awt.geom.RoundRectangle2D; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
| -import static com.whitemagicsoftware.kmcaster.AppImage.*; | ||
| -import static com.whitemagicsoftware.kmcaster.listeners.Key.*; | ||
| +import static com.whitemagicsoftware.kmcaster.HardwareSwitches.state; | ||
| +import static com.whitemagicsoftware.kmcaster.SwitchName.*; | ||
| public class EventFrame extends JFrame { | ||
| private static final float ARC = 8; | ||
| private static final Dimension FRAME_DIMENSIONS = new Dimension( 484, 70 ); | ||
| private static final Color TRANSLUCENT = new Color( .2f, .2f, .2f, 0.5f ); | ||
| private static final Color TRANSPARENT = new Color( 0, 0, 0, 0 ); | ||
| - private final Map<KeyState, Image> mKeyStates = new HashMap<>(); | ||
| - private final Map<Key, ImageComponent> mKeyViews = new HashMap<>(); | ||
| + private final HardwareSwitches mSwitches; | ||
| + private final Map<SwitchName, ImageComponent> mKeyViews = new HashMap<>(); | ||
| public EventFrame() { | ||
| final var dimensions = new Dimension( getWidth(), getHeight() - 10 ); | ||
| + mSwitches = new HardwareSwitches( dimensions ); | ||
| - final var mouseImage = MOUSE_REST.toImage( dimensions ); | ||
| + final var mouseImage = mSwitches.get( state( MOUSE_LEFT, false ) ); | ||
| final var mouseComponent = createImageComponent( mouseImage ); | ||
| - final var shiftUpImage = KEY_UP_SHIFT.toImage( dimensions ); | ||
| - final var ctrlUpImage = KEY_UP_CTRL.toImage( dimensions ); | ||
| - final var altUpImage = KEY_UP_ALT.toImage( dimensions ); | ||
| - final var regularUpImage = KEY_UP_REGULAR.toImage( dimensions ); | ||
| + final var shiftUpImage = mSwitches.get( state( KEY_SHIFT, false ) ); | ||
| + final var ctrlUpImage = mSwitches.get( state( KEY_CTRL, false ) ); | ||
| + final var altUpImage = mSwitches.get( state( KEY_ALT, false ) ); | ||
| + final var regularUpImage = mSwitches.get( state( KEY_REGULAR, false ) ); | ||
| final var shiftComponent = createImageComponent( shiftUpImage ); | ||
| content.setLayout( layout ); | ||
| content.add( panel ); | ||
| - | ||
| - final var shiftDnImage = KEY_DN_SHIFT.toImage( dimensions ); | ||
| - final var ctrlDnImage = KEY_DN_CTRL.toImage( dimensions ); | ||
| - final var altDnImage = KEY_DN_ALT.toImage( dimensions ); | ||
| - final var regularDnImage = KEY_DN_REGULAR.toImage( dimensions ); | ||
| - | ||
| - mKeyStates.put( new KeyState( KEY_SHIFT, false ), shiftUpImage ); | ||
| - mKeyStates.put( new KeyState( KEY_SHIFT, true ), shiftDnImage ); | ||
| - mKeyStates.put( new KeyState( KEY_CTRL, false ), ctrlUpImage ); | ||
| - mKeyStates.put( new KeyState( KEY_CTRL, true ), ctrlDnImage ); | ||
| - mKeyStates.put( new KeyState( KEY_ALT, false ), altUpImage ); | ||
| - mKeyStates.put( new KeyState( KEY_ALT, true ), altDnImage ); | ||
| - mKeyStates.put( new KeyState( KEY_REGULAR, false ), regularUpImage ); | ||
| - mKeyStates.put( new KeyState( KEY_REGULAR, true ), regularDnImage ); | ||
| mKeyViews.put( KEY_SHIFT, shiftComponent ); | ||
| mKeyViews.put( KEY_CTRL, ctrlComponent ); | ||
| mKeyViews.put( KEY_ALT, altComponent ); | ||
| mKeyViews.put( KEY_REGULAR, regularComponent ); | ||
| } | ||
| - protected void updateKeys( final KeyState keyState ) { | ||
| - final var image = mKeyStates.get( keyState ); | ||
| + protected void updateKeys( final HardwareState keyState ) { | ||
| + final var image = mSwitches.get( keyState ); | ||
| final var component = mKeyViews.get( keyState.getKey() ); | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster; | ||
| + | ||
| +/** | ||
| + * Responsible for defining hardware switch states. | ||
| + */ | ||
| +public class HardwareState { | ||
| + private final SwitchName mKey; | ||
| + private final String mState; | ||
| + | ||
| + public HardwareState( final SwitchName key, final boolean pressed ) { | ||
| + assert key != null; | ||
| + | ||
| + mKey = key; | ||
| + mState = Boolean.toString( pressed ); | ||
| + } | ||
| + | ||
| + public SwitchName getKey() { | ||
| + return mKey; | ||
| + } | ||
| + | ||
| + @Override | ||
| + public boolean equals( final Object o ) { | ||
| + if( this == o ) { | ||
| + return true; | ||
| + } | ||
| + if( o == null || getClass() != o.getClass() ) { | ||
| + return false; | ||
| + } | ||
| + | ||
| + final HardwareState that = (HardwareState) o; | ||
| + | ||
| + if( mKey != that.mKey ) { | ||
| + return false; | ||
| + } | ||
| + return mState.equals( that.mState ); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public int hashCode() { | ||
| + int result = mKey.hashCode(); | ||
| + result = 31 * result + mState.hashCode(); | ||
| + return result; | ||
| + } | ||
| +} | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster; | ||
| + | ||
| +import java.awt.*; | ||
| +import java.util.HashMap; | ||
| +import java.util.Map; | ||
| + | ||
| +import static com.whitemagicsoftware.kmcaster.SwitchName.*; | ||
| +import static java.lang.String.format; | ||
| + | ||
| +/** | ||
| + * Responsible for loading vector graphics representations of application | ||
| + * images. The images provide an on-screen interface that indicate to the user | ||
| + * what key or mouse events are being triggered. | ||
| + */ | ||
| +public class HardwareSwitches { | ||
| + | ||
| + private final static String DIR_IMAGES = "/images"; | ||
| + private final static String DIR_IMAGES_KEYBOARD = DIR_IMAGES + "/key"; | ||
| + private final static String DIR_IMAGES_MOUSE = DIR_IMAGES + "/mouse"; | ||
| + | ||
| + private final static SvgRasterizer sRasterizer = new SvgRasterizer(); | ||
| + | ||
| + private final Map<HardwareState, Image> mImages = new HashMap<>(); | ||
| + private final Dimension mDimension; | ||
| + | ||
| + /** | ||
| + * Constructs an enumerated type that represents the different types of | ||
| + * images shown when keyboard and mouse events are triggered. | ||
| + * | ||
| + * @param dimension The image will be scaled to the given height, aspect | ||
| + * ratio is maintained. | ||
| + */ | ||
| + public HardwareSwitches( final Dimension dimension ) { | ||
| + assert dimension != null; | ||
| + | ||
| + mDimension = dimension; | ||
| + | ||
| + final var mouseReleased = mouseImage( "0" ); | ||
| + | ||
| + for( int i = 1; i <= 3; i++ ) { | ||
| + final var s = Integer.toString( i ); | ||
| + final var switchName = SwitchName.valueFrom( "button " + s ); | ||
| + mImages.put( state( switchName, true ), mouseImage( s ) ); | ||
| + mImages.put( state( switchName, false ), mouseReleased ); | ||
| + } | ||
| + | ||
| + mImages.put( state( MOUSE_LR, true ), mouseImage( "1-3" ) ); | ||
| + mImages.put( state( MOUSE_LR, false ), mouseReleased ); | ||
| + | ||
| + mImages.put( state( KEY_ALT, true ), keyDnImage( "medium" ) ); | ||
| + mImages.put( state( KEY_ALT, false ), keyUpImage( "medium" ) ); | ||
| + mImages.put( state( KEY_CTRL, true ), keyDnImage( "medium" ) ); | ||
| + mImages.put( state( KEY_CTRL, false ), keyUpImage( "medium" ) ); | ||
| + mImages.put( state( KEY_SHIFT, true ), keyDnImage( "long" ) ); | ||
| + mImages.put( state( KEY_SHIFT, false ), keyUpImage( "long" ) ); | ||
| + mImages.put( state( KEY_REGULAR, true ), keyDnImage( "short" ) ); | ||
| + mImages.put( state( KEY_REGULAR, false ), keyUpImage( "short" ) ); | ||
| + } | ||
| + | ||
| + public Image get( final HardwareState state ) { | ||
| + return mImages.get( state ); | ||
| + } | ||
| + | ||
| + public static HardwareState state( final SwitchName name, final boolean state ) { | ||
| + return new HardwareState( name, state ); | ||
| + } | ||
| + | ||
| + private Image mouseImage( final String prefix ) { | ||
| + return createImage( format( "%s/%s", DIR_IMAGES_MOUSE, prefix ) ); | ||
| + } | ||
| + | ||
| + private Image keyImage( | ||
| + final String state, final String prefix ) { | ||
| + return createImage( | ||
| + format( "%s/%s/%s", DIR_IMAGES_KEYBOARD, state, prefix ) | ||
| + ); | ||
| + } | ||
| + | ||
| + private Image keyUpImage( final String prefix ) { | ||
| + return keyImage( "up", prefix ); | ||
| + } | ||
| + | ||
| + private Image keyDnImage( final String prefix ) { | ||
| + return keyImage( "dn", prefix ); | ||
| + } | ||
| + | ||
| + private Image createImage( final String path ) { | ||
| + assert mDimension != null; | ||
| + | ||
| + return sRasterizer.rasterize( format( "%s.svg", path ), mDimension ); | ||
| + } | ||
| +} | ||
| } | ||
| + public Image getImage() { | ||
| + return mImage; | ||
| + } | ||
| + | ||
| /** | ||
| * Repaints this component using the given image. This is a mutable |
| -/* | ||
| - * Copyright 2020 White Magic Software, Ltd. | ||
| - * | ||
| - * All rights reserved. | ||
| - * | ||
| - * Redistribution and use in source and binary forms, with or without | ||
| - * modification, are permitted provided that the following conditions are met: | ||
| - * | ||
| - * o Redistributions of source code must retain the above copyright | ||
| - * notice, this list of conditions and the following disclaimer. | ||
| - * | ||
| - * o Redistributions in binary form must reproduce the above copyright | ||
| - * notice, this list of conditions and the following disclaimer in the | ||
| - * documentation and/or other materials provided with the distribution. | ||
| - * | ||
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| - */ | ||
| -package com.whitemagicsoftware.kmcaster; | ||
| - | ||
| -import com.whitemagicsoftware.kmcaster.listeners.Key; | ||
| - | ||
| -import static java.lang.Boolean.parseBoolean; | ||
| - | ||
| -public class KeyState { | ||
| - private final Key mKey; | ||
| - private final String mState; | ||
| - | ||
| - public KeyState( final Key key, final boolean pressed ) { | ||
| - assert key != null; | ||
| - | ||
| - mKey = key; | ||
| - mState = Boolean.toString( pressed ); | ||
| - } | ||
| - | ||
| - public KeyState( final Key key, final String pressed ) { | ||
| - this( key, parseBoolean( pressed ) ); | ||
| - } | ||
| - | ||
| - public Key getKey() { | ||
| - return mKey; | ||
| - } | ||
| - | ||
| - @Override | ||
| - public boolean equals( final Object o ) { | ||
| - if( this == o ) { | ||
| - return true; | ||
| - } | ||
| - if( o == null || getClass() != o.getClass() ) { | ||
| - return false; | ||
| - } | ||
| - | ||
| - final KeyState keyState = (KeyState) o; | ||
| - | ||
| - if( mKey != keyState.mKey ) { | ||
| - return false; | ||
| - } | ||
| - return mState.equals( keyState.mState ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public int hashCode() { | ||
| - int result = mKey.hashCode(); | ||
| - result = 31 * result + mState.hashCode(); | ||
| - return result; | ||
| - } | ||
| -} | ||
| package com.whitemagicsoftware.kmcaster; | ||
| -import com.whitemagicsoftware.kmcaster.listeners.Key; | ||
| import com.whitemagicsoftware.kmcaster.listeners.KeyboardListener; | ||
| import com.whitemagicsoftware.kmcaster.listeners.MouseListener; | ||
| import org.jnativehook.GlobalScreen; | ||
| import java.beans.PropertyChangeEvent; | ||
| import java.beans.PropertyChangeListener; | ||
| import java.util.logging.Level; | ||
| +import static java.lang.Boolean.parseBoolean; | ||
| import static java.util.logging.Logger.getLogger; | ||
| import static javax.swing.SwingUtilities.invokeLater; | ||
| } | ||
| - private KeyState createKeyState( final String name, final Object bool ) { | ||
| - final var key = Key.valueFrom( name ); | ||
| - final var state = bool.toString(); | ||
| + private HardwareState createKeyState( final String name, final Object bool ) { | ||
| + assert name != null; | ||
| + assert bool != null; | ||
| - return new KeyState( key, state ); | ||
| + final var key = SwitchName.valueFrom( name ); | ||
| + final var state = parseBoolean( bool.toString() ); | ||
| + | ||
| + return new HardwareState( key, state ); | ||
| } | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster; | ||
| + | ||
| +import com.kitfox.svg.SVGDiagram; | ||
| +import com.kitfox.svg.SVGException; | ||
| +import com.kitfox.svg.SVGUniverse; | ||
| + | ||
| +import java.awt.*; | ||
| +import java.awt.geom.AffineTransform; | ||
| +import java.awt.image.BufferedImage; | ||
| +import java.net.URL; | ||
| +import java.util.Map; | ||
| + | ||
| +import static com.whitemagicsoftware.kmcaster.KmCaster.rethrow; | ||
| +import static java.awt.RenderingHints.*; | ||
| +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON; | ||
| +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; | ||
| + | ||
| +/** | ||
| + * Responsible for converting SVG images into rasterized PNG images. | ||
| + */ | ||
| +public class SvgRasterizer { | ||
| + public final static Map<Object, Object> RENDERING_HINTS = Map.of( | ||
| + KEY_ANTIALIASING, | ||
| + VALUE_ANTIALIAS_ON, | ||
| + KEY_ALPHA_INTERPOLATION, | ||
| + VALUE_ALPHA_INTERPOLATION_QUALITY, | ||
| + KEY_COLOR_RENDERING, | ||
| + VALUE_COLOR_RENDER_QUALITY, | ||
| + KEY_DITHERING, | ||
| + VALUE_DITHER_DISABLE, | ||
| + KEY_FRACTIONALMETRICS, | ||
| + VALUE_FRACTIONALMETRICS_ON, | ||
| + KEY_INTERPOLATION, | ||
| + VALUE_INTERPOLATION_BICUBIC, | ||
| + KEY_RENDERING, | ||
| + VALUE_RENDER_QUALITY, | ||
| + KEY_STROKE_CONTROL, | ||
| + VALUE_STROKE_PURE, | ||
| + KEY_TEXT_ANTIALIASING, | ||
| + VALUE_TEXT_ANTIALIAS_ON | ||
| + ); | ||
| + | ||
| + private final static SVGUniverse sRenderer = new SVGUniverse(); | ||
| + | ||
| + /** | ||
| + * Rasterizes a vector graphic to a given size using a {@link BufferedImage}. | ||
| + * The rendering hints are set to produce high quality output. | ||
| + * | ||
| + * @param path Fully qualified path to the image resource to rasterize. | ||
| + * @param dstDim The output image dimensions. | ||
| + * @return The rasterized {@link Image}. | ||
| + */ | ||
| + public Image rasterize( final String path, final Dimension dstDim ) { | ||
| + final var diagram = loadDiagram( path ); | ||
| + final var diaWidth = diagram.getWidth(); | ||
| + final var diaHeight = diagram.getHeight(); | ||
| + final var srcDim = new Dimension( (int) diaWidth, (int) diaHeight ); | ||
| + | ||
| + final var scaledDim = scale( srcDim, dstDim ); | ||
| + final var w = (int) scaledDim.getWidth(); | ||
| + final var h = (int) scaledDim.getHeight(); | ||
| + | ||
| + final var image = new BufferedImage( w, h, TYPE_INT_ARGB ); | ||
| + | ||
| + try { | ||
| + final Graphics2D g = image.createGraphics(); | ||
| + g.setRenderingHints( RENDERING_HINTS ); | ||
| + | ||
| + final AffineTransform transform = g.getTransform(); | ||
| + transform.setToScale( w / diaWidth, h / diaHeight ); | ||
| + | ||
| + g.setTransform( transform ); | ||
| + diagram.render( g ); | ||
| + g.dispose(); | ||
| + } catch( final SVGException e ) { | ||
| + rethrow( e ); | ||
| + } | ||
| + | ||
| + return image; | ||
| + } | ||
| + | ||
| + private URL getResourceUrl( final String path ) { | ||
| + return HardwareSwitches.class.getResource( path ); | ||
| + } | ||
| + | ||
| + private SVGDiagram loadDiagram( final String path ) { | ||
| + final var url = getResourceUrl( path ); | ||
| + return applySettings( sRenderer.getDiagram( sRenderer.loadSVG( url ) ) ); | ||
| + } | ||
| + | ||
| + private SVGDiagram applySettings( final SVGDiagram diagram ) { | ||
| + diagram.setIgnoringClipHeuristic( true ); | ||
| + return diagram; | ||
| + } | ||
| + | ||
| + private Dimension scale( final Dimension src, final Dimension dst ) { | ||
| + final var srcWidth = src.getWidth(); | ||
| + final var srcHeight = src.getHeight(); | ||
| + final var dstHeight = dst.getHeight(); | ||
| + | ||
| + var newWidth = srcWidth; | ||
| + var newHeight = srcHeight; | ||
| + | ||
| + if( newHeight < dstHeight ) { | ||
| + newHeight = dstHeight; | ||
| + newWidth = (newHeight * srcWidth) / srcHeight; | ||
| + } | ||
| + | ||
| + return new Dimension( (int) newWidth, (int) newHeight ); | ||
| + } | ||
| +} | ||
| +/* | ||
| + * Copyright 2020 White Magic Software, Ltd. | ||
| + * | ||
| + * All rights reserved. | ||
| + * | ||
| + * Redistribution and use in source and binary forms, with or without | ||
| + * modification, are permitted provided that the following conditions are met: | ||
| + * | ||
| + * o Redistributions of source code must retain the above copyright | ||
| + * notice, this list of conditions and the following disclaimer. | ||
| + * | ||
| + * o Redistributions in binary form must reproduce the above copyright | ||
| + * notice, this list of conditions and the following disclaimer in the | ||
| + * documentation and/or other materials provided with the distribution. | ||
| + * | ||
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| + */ | ||
| +package com.whitemagicsoftware.kmcaster; | ||
| + | ||
| +/** | ||
| + * Used for compile-time binding between change listeners input events. | ||
| + */ | ||
| +public enum SwitchName { | ||
| + KEY_ALT( "alt" ), | ||
| + KEY_CTRL( "ctrl" ), | ||
| + KEY_SHIFT( "shift" ), | ||
| + KEY_REGULAR( "regular" ), | ||
| + MOUSE_LEFT( "button 1" ), | ||
| + MOUSE_WHEEL( "button 2" ), | ||
| + MOUSE_RIGHT( "button 3" ), | ||
| + MOUSE_LR( "button 1-3" ); | ||
| + | ||
| + private final String mName; | ||
| + | ||
| + SwitchName( final String name ) { | ||
| + mName = name; | ||
| + } | ||
| + | ||
| + public boolean isName( final String name ) { | ||
| + return mName.equalsIgnoreCase( name ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Looks up the key that matches the given name, case-insensitively. | ||
| + * | ||
| + * @param name The name of the key to find in this enum. | ||
| + * @return The {@link SwitchName} object that matches the name. | ||
| + */ | ||
| + public static SwitchName valueFrom( final String name ) { | ||
| + for( final var b : SwitchName.values() ) { | ||
| + if( b.isName( name ) ) { | ||
| + return b; | ||
| + } | ||
| + } | ||
| + | ||
| + return KEY_REGULAR; | ||
| + } | ||
| + | ||
| + @Override | ||
| + public String toString() { | ||
| + return mName; | ||
| + } | ||
| +} | ||
| -/* | ||
| - * Copyright 2020 White Magic Software, Ltd. | ||
| - * | ||
| - * All rights reserved. | ||
| - * | ||
| - * Redistribution and use in source and binary forms, with or without | ||
| - * modification, are permitted provided that the following conditions are met: | ||
| - * | ||
| - * o Redistributions of source code must retain the above copyright | ||
| - * notice, this list of conditions and the following disclaimer. | ||
| - * | ||
| - * o Redistributions in binary form must reproduce the above copyright | ||
| - * notice, this list of conditions and the following disclaimer in the | ||
| - * documentation and/or other materials provided with the distribution. | ||
| - * | ||
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| - */ | ||
| -package com.whitemagicsoftware.kmcaster.listeners; | ||
| - | ||
| -/** | ||
| - * Used for compile-time binding between change listeners and keyboard | ||
| - * events. | ||
| - */ | ||
| -public enum Key { | ||
| - KEY_ALT( "alt" ), | ||
| - KEY_CTRL( "ctrl" ), | ||
| - KEY_SHIFT( "shift" ), | ||
| - KEY_REGULAR( "regular" ); | ||
| - | ||
| - private final String mName; | ||
| - | ||
| - Key( final String name ) { | ||
| - mName = name; | ||
| - } | ||
| - | ||
| - public boolean isName( final String name ) { | ||
| - return mName.equalsIgnoreCase( name ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Looks up the key that matches the given name, case-insensitively. | ||
| - * | ||
| - * @param name The name of the key to find in this enum. | ||
| - * @return The {@link Key} object that matches the name. | ||
| - */ | ||
| - public static Key valueFrom( final String name ) { | ||
| - for( final var b : Key.values() ) { | ||
| - if( b.isName( name ) ) { | ||
| - return b; | ||
| - } | ||
| - } | ||
| - | ||
| - return KEY_REGULAR; | ||
| - } | ||
| - | ||
| - @Override | ||
| - public String toString() { | ||
| - return mName; | ||
| - } | ||
| -} | ||
| package com.whitemagicsoftware.kmcaster.listeners; | ||
| +import com.whitemagicsoftware.kmcaster.SwitchName; | ||
| import org.jnativehook.keyboard.NativeKeyEvent; | ||
| import org.jnativehook.keyboard.NativeKeyListener; | ||
| import java.beans.PropertyChangeListener; | ||
| import java.beans.PropertyChangeSupport; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| -import static com.whitemagicsoftware.kmcaster.listeners.Key.*; | ||
| +import static com.whitemagicsoftware.kmcaster.SwitchName.*; | ||
| import static java.util.Map.entry; | ||
| import static org.jnativehook.NativeInputEvent.*; | ||
| * @param n New property value. | ||
| */ | ||
| - private void tryFire( final Key key, final String o, final String n ) { | ||
| + private void tryFire( final SwitchName key, final String o, final String n ) { | ||
| if( !o.equals( n ) ) { | ||
| mDispatcher.firePropertyChange( key.toString(), o, n ); | ||
| } | ||
| } | ||
| /** | ||
| - * Delegates to {@link #tryFire(Key, String, String)} with {@link Boolean} | ||
| + * Delegates to {@link #tryFire(SwitchName, String, String)} with {@link Boolean} | ||
| * values as strings. | ||
| * | ||
| * @param key The name of the property that has changed. | ||
| * @param o Old property value. | ||
| * @param n New property value. | ||
| */ | ||
| - private void tryFire( final Key key, final boolean o, final boolean n ) { | ||
| + private void tryFire( final SwitchName key, final boolean o, final boolean n ) { | ||
| tryFire( key, Boolean.toString( o ), Boolean.toString( n ) ); | ||
| } | ||
| package com.whitemagicsoftware.kmcaster.listeners; | ||
| +import com.whitemagicsoftware.kmcaster.SwitchName; | ||
| import org.jnativehook.keyboard.NativeKeyEvent; | ||
| /** | ||
| * Responsible for tracking the state of modifier keys. | ||
| */ | ||
| class KeyboardModifier { | ||
| private boolean mHeld; | ||
| private final int mMask; | ||
| - private final Key mKey; | ||
| + private final SwitchName mKey; | ||
| - KeyboardModifier( final Key key, final int mask ) { | ||
| + KeyboardModifier( final SwitchName key, final int mask ) { | ||
| assert key != null; | ||
| } | ||
| - public Key getKey() { | ||
| + public SwitchName getKey() { | ||
| return mKey; | ||
| } | ||
| Author | DaveJarvis <email> |
|---|---|
| Date | 2020-07-17 00:00:20 GMT-0700 |
| Commit | 57413d222f2be0151cb8575994bdf95eb7b31139 |
| Parent | 620583d |
| Delta | 458 lines added, 388 lines removed, 70-line increase |