From 2e47b179cf6e8403f21935f4ec9fe157fb740141 Mon Sep 17 00:00:00 2001 From: Viproz Date: Wed, 7 Nov 2018 16:16:37 +0100 Subject: [PATCH 1/2] Changed behavior of the delete key Added click selection support for Textfields --- src/controlP5/ControlWindow.java | 2 +- src/controlP5/Textfield.java | 38 +++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/controlP5/ControlWindow.java b/src/controlP5/ControlWindow.java index 968d172..0ca169f 100755 --- a/src/controlP5/ControlWindow.java +++ b/src/controlP5/ControlWindow.java @@ -843,7 +843,7 @@ public final class ControlWindow { _myApplet.frame.removeNotify( ); _myApplet.frame.setUndecorated( isUndecorated ); _myApplet.setSize( _myApplet.width , _myApplet.height ); - _myApplet.setBounds( 0 , 0 , _myApplet.width , _myApplet.height ); + //_myApplet.setBounds( 0 , 0 , _myApplet.width , _myApplet.height ); _myApplet.frame.setSize( _myApplet.width , _myApplet.height ); _myApplet.frame.addNotify( ); } diff --git a/src/controlP5/Textfield.java b/src/controlP5/Textfield.java index b42957c..851266c 100755 --- a/src/controlP5/Textfield.java +++ b/src/controlP5/Textfield.java @@ -134,8 +134,8 @@ public class Textfield extends Controller< Textfield > { keyMapping = new HashMap< Integer , TextfieldCommand >( ); keyMapping.put( ENTER , new Enter( ) ); keyMapping.put( DEFAULT , new InsertCharacter( ) ); - keyMapping.put( DELETE , new DeleteCharacter( ) ); - keyMapping.put( BACKSPACE , new DeleteCharacter( ) ); + keyMapping.put( DELETE , new DeleteCharacterRight( ) ); + keyMapping.put( BACKSPACE , new DeleteCharacterLeft( ) ); keyMapping.put( LEFT , new MoveLeft( ) ); keyMapping.put( RIGHT , new MoveRight( ) ); keyMapping.put( UP , new MoveUp( ) ); @@ -261,11 +261,27 @@ public class Textfield extends Controller< Textfield > { @Override protected void mousePressed( ) { if ( isActive ) { // TODO System.out.println("adjust cursor"); + // Multiline not supported } - int x = ( int ) ( getControlWindow( ).mouseX - x( getAbsolutePosition( ) ) ); - int y = ( int ) ( getControlWindow( ).mouseY - y( getAbsolutePosition( ) ) ); + int x = ( int ) ( getControlWindow( ).mouseX - x( getPosition( ) ) ); + int y = ( int ) ( getControlWindow( ).mouseY - y( getPosition( ) ) ); - // TODO System.out.println(x + ":" + y); + int i = 0; + int textWidth; + for(i = 0 ; i <= _myTextBuffer.length() ; i++) { + textWidth = ControlFont.getWidthFor( _myTextBuffer.substring( 0 , i ) , _myValueLabel , buffer ); + if(textWidth > x) { + if(i != 0 && textWidth-x > ControlFont.getWidthFor( _myTextBuffer.substring( i-1 , i ) , _myValueLabel , buffer )/2) { + i--; + } + break; + } + } + if(i > _myTextBuffer.length()) + i = _myTextBuffer.length(); + + setIndex(i); + setFocus( true ); } @@ -424,7 +440,7 @@ public class Textfield extends Controller< Textfield > { } } - class DeleteCharacter implements TextfieldCommand { + class DeleteCharacterLeft implements TextfieldCommand { public void execute( ) { if ( _myTextBuffer.length( ) > 0 && _myTextBufferIndex > 0 ) { @@ -434,6 +450,16 @@ public class Textfield extends Controller< Textfield > { } } + class DeleteCharacterRight implements TextfieldCommand { + + public void execute( ) { + if ( _myTextBuffer.length( ) > 0 && _myTextBufferIndex < _myTextBuffer.length( ) ) { + _myTextBuffer.deleteCharAt( _myTextBufferIndex ); + setIndex( _myTextBufferIndex ); + } + } + } + class MoveLeft implements TextfieldCommand { public void execute( ) { From 52b30f99bf536634598262037a4398ba16489659 Mon Sep 17 00:00:00 2001 From: Viproz Date: Thu, 8 Nov 2018 14:03:17 +0100 Subject: [PATCH 2/2] Added text selection Fixed double-click Fixed double call to mouse release --- src/controlP5/CColor.java | 15 ++++ src/controlP5/ControlFont.java | 17 +++- src/controlP5/ControlWindow.java | 20 ++++- src/controlP5/Controller.java | 9 +- src/controlP5/Label.java | 29 +++++++ src/controlP5/Textfield.java | 144 +++++++++++++++++++++++++++++-- 6 files changed, 218 insertions(+), 16 deletions(-) diff --git a/src/controlP5/CColor.java b/src/controlP5/CColor.java index 1720a14..ea37a04 100755 --- a/src/controlP5/CColor.java +++ b/src/controlP5/CColor.java @@ -34,6 +34,7 @@ import java.io.Serializable; public class CColor implements Serializable { private int colorBackground = 0xff003652; + private int colorSelectedBackground = 0xffffffff; private int colorForeground = 0xff00698c; private int colorActive = 0xff08a2cf; // 0699C4; private int colorCaptionLabel = 0xffffffff; @@ -52,6 +53,7 @@ public class CColor implements Serializable { protected CColor set( CColor theColor ) { colorBackground = theColor.colorBackground; + colorSelectedBackground = theColor.colorSelectedBackground; colorForeground = theColor.colorForeground; colorActive = theColor.colorActive; colorCaptionLabel = theColor.colorCaptionLabel; @@ -125,6 +127,15 @@ public class CColor implements Serializable { return this; } + public CColor setSelectedBackground( int theColor ) { + if ( ( theColor & 0xff000000 ) == 0 ) { + colorSelectedBackground = 0xff000000; + } else { + colorSelectedBackground = theColor; + } + return this; + } + public CColor setActive( int theColor ) { if ( ( theColor & 0xff000000 ) == 0 ) { colorActive = 0xff000000; @@ -164,6 +175,10 @@ public class CColor implements Serializable { return colorBackground; } + public int getSelectedBackground( ) { + return colorSelectedBackground; + } + public int getActive( ) { return colorActive; } diff --git a/src/controlP5/ControlFont.java b/src/controlP5/ControlFont.java index 53d553b..32dca88 100755 --- a/src/controlP5/ControlFont.java +++ b/src/controlP5/ControlFont.java @@ -247,9 +247,22 @@ public class ControlFont { debug( theGraphics , theLabel ); theGraphics.fill( theLabel.getColor( ) ); theGraphics.textLeading( theLabel.getLineHeight( ) ); - theGraphics.text( theLabel.getTextFormatted( ) , 0 , 0 ); + String myText = theLabel.getTextFormatted( ); + + theGraphics.fill(theLabel.getColor()); + theGraphics.text(myText.substring(0, theLabel.getSelectedStart()) , 0 , 0); + theGraphics.fill( theLabel.getSelectedColor( ) ); + theGraphics.text(myText.substring(theLabel.getSelectedStart(), theLabel.getSelectedStop()) , theGraphics.textWidth(myText.substring(0, theLabel.getSelectedStart())) , 0); + theGraphics.fill( theLabel.getColor( ) ); + theGraphics.text(myText.substring(theLabel.getSelectedStop(), myText.length()) , theGraphics.textWidth(myText.substring(0, theLabel.getSelectedStop())) , 0); + if ( RENDER_2X ) { - theGraphics.text( theLabel.getTextFormatted( ) , 0 , 0 ); + theGraphics.fill(theLabel.getColor()); + theGraphics.text(myText.substring(0, theLabel.getSelectedStart()) , 0 , 0); + theGraphics.fill( theLabel.getSelectedColor( ) ); + theGraphics.text(myText.substring(theLabel.getSelectedStart(), theLabel.getSelectedStop()) , theGraphics.textWidth(myText.substring(0, theLabel.getSelectedStart())) , 0); + theGraphics.fill( theLabel.getColor( ) ); + theGraphics.text(myText.substring(theLabel.getSelectedStop(), myText.length()) , theGraphics.textWidth(myText.substring(0, theLabel.getSelectedStop())) , 0); } } diff --git a/src/controlP5/ControlWindow.java b/src/controlP5/ControlWindow.java index 0ca169f..0b096f3 100755 --- a/src/controlP5/ControlWindow.java +++ b/src/controlP5/ControlWindow.java @@ -75,6 +75,8 @@ public final class ControlWindow { protected int mouseY; protected int pmouseX; protected int pmouseY; + protected int pclickMouseX; + protected int pclickMouseY; protected boolean mousePressed; protected long mousePressedTime; protected long pmousePressedTime; @@ -401,7 +403,9 @@ public final class ControlWindow { * boolean). */ public void mouseEvent( int theX , int theY , boolean pressed ) { - + pclickMouseX = mouseX; + pclickMouseY = mouseY; + mouseX = theX - cp5.pgx - cp5.ox; mouseY = theY - cp5.pgy - cp5.oy; @@ -440,12 +444,16 @@ public final class ControlWindow { */ public void mouseEvent( MouseEvent theMouseEvent ) { if ( isMouse ) { + int oldX = mouseX; + int oldY = mouseY; mouseX = theMouseEvent.getX( ) - cp5.pgx - cp5.ox; mouseY = theMouseEvent.getY( ) - cp5.pgy - cp5.oy; if ( theMouseEvent.getAction( ) == MouseEvent.PRESS ) { mousePressedEvent( ); } if ( theMouseEvent.getAction( ) == MouseEvent.RELEASE ) { + pclickMouseX = oldX; + pclickMouseY = oldY; mouseReleasedEvent( ); } if ( theMouseEvent.getAction( ) == MouseEvent.WHEEL ) { @@ -600,7 +608,7 @@ public final class ControlWindow { pmouseX = mouseX; pmouseY = mouseY; - + /* draw Tooltip here. */ cp5.getTooltip( ).draw( this ); @@ -921,6 +929,14 @@ public final class ControlWindow { return pmouseY; } + public int getPreviousClickX( ) { + return pclickMouseX; + } + + public int getPreviousClickY( ) { + return pclickMouseY; + } + public Pointer set( int theX , int theY ) { setX( theX ); setY( theY ); diff --git a/src/controlP5/Controller.java b/src/controlP5/Controller.java index 78ffc0c..2d63d39 100755 --- a/src/controlP5/Controller.java +++ b/src/controlP5/Controller.java @@ -545,11 +545,11 @@ public abstract class Controller< T > implements ControllerInterface< T > , CDra } public int px( ) { - return ( int ) ( _myControlWindow.pmouseX - Controller.x( _myParent.getAbsolutePosition( ) ) - Controller.x( position ) ); + return ( int ) ( _myControlWindow.pclickMouseX - Controller.x( _myParent.getAbsolutePosition( ) ) - Controller.x( position ) ); } public int py( ) { - return ( int ) ( _myControlWindow.pmouseY - Controller.y( _myParent.getAbsolutePosition( ) ) - Controller.y( position ) ); + return ( int ) ( _myControlWindow.pclickMouseY - Controller.y( _myParent.getAbsolutePosition( ) ) - Controller.y( position ) ); } public int dx( ) { @@ -590,7 +590,7 @@ public abstract class Controller< T > implements ControllerInterface< T > , CDra onPress( ); cp5.getControlBroadcaster( ).invokeAction( new CallbackEvent( this , ACTION_PRESS ) ); callListener( ACTION_PRESS ); - if ( getPointer( ).dt( ) < 500 ) { + if ( getPointer( ).dt( ) < 500 && getPointer( ).dx() == 0 && getPointer( ).dy() == 0 ) { onDoublePress( ); callListener( ACTION_DOUBLE_PRESS ); } @@ -628,8 +628,7 @@ public abstract class Controller< T > implements ControllerInterface< T > , CDra onReleaseOutside( ); cp5.getControlBroadcaster( ).invokeAction( new CallbackEvent( this , ACTION_RELEASE_OUTSIDE ) ); callListener( ACTION_RELEASE_OUTSIDE ); - } - if ( this instanceof Textfield ) { + } else if ( this instanceof Textfield ) { mouseReleasedOutside( ); onReleaseOutside( ); callListener( ACTION_RELEASE_OUTSIDE ); diff --git a/src/controlP5/Label.java b/src/controlP5/Label.java index a7f75b8..52a8a60 100755 --- a/src/controlP5/Label.java +++ b/src/controlP5/Label.java @@ -48,6 +48,7 @@ public class Label implements CDrawable { protected ControllerStyle _myControllerStyle = new ControllerStyle( ); protected boolean isVisible = true; protected int _myColor = 0xffffffff; + protected int _mySelectedColor = 0xff000000; protected boolean isColorBackground; protected boolean isToUpperCase = isToUpperCaseDefault; protected boolean changed; @@ -67,6 +68,8 @@ public class Label implements CDrawable { protected Labeltype _myLabeltype; protected int _myTextHeight = 1; protected float offsetYratio = 0; + protected int _mySelectedStart = 0; + protected int _mySelectedStop = 0; private ControlP5 cp5; private Label( Label theLabel ) { @@ -366,6 +369,16 @@ public class Label implements CDrawable { return _myColor; } + public int getSelectedColor( ) { + return _mySelectedColor; + } + + public Label setSelectedColor( int theColor ) { + _mySelectedColor = theColor; + setChanged( true ); + return this; + } + public Label setColorBackground( int theColor ) { enableColorBackground( ); _myColorBackground = theColor; @@ -404,6 +417,22 @@ public class Label implements CDrawable { return isToUpperCase; } + public int getSelectedStart( ) { + return _mySelectedStart; + } + + public int getSelectedStop( ) { + return _mySelectedStop; + } + + public void setSelectedStart(int start) { + _mySelectedStart = start; + } + + public void setSelectedStop(int stop) { + _mySelectedStop = stop; + } + protected Label copy( ) { return new Label( this ); } diff --git a/src/controlP5/Textfield.java b/src/controlP5/Textfield.java index 851266c..aeb4fd5 100755 --- a/src/controlP5/Textfield.java +++ b/src/controlP5/Textfield.java @@ -71,6 +71,9 @@ public class Textfield extends Controller< Textfield > { protected boolean isPasswordMode; protected boolean autoclear = true; protected int _myColorCursor = 0x88ffffff; + protected int startDragIndex = 0; + protected int currentDragIndex = 0; + protected boolean isDragging = false; private PGraphics buffer; public enum InputFilter { @@ -266,6 +269,9 @@ public class Textfield extends Controller< Textfield > { int x = ( int ) ( getControlWindow( ).mouseX - x( getPosition( ) ) ); int y = ( int ) ( getControlWindow( ).mouseY - y( getPosition( ) ) ); + _myValueLabel.setSelectedStart(0); + _myValueLabel.setSelectedStop(0); + int i = 0; int textWidth; for(i = 0 ; i <= _myTextBuffer.length() ; i++) { @@ -286,11 +292,82 @@ public class Textfield extends Controller< Textfield > { } @Override protected void mouseReleasedOutside( ) { - if ( isKeepFocus == false ) { + if ( isKeepFocus == false && !isDragging ) { isTexfieldActive = isActive = false; + startDragIndex = 0; + currentDragIndex = 0; + updateLabelSelection(); } + isDragging = false; } + @Override protected void onStartDrag( ) { + int x = (int) (getControlWindow().mouseX - x(getPosition())); + int i = 0; + int textWidth; + isDragging = true; + for(i = 0 ; i <= _myTextBuffer.length() ; i++) { + textWidth = ControlFont.getWidthFor( _myTextBuffer.substring( 0 , i ) , _myValueLabel , buffer ); + if(textWidth > x) { + if(i != 0 && textWidth-x > ControlFont.getWidthFor( _myTextBuffer.substring( i-1 , i ) , _myValueLabel , buffer )/2) { + i--; + } + break; + } + } + if(i > _myTextBuffer.length()) + i = _myTextBuffer.length(); + + startDragIndex = i; + setIndex(i); + + setFocus( true ); + } + + @Override protected void onDrag( ) { + int x = (int) (getControlWindow().mouseX - x(getPosition())); + int i = 0; + int textWidth; + for(i = 0 ; i <= _myTextBuffer.length() ; i++) { + textWidth = ControlFont.getWidthFor( _myTextBuffer.substring( 0 , i ) , _myValueLabel , buffer ); + if(textWidth > x) { + if(i != 0 && textWidth-x > ControlFont.getWidthFor( _myTextBuffer.substring( i-1 , i ) , _myValueLabel , buffer )/2) { + i--; + } + break; + } + } + if(i > _myTextBuffer.length()) + i = _myTextBuffer.length(); + + currentDragIndex = i; + updateLabelSelection(); + + setIndex(i); + setFocus( true ); + } + + @Override protected void onDoublePress( ) { + startDragIndex = 0; + currentDragIndex = _myTextBuffer.length(); + updateLabelSelection(); + setIndex(currentDragIndex); + } + + @Override protected void onEndDrag( ) { + isDragging = false; + } + + protected void updateLabelSelection() { + if(startDragIndex > currentDragIndex) { + _myValueLabel.setSelectedStart(currentDragIndex); + _myValueLabel.setSelectedStop(startDragIndex); + } else { + _myValueLabel.setSelectedStart(startDragIndex); + _myValueLabel.setSelectedStop(currentDragIndex); + } + } + public int getIndex( ) { return _myTextBufferIndex; } @@ -317,11 +394,21 @@ public class Textfield extends Controller< Textfield > { @Override public void draw( PGraphics theGraphics ) { + final String text = passCheck( getText( ) ); + theGraphics.pushStyle( ); theGraphics.fill( color.getBackground( ) ); theGraphics.pushMatrix( ); theGraphics.translate( x( position ) , y( position ) ); - theGraphics.rect( 0 , 0 , getWidth( ) , getHeight( ) ); + theGraphics.fill(color.getBackground()); + theGraphics.rect(0, 0, getWidth(), getHeight()); + + //theGraphics.fill(color.getBackground()); + //theGraphics.rect(0, 0, theGraphics.textWidth(text.substring(0, _myValueLabel.getSelectedStart())), getHeight()); + theGraphics.fill(color.getSelectedBackground()); + theGraphics.rect(ControlFont.getWidthFor(text.substring(0, _myValueLabel.getSelectedStart()), _myValueLabel, buffer), 0, ControlFont.getWidthFor(text.substring(_myValueLabel.getSelectedStart(), _myValueLabel.getSelectedStop()), _myValueLabel, buffer), getHeight()); + theGraphics.fill(color.getBackground()); + theGraphics.noStroke( ); theGraphics.fill( _myColorCursor ); @@ -330,7 +417,6 @@ public class Textfield extends Controller< Textfield > { buffer.beginDraw( ); buffer.background( 0 , 0 ); - final String text = passCheck( getText( ) ); final int textWidth = ControlFont.getWidthFor( text.substring( 0 , _myTextBufferIndex ) , _myValueLabel , buffer ); final int dif = PApplet.max( textWidth - _myValueLabel.getWidth( ) , 0 ); final int _myTextBufferIndexPosition = ControlFont.getWidthFor( text.substring( 0 , _myTextBufferIndex ) , _myValueLabel , buffer ); @@ -417,6 +503,20 @@ public class Textfield extends Controller< Textfield > { } if ( _myInputFilter.apply( cp5.getKey( ) ) ) { + if(startDragIndex != currentDragIndex) { + int strt = startDragIndex; + int current = currentDragIndex; + startDragIndex = 0; + currentDragIndex = 0; + updateLabelSelection(); + if(strt > current) { + _myTextBuffer.delete(current, strt); + setIndex(current); + } else { + _myTextBuffer.delete(strt, current); + setIndex(strt); + } + } _myTextBuffer.insert( _myTextBufferIndex , ( char ) cp5.getKey( ) ); setIndex( _myTextBufferIndex + 1 ); } @@ -444,8 +544,23 @@ public class Textfield extends Controller< Textfield > { public void execute( ) { if ( _myTextBuffer.length( ) > 0 && _myTextBufferIndex > 0 ) { - _myTextBuffer.deleteCharAt( _myTextBufferIndex - 1 ); - setIndex( _myTextBufferIndex - 1 ); + if(startDragIndex != currentDragIndex) { + int strt = startDragIndex; + int current = currentDragIndex; + startDragIndex = 0; + currentDragIndex = 0; + updateLabelSelection(); + if(strt > current) { + _myTextBuffer.delete(current, strt); + setIndex(current); + } else { + _myTextBuffer.delete(strt, current); + setIndex(strt); + } + } else { + _myTextBuffer.deleteCharAt( _myTextBufferIndex - 1 ); + setIndex( _myTextBufferIndex - 1 ); + } } } } @@ -454,8 +569,23 @@ public class Textfield extends Controller< Textfield > { public void execute( ) { if ( _myTextBuffer.length( ) > 0 && _myTextBufferIndex < _myTextBuffer.length( ) ) { - _myTextBuffer.deleteCharAt( _myTextBufferIndex ); - setIndex( _myTextBufferIndex ); + if(startDragIndex != currentDragIndex) { + int strt = startDragIndex; + int current = currentDragIndex; + startDragIndex = 0; + currentDragIndex = 0; + updateLabelSelection(); + if(strt > current) { + _myTextBuffer.delete(current, strt); + setIndex(current); + } else { + _myTextBuffer.delete(strt, current); + setIndex(strt); + } + } else { + _myTextBuffer.deleteCharAt( _myTextBufferIndex ); + setIndex( _myTextBufferIndex ); + } } } }