Merge commit '77d3a60869e7a780c6ae069e51530e1eacece5e2'
[fanfix.git] / src / jexer / bits / MnemonicString.java
CommitLineData
daa4106c 1/*
df8de03f
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
df8de03f 5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
df8de03f 7 *
e16dda65
KL
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
df8de03f 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
df8de03f 17 *
e16dda65
KL
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
7b5261bc
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
df8de03f
KL
28 */
29package jexer.bits;
30
31/**
43ad7b6c
KL
32 * MnemonicString is used to render a string like "&File" into a
33 * highlighted 'F' and the rest of 'ile'. To insert a literal '&', use
34 * two '&&' characters, e.g. "&File && Stuff" would be
35 * "File & Stuff" with the first 'F' highlighted.
df8de03f 36 */
051e2913 37public class MnemonicString {
df8de03f 38
d36057df
KL
39 // ------------------------------------------------------------------------
40 // Variables --------------------------------------------------------------
41 // ------------------------------------------------------------------------
42
df8de03f 43 /**
7b5261bc 44 * Keyboard shortcut to activate this item.
df8de03f 45 */
218d18db 46 private int shortcut;
df8de03f
KL
47
48 /**
7b5261bc 49 * Location of the highlighted character.
df8de03f 50 */
7b5261bc 51 private int shortcutIdx = -1;
df8de03f 52
9f613a0c
KL
53 /**
54 * Screen location of the highlighted character (number of text cells
55 * required to display from the beginning to shortcutIdx).
56 */
57 private int screenShortcutIdx = -1;
58
df8de03f 59 /**
7b5261bc 60 * The raw (uncolored) string.
df8de03f 61 */
7b5261bc 62 private String rawLabel;
df8de03f 63
d36057df
KL
64 // ------------------------------------------------------------------------
65 // Constructors -----------------------------------------------------------
66 // ------------------------------------------------------------------------
329fd62e 67
df8de03f 68 /**
7b5261bc 69 * Public constructor.
df8de03f
KL
70 *
71 * @param label widget label or title. Label must contain a keyboard
43ad7b6c 72 * shortcut, denoted by prefixing a letter with "&", e.g. "&File"
df8de03f 73 */
7b5261bc 74 public MnemonicString(final String label) {
df8de03f 75
7b5261bc 76 // Setup the menu shortcut
218d18db 77 StringBuilder newLabel = new StringBuilder();
7b5261bc
KL
78 boolean foundAmp = false;
79 boolean foundShortcut = false;
80 int scanShortcutIdx = 0;
9f613a0c 81 int scanScreenShortcutIdx = 0;
218d18db
KL
82 for (int i = 0; i < label.length();) {
83 int c = label.codePointAt(i);
84 i += Character.charCount(c);
85
7b5261bc
KL
86 if (c == '&') {
87 if (foundAmp) {
218d18db 88 newLabel.append('&');
7b5261bc 89 scanShortcutIdx++;
9f613a0c 90 scanScreenShortcutIdx++;
7b5261bc
KL
91 } else {
92 foundAmp = true;
93 }
94 } else {
218d18db 95 newLabel.append(Character.toChars(c));
7b5261bc
KL
96 if (foundAmp) {
97 if (!foundShortcut) {
98 shortcut = c;
99 foundAmp = false;
100 foundShortcut = true;
101 shortcutIdx = scanShortcutIdx;
9f613a0c 102 screenShortcutIdx = scanScreenShortcutIdx;
7b5261bc
KL
103 }
104 } else {
105 scanShortcutIdx++;
9f613a0c 106 scanScreenShortcutIdx += StringUtils.width(c);
7b5261bc
KL
107 }
108 }
109 }
218d18db 110 this.rawLabel = newLabel.toString();
df8de03f 111 }
d36057df
KL
112
113 // ------------------------------------------------------------------------
114 // MnemonicString ---------------------------------------------------------
115 // ------------------------------------------------------------------------
116
117 /**
118 * Get the keyboard shortcut character.
119 *
120 * @return the highlighted character
121 */
218d18db 122 public int getShortcut() {
d36057df
KL
123 return shortcut;
124 }
125
126 /**
127 * Get location of the highlighted character.
128 *
129 * @return location of the highlighted character
130 */
131 public int getShortcutIdx() {
132 return shortcutIdx;
133 }
134
9f613a0c
KL
135 /**
136 * Get the screen location of the highlighted character.
137 *
138 * @return the number of text cells required to display from the
139 * beginning of the label to shortcutIdx
140 */
141 public int getScreenShortcutIdx() {
142 return screenShortcutIdx;
143 }
144
d36057df
KL
145 /**
146 * Get the raw (uncolored) string.
147 *
148 * @return the raw (uncolored) string
149 */
150 public String getRawLabel() {
151 return rawLabel;
152 }
153
df8de03f 154}