Browse Source

Added support for insert text mode.

pull/170/head
weisj 5 years ago
parent
commit
a9a190fecb
  1. 2
      core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java
  2. 67
      core/src/main/java/com/github/weisj/darklaf/ui/text/DarkCaret.java
  3. 3
      core/src/main/java/com/github/weisj/darklaf/ui/text/DarkEditorPaneUI.java
  4. 16
      core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java
  5. 51
      core/src/main/java/com/github/weisj/darklaf/ui/text/action/DarkTextAction.java
  6. 76
      core/src/main/java/com/github/weisj/darklaf/ui/text/action/DeleteNextCharAction.java
  7. 76
      core/src/main/java/com/github/weisj/darklaf/ui/text/action/DeletePreviousCharAction.java
  8. 51
      core/src/main/java/com/github/weisj/darklaf/ui/text/action/ToggleInsertAction.java

2
core/src/main/java/com/github/weisj/darklaf/task/InputDefaultsInitTask.java

@ -100,7 +100,7 @@ public class InputDefaultsInitTask implements DefaultsInitTask {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, mask), DefaultEditorKit.cutAction);
}
private static void patchComboBox(final UIDefaults metalDefaults, final UIDefaults defaults) {
private void patchComboBox(final UIDefaults metalDefaults, final UIDefaults defaults) {
defaults.remove("ComboBox.ancestorInputMap");
defaults.remove("ComboBox.actionMap");
defaults.put("ComboBox.ancestorInputMap", metalDefaults.get("ComboBox.ancestorInputMap"));

67
core/src/main/java/com/github/weisj/darklaf/ui/text/DarkCaret.java

@ -51,22 +51,66 @@ public class DarkCaret extends DefaultCaret implements UIResource {
private final DarkHighlightPainter selectionPainter;
private MouseEvent selectedWordEvent;
private CaretStyle style;
private CaretStyle insertStyle;
private boolean alwaysVisible;
private boolean pasteOnMiddleMouseClick;
private boolean insertMode;
private boolean deleteCharMode;
public DarkCaret() {
this(CaretStyle.THICK_VERTICAL_LINE_STYLE);
this(null, null);
}
public DarkCaret(final CaretStyle style) {
public DarkCaret(final CaretStyle style, final CaretStyle insertStyle) {
seg = new Segment();
setStyle(style);
setStyles(style, insertStyle);
selectionPainter = new DarkHighlightPainter();
selectLine = new SelectLineAction();
selectWord = new SelectWordAction();
pasteOnMiddleMouseClick = true;
}
public boolean isInsertMode() {
return insertMode;
}
public void setInsertMode(final boolean insertMode) {
if (this.insertMode != insertMode) {
this.insertMode = insertMode;
repaint();
}
}
public void setDeleteCharMode(final boolean deleteCharMode) {
this.deleteCharMode = deleteCharMode;
}
@Override
public int getMark() {
int mark = super.getMark();
int dot = super.getDot();
JTextComponent target = getComponent();
if (isInsertMode()
&& target != null
&& mark == dot
&& !deleteCharMode
&& !isEndOfLine(target, dot)) {
mark += 1;
}
return mark;
}
private boolean isEndOfLine(final JTextComponent target, final int dot) {
Document doc = target.getDocument();
if (dot >= doc.getLength()) return true;
try {
return target.getText(dot, 1).equals("\n");
} catch (BadLocationException e) {
return false;
}
}
public boolean getRoundedSelectionEdges() {
return ((DarkHighlightPainter) getSelectionPainter()).getRoundedEdges();
}
@ -76,16 +120,21 @@ public class DarkCaret extends DefaultCaret implements UIResource {
}
public CaretStyle getStyle() {
return style;
return isInsertMode() ? insertStyle : style;
}
public void setStyle(final CaretStyle style) {
public void setStyles(final CaretStyle style, final CaretStyle insertStyle) {
CaretStyle s = style;
CaretStyle is = insertStyle;
if (s == null) {
s = CaretStyle.THICK_VERTICAL_LINE_STYLE;
}
if (s != this.style) {
if (is == null) {
is = CaretStyle.BLOCK_BORDER_STYLE;
}
if (s != this.style || is != this.insertStyle) {
this.style = s;
this.insertStyle = is;
repaint();
}
}
@ -305,18 +354,18 @@ public class DarkCaret extends DefaultCaret implements UIResource {
if (textAreaBg == null) {
textAreaBg = Color.white;
}
switch (style) {
switch (getStyle()) {
case BLOCK_STYLE :
g.setXORMode(textAreaBg);
g.fillRect(r.x, r.y, r.width, r.height);
break;
case BLOCK_BORDER_STYLE :
PaintUtil.drawRect(g, r.x, r.y, r.width, r.height, style.getSize());
PaintUtil.drawRect(g, r.x, r.y, r.width, r.height, getStyle().getSize());
break;
case UNDERLINE_STYLE :
g.setXORMode(textAreaBg);
int y = r.y + r.height;
g.fillRect(r.x, y - style.getSize(), r.width, style.getSize());
g.fillRect(r.x, y - getStyle().getSize(), r.width, getStyle().getSize());
break;
case THICK_VERTICAL_LINE_STYLE :
case VERTICAL_LINE_STYLE :

3
core/src/main/java/com/github/weisj/darklaf/ui/text/DarkEditorPaneUI.java

@ -28,7 +28,6 @@ import java.awt.*;
import java.beans.PropertyChangeEvent;
import javax.swing.*;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.*;
@ -243,7 +242,7 @@ public class DarkEditorPaneUI extends DarkTextUI {
* Fetch an action map to use. The map for a JEditorPane is not shared because it changes with the EditorKit.
*/
public ActionMap getActionMap() {
ActionMap am = new ActionMapUIResource();
ActionMap am = super.getActionMap();
am.put("requestFocus", new FocusAction());
EditorKit editorKit = getEditorKit(getComponent());
if (editorKit != null) {

16
core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java

@ -48,6 +48,9 @@ import com.github.weisj.darklaf.graphics.PaintUtil;
import com.github.weisj.darklaf.ui.list.DarkListUI;
import com.github.weisj.darklaf.ui.table.DarkTableCellBorder;
import com.github.weisj.darklaf.ui.table.DarkTableUI;
import com.github.weisj.darklaf.ui.text.action.DeleteNextCharAction;
import com.github.weisj.darklaf.ui.text.action.DeletePreviousCharAction;
import com.github.weisj.darklaf.ui.text.action.ToggleInsertAction;
import com.github.weisj.darklaf.ui.tree.DarkTreeUI;
import com.github.weisj.darklaf.util.DarkUIUtil;
import com.github.weisj.darklaf.util.PropertyUtil;
@ -65,6 +68,8 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi
public static final String KEY_IS_LIST_RENDER = DarkListUI.KEY_IS_LIST_RENDERER;
public static final String KEY_DEFAULT_TEXT = KEY_PREFIX + "defaultText";
protected static final String TOGGLE_INSERT = "toggle_insert";
protected JTextComponent editor;
private FocusListener focusListener = new FocusListener() {
@Override
@ -89,11 +94,15 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi
@Override
protected Caret createCaret() {
return new DarkCaret(getDefaultCaretStyle());
return new DarkCaret(getDefaultCaretStyle(), getDefaultInsertCaretStyle());
}
protected abstract DarkCaret.CaretStyle getDefaultCaretStyle();
protected DarkCaret.CaretStyle getDefaultInsertCaretStyle() {
return DarkCaret.CaretStyle.BLOCK_STYLE;
}
protected Color disabledColor;
protected Color inactiveColor;
@ -342,6 +351,7 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi
if (shared != null) {
map.setParent(shared);
}
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), TOGGLE_INSERT);
return map;
}
@ -366,6 +376,7 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi
* processed when the text component has focus and isn't editable.
*
*/
System.out.println(getEditorKit(editor));
if (getEditorKit(editor) instanceof DefaultEditorKit) {
if (map != null) {
Object obj = map.get(DefaultEditorKit.insertBreakAction);
@ -373,6 +384,9 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi
Action action = new TextActionWrapper((TextAction) obj);
componentMap.put(action.getValue(Action.NAME), action);
}
map.put(DefaultEditorKit.deletePrevCharAction, new DeletePreviousCharAction());
map.put(DefaultEditorKit.deleteNextCharAction, new DeleteNextCharAction());
map.put(TOGGLE_INSERT, new ToggleInsertAction());
}
}
if (map != null) {

51
core/src/main/java/com/github/weisj/darklaf/ui/text/action/DarkTextAction.java

@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.text.action;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;
import com.github.weisj.darklaf.ui.text.DarkCaret;
public abstract class DarkTextAction extends TextAction {
/**
* Creates a new JTextAction object.
*
* @param name the name of the action
*/
public DarkTextAction(final String name) {
super(name);
}
protected void setupDeleteMode(final JTextComponent textComponent, final boolean isDeleteMode) {
if (textComponent == null) return;
Caret c = textComponent.getCaret();
if (c instanceof DarkCaret) {
((DarkCaret) c).setDeleteCharMode(isDeleteMode);
}
}
}

76
core/src/main/java/com/github/weisj/darklaf/ui/text/action/DeleteNextCharAction.java

@ -0,0 +1,76 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.text.action;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.*;
public class DeleteNextCharAction extends DarkTextAction {
public DeleteNextCharAction() {
super(DefaultEditorKit.deleteNextCharAction);
}
@Override
public void actionPerformed(final ActionEvent e) {
JTextComponent target = getTextComponent(e);
setupDeleteMode(target, true);
boolean beep = true;
if ((target != null) && (target.isEditable())) {
try {
Document doc = target.getDocument();
Caret caret = target.getCaret();
int dot = caret.getDot();
int mark = caret.getMark();
if (dot != mark) {
doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
beep = false;
} else if (dot < doc.getLength()) {
int delChars = 1;
if (dot < doc.getLength() - 1) {
String dotChars = doc.getText(dot, 2);
char c0 = dotChars.charAt(0);
char c1 = dotChars.charAt(1);
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
c1 >= '\uDC00' && c1 <= '\uDFFF') {
delChars = 2;
}
}
doc.remove(dot, delChars);
beep = false;
}
} catch (BadLocationException ignored) {}
}
if (beep) {
UIManager.getLookAndFeel().provideErrorFeedback(target);
}
setupDeleteMode(target, false);
}
}

76
core/src/main/java/com/github/weisj/darklaf/ui/text/action/DeletePreviousCharAction.java

@ -0,0 +1,76 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.text.action;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.*;
public class DeletePreviousCharAction extends DarkTextAction {
public DeletePreviousCharAction() {
super(DefaultEditorKit.deletePrevCharAction);
}
@Override
public void actionPerformed(final ActionEvent e) {
JTextComponent target = getTextComponent(e);
setupDeleteMode(target, true);
boolean beep = true;
if ((target != null) && (target.isEditable())) {
try {
Document doc = target.getDocument();
Caret caret = target.getCaret();
int dot = caret.getDot();
int mark = caret.getMark();
if (dot != mark) {
doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
beep = false;
} else if (dot > 0) {
int delChars = 1;
if (dot > 1) {
String dotChars = doc.getText(dot - 2, 2);
char c0 = dotChars.charAt(0);
char c1 = dotChars.charAt(1);
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
c1 >= '\uDC00' && c1 <= '\uDFFF') {
delChars = 2;
}
}
doc.remove(dot - delChars, delChars);
beep = false;
}
} catch (BadLocationException ignored) {}
}
if (beep) {
UIManager.getLookAndFeel().provideErrorFeedback(target);
}
setupDeleteMode(target, false);
}
}

51
core/src/main/java/com/github/weisj/darklaf/ui/text/action/ToggleInsertAction.java

@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.text.action;
import java.awt.event.ActionEvent;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;
import com.github.weisj.darklaf.ui.text.DarkCaret;
public class ToggleInsertAction extends TextAction {
public ToggleInsertAction() {
super("toggle insert mode");
}
@Override
public void actionPerformed(final ActionEvent e) {
JTextComponent target = getTextComponent(e);
if (target != null) {
Caret c = target.getCaret();
if (c instanceof DarkCaret) {
((DarkCaret) c).setInsertMode(!((DarkCaret) c).isInsertMode());
}
}
}
}
Loading…
Cancel
Save