Configuration files support

This commit is contained in:
Dmitry Isaenko 2019-10-19 09:34:42 +03:00
parent 8de2e05af1
commit e6f1a50622
24 changed files with 1108 additions and 342 deletions

View file

@ -13,6 +13,7 @@ LogiLed is a Logitech G513 Carbon GUI driver for adjusting backlight and effects
#### Used libraries & resources
* [OpenJFX](https://wiki.openjdk.java.net/display/OpenJFX/Main)
* [usb4java](https://mvnrepository.com/artifact/org.usb4java/usb4java)
* [Jackson](https://github.com/FasterXML/jackson)
* Few icons taken from: [materialdesignicons.com](http://materialdesignicons.com/)
* Special thanks to pioneers and superstars who created, contributed and maintaining [g810-led](https://github.com/MatMoul/g810-led) project!
@ -55,7 +56,12 @@ Want to support development? Make a donation* (see below):
#### TODO
* [x] Tray support
* [ ] Configuration files support
* [ ] tray icon size checks
* [x] Configuration files support
* [ ] Settings
* [ ] Tray icon settings
* [ ] Autoload
* [ ] Headless mode (CLI)
* [ ] Fix UI
* [ ] Add opened file name to info pane
* [ ] Dark theme

23
pom.xml
View file

@ -6,7 +6,7 @@
<groupId>loper</groupId>
<artifactId>LogiLed</artifactId>
<version>0.3-SNAPSHOT</version>
<version>0.4-SNAPSHOT</version>
<!-- <url></url> -->
<description>
@ -143,6 +143,27 @@
<version>1.3.0</version>
<scope>compile</scope>
</dependency>
<!-- Jackson support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
<scope>compile</scope>
</dependency>
<!--
<dependency>
<groupId>net.java.dev.jna</groupId>

View file

@ -0,0 +1,28 @@
package logiled.Config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.awt.*;
import java.io.IOException;
public class HexDeserializer extends StdDeserializer<Byte> {
public HexDeserializer(){
this(null);
}
public HexDeserializer(Class<?> aByte){
super(aByte);
}
@Override
public Byte deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return (byte) Integer.parseInt(jsonParser.getValueAsString(), 16);
}
}

View file

@ -0,0 +1,23 @@
package logiled.Config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
public class HexSerializer extends StdSerializer<Byte> {
public HexSerializer(){
this(null);
}
public HexSerializer(Class<Byte> aByte){
super(aByte);
}
@Override
public void serialize(Byte aByte, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(String.format("%02x", aByte));
}
}

View file

@ -0,0 +1,57 @@
package logiled.Config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import logiled.Controllers.Model.LoRule;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LoRuleDeSerializer extends StdDeserializer<LoRule> {
public LoRuleDeSerializer(){
this(null);
}
public LoRuleDeSerializer(Class<LoRule> aRule){
super(aRule);
}
@Override
public LoRule deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
List<String> values = new ArrayList<>();
ObjectCodec codec = jsonParser.getCodec();
JsonNode node = codec.readTree(jsonParser);
final byte red = (byte) Integer.parseInt(node.get("RED").asText(), 16);
final byte green = (byte) Integer.parseInt(node.get("GREEN").asText(), 16);
final byte blue = (byte) Integer.parseInt(node.get("BLUE").asText(), 16);
Iterator<JsonNode> iterator = node.get("Codes").elements();
while (iterator.hasNext())
values.add(iterator.next().asText());
return new LoRule(red, green, blue, values.toArray(new String[0]));
}
/*
@Override
public void serialize(LoRule loRule, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("RED", String.format("%02x", loRule.getRed()));
jsonGenerator.writeStringField("GREEN", String.format("%02x", loRule.getGreen()));
jsonGenerator.writeStringField("BLUE", String.format("%02x", loRule.getBlue()));
jsonGenerator.writeArrayFieldStart("Codes");
for (String s : loRule.getKeyLedCode())
jsonGenerator.writeString(s);
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
}
*/
}

View file

@ -0,0 +1,32 @@
package logiled.Config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import logiled.Controllers.Model.LoRule;
import java.io.IOException;
public class LoRuleSerializer extends StdSerializer<LoRule> {
public LoRuleSerializer(){
this(null);
}
public LoRuleSerializer(Class<LoRule> aRule){
super(aRule);
}
@Override
public void serialize(LoRule loRule, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("RED", String.format("%02x", loRule.getRed()));
jsonGenerator.writeStringField("GREEN", String.format("%02x", loRule.getGreen()));
jsonGenerator.writeStringField("BLUE", String.format("%02x", loRule.getBlue()));
jsonGenerator.writeArrayFieldStart("Codes");
for (String s : loRule.getKeyLedCode())
jsonGenerator.writeString(s);
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
}
}

View file

@ -0,0 +1,49 @@
package logiled.Config;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import logiled.Controllers.Model.LoRule;
import java.util.HashMap;
import java.util.List;
// Move to main controller; implement getters and use annotation?
@JsonPropertyOrder({"Model", "Led & Keys", "Effect", "Game mode keys"})
public class SettingsFileFormat {
@JsonProperty("Model")
private static final String kbrdModel = "G513";
@JsonProperty("Effect")
@JsonSerialize(contentUsing = HexSerializer.class)
@JsonDeserialize(contentUsing = HexDeserializer.class)
private HashMap<String, Byte> effectHumanReadable;
@JsonProperty("Game mode keys")
private List<String> gameModeKeyCodes;
@JsonProperty("Led & Keys")
@JsonSerialize(contentUsing = LoRuleSerializer.class)
@JsonDeserialize(contentUsing = LoRuleDeSerializer.class)
private List<LoRule> keyLedRule;
public void setGameModeKeyCodes(List<String> gameModeKeyCodes) {
this.gameModeKeyCodes = gameModeKeyCodes;
}
public void setEffectHumanReadable(HashMap<String, Byte> map) {
this.effectHumanReadable = map;
}
public void setKeyLedRule(List<LoRule> keyLedRule) {
this.keyLedRule = keyLedRule;
}
public HashMap<String, Byte> getEffectHumanReadable() { return effectHumanReadable; }
public List<String> getGameModeKeyCodes() { return gameModeKeyCodes; }
public List<LoRule> getKeyLedRule() { return keyLedRule; }
}

View file

@ -4,6 +4,8 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.paint.Color;
import logiled.Controllers.Helpers.LoEffects;
import java.net.URL;
import java.nio.ByteBuffer;
@ -46,12 +48,12 @@ public class EffectsController implements Initializable {
mainSlideInfoLbl.setText(String.format("%.0f", mainSlide.getValue()));
effectsMenu.setText(((RadioMenuItem) effectsToggleGrp.getSelectedToggle()).getText());
effectsToggleGrp.selectedToggleProperty().addListener((observableValue, oldToggle, newToggle) -> effectsMenu.setText(((MenuItem) newToggle).getText()));
}
@FXML
private void selectEffect(ActionEvent event){
final RadioMenuItem item = (RadioMenuItem) event.getSource();
effectsMenu.setText(item.getText());
switch (item.getId()){
case "disRMI":
mainClrPkr.setVisible(false);
@ -181,4 +183,90 @@ public class EffectsController implements Initializable {
return effectsSet;
}
/**
* Restore from config file.
* */
public void setConfig(HashMap<String, Byte> effectConfig){
int sliderVal;
switch (LoEffects.values()[effectConfig.get("EFFECT")]){
case DISABLE:
disRMI.fire();
effectsToggleGrp.selectToggle(disRMI);
break;
case CONSTANT_COLOR:
constRMI.fire();
effectsToggleGrp.selectToggle(constRMI);
mainClrPkr.setValue(Color.color(uByteToDoubleClr(effectConfig.get("RED")), uByteToDoubleClr(effectConfig.get("GREEN")), uByteToDoubleClr(effectConfig.get("BLUE"))));
break;
case BREATH:
breathRMI.fire();
effectsToggleGrp.selectToggle(breathRMI);
mainClrPkr.setValue(Color.color(uByteToDoubleClr(effectConfig.get("RED")), uByteToDoubleClr(effectConfig.get("GREEN")), uByteToDoubleClr(effectConfig.get("BLUE"))));
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case CIRCLES_ON_PRESS:
circlesOnPressRMI.fire();
effectsToggleGrp.selectToggle(circlesOnPressRMI);
mainClrPkr.setValue(Color.color(uByteToDoubleClr(effectConfig.get("RED")), uByteToDoubleClr(effectConfig.get("GREEN")), uByteToDoubleClr(effectConfig.get("BLUE"))));
sliderVal = concatInt((byte) 0, effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case CYCLE:
cycleRMI.fire();
effectsToggleGrp.selectToggle(cycleRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_HORIZONTAL_FRW:
hWaveFrwRMI.fire();
effectsToggleGrp.selectToggle(hWaveFrwRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_VERTICAL_FRW:
vWaveFrwRMI.fire();
effectsToggleGrp.selectToggle(vWaveFrwRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_CENTER_TO_EDGE:
cntrToEdgWaveRMI.fire();
effectsToggleGrp.selectToggle(cntrToEdgWaveRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_HORIZONTAL_BKW:
hWaveBkwRMI.fire();
effectsToggleGrp.selectToggle(hWaveBkwRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_VERTICAL_BKW:
vWaveBkwRMI.fire();
effectsToggleGrp.selectToggle(vWaveBkwRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
break;
case WAVE_EDGE_TO_CENTER:
edgToCntrWaveRMI.fire();
effectsToggleGrp.selectToggle(edgToCntrWaveRMI);
sliderVal = concatInt(effectConfig.get("TIME_HIGH"), effectConfig.get("TIME_LOW"));
mainSlide.setValue(sliderVal);
}
}
/**
* Since we widely use byte as representation of the Red/Green/Blue, this will convert byte to double < 1.
* @return double value of the color
* */
private double uByteToDoubleClr(byte b){
return Byte.toUnsignedInt(b)/255.0;
}
/**
* Assemble int value of the two bytes
* */
private int concatInt(byte hi, byte lo){
return ByteBuffer.wrap(new byte[]{0x00, 0x00, hi, lo}).getInt();
}
}

View file

@ -5,6 +5,7 @@ import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ToggleButton;
import logiled.Controllers.Helpers.LoCodepage;
import java.net.URL;
import java.util.*;
@ -16,14 +17,12 @@ public class GameModeController implements Initializable {
private List<String> keySet;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
keySet = new ArrayList<>();
resetBtn.setOnAction(ActionEvent -> {
for (String keyID : keySet) {
for (String keyID : keySet)
((ToggleButton) resetBtn.getScene().lookup("#"+keyID)).setSelected(false);
}
keySet.clear();
});
}
@ -44,4 +43,19 @@ public class GameModeController implements Initializable {
return listCodes;
}
/**
* Get set of keys disabled in game mode. Would be stored in config file.
* */
public List<String> getInternalKeySet(){
return keySet;
}
/**
* Restore from config file.
* */
public void setConfig(List<String> keySet){
resetBtn.fire();
this.keySet = keySet;
for (String keyID : keySet)
((ToggleButton) resetBtn.getScene().lookup("#"+keyID)).setSelected(true);
}
}

View file

@ -1,4 +1,4 @@
package logiled.Controllers;
package logiled.Controllers.Helpers;
public enum LoCodepage {
l_game ((byte) 0x2),

View file

@ -1,4 +1,4 @@
package logiled.Controllers;
package logiled.Controllers.Helpers;
public enum LoEffects {
DISABLE ((byte) 0),

View file

@ -6,8 +6,13 @@ import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import logiled.Controllers.Model.LoRule;
import logiled.Controllers.Model.RuleBox;
import javax.swing.text.html.ImageView;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
@ -28,6 +33,9 @@ public class KeysLedsController implements Initializable {
k_arr_up, k_arr_down, k_arr_left, k_arr_right, k_end,
k_num, k_num_slash, k_num_asterisk, k_num_minus, k_num_9, k_num_8, k_num_7, k_num_6, k_num_5, k_num_4, k_num_3, k_num_2, k_num_1, k_num_0, k_num_period, k_num_enter, k_num_plus,
l_game, l_caps;
private HashMap<String, Button> kbrdMap;
@FXML
private Button addRuleBtn, remRuleBtn;
@ -36,6 +44,114 @@ public class KeysLedsController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
kbrdMap = new HashMap<>();
kbrdMap.put("k_esc", k_esc);
kbrdMap.put("k_f1", k_f1);
kbrdMap.put("k_f2", k_f2);
kbrdMap.put("k_f3", k_f3);
kbrdMap.put("k_f4", k_f4);
kbrdMap.put("k_f5", k_f5);
kbrdMap.put("k_f6", k_f6);
kbrdMap.put("k_f7", k_f7);
kbrdMap.put("k_f8", k_f8);
kbrdMap.put("k_f9", k_f9);
kbrdMap.put("k_f10", k_f10);
kbrdMap.put("k_f11", k_f11);
kbrdMap.put("k_f12", k_f12);
kbrdMap.put("k_1", k_1);
kbrdMap.put("k_2", k_2);
kbrdMap.put("k_3", k_3);
kbrdMap.put("k_4", k_4);
kbrdMap.put("k_5", k_5);
kbrdMap.put("k_6", k_6);
kbrdMap.put("k_7", k_7);
kbrdMap.put("k_8", k_8);
kbrdMap.put("k_9", k_9);
kbrdMap.put("k_0", k_0);
kbrdMap.put("k_dash", k_dash);
kbrdMap.put("k_equal", k_equal);
kbrdMap.put("k_backspace", k_backspace);
kbrdMap.put("k_tab", k_tab);
kbrdMap.put("k_q", k_q);
kbrdMap.put("k_w", k_w);
kbrdMap.put("k_e", k_e);
kbrdMap.put("k_r", k_r);
kbrdMap.put("k_t", k_t);
kbrdMap.put("k_y", k_y);
kbrdMap.put("k_u", k_u);
kbrdMap.put("k_i", k_i);
kbrdMap.put("k_o", k_o);
kbrdMap.put("k_p", k_p);
kbrdMap.put("k_bracket_open", k_bracket_open);
kbrdMap.put("k_bracket_close", k_bracket_close);
kbrdMap.put("k_backslash", k_backslash);
kbrdMap.put("k_caps", k_caps);
kbrdMap.put("k_a", k_a);
kbrdMap.put("k_s", k_s);
kbrdMap.put("k_d", k_d);
kbrdMap.put("k_f", k_f);
kbrdMap.put("k_g", k_g);
kbrdMap.put("k_h", k_h);
kbrdMap.put("k_j", k_j);
kbrdMap.put("k_k", k_k);
kbrdMap.put("k_l", k_l);
kbrdMap.put("k_semicolon", k_semicolon);
kbrdMap.put("k_quotation", k_quotation);
kbrdMap.put("k_enter", k_enter);
kbrdMap.put("k_l_shift", k_l_shift);
kbrdMap.put("k_z", k_z);
kbrdMap.put("k_x", k_x);
kbrdMap.put("k_c", k_c);
kbrdMap.put("k_v", k_v);
kbrdMap.put("k_b", k_b);
kbrdMap.put("k_n", k_n);
kbrdMap.put("k_m", k_m);
kbrdMap.put("k_comma", k_comma);
kbrdMap.put("k_dot", k_dot);
kbrdMap.put("k_shash", k_shash);
kbrdMap.put("k_r_shift", k_r_shift);
kbrdMap.put("k_l_ctrl", k_l_ctrl);
kbrdMap.put("k_win", k_win);
kbrdMap.put("k_l_alt", k_l_alt);
kbrdMap.put("k_space", k_space);
kbrdMap.put("k_r_alt", k_r_alt);
kbrdMap.put("k_fn", k_fn);
kbrdMap.put("k_menu", k_menu);
kbrdMap.put("k_r_ctrl", k_r_ctrl);
kbrdMap.put("k_prtscr", k_prtscr);
kbrdMap.put("k_scrl", k_scrl);
kbrdMap.put("k_pause", k_pause);
kbrdMap.put("k_tilde", k_tilde);
kbrdMap.put("k_ins", k_ins);
kbrdMap.put("k_home", k_home);
kbrdMap.put("k_pg_up", k_pg_up);
kbrdMap.put("k_del", k_del);
kbrdMap.put("k_pg_dn", k_pg_dn);
kbrdMap.put("k_arr_up", k_arr_up);
kbrdMap.put("k_arr_down", k_arr_down);
kbrdMap.put("k_arr_left", k_arr_left);
kbrdMap.put("k_arr_right", k_arr_right);
kbrdMap.put("k_end", k_end);
kbrdMap.put("k_num", k_num);
kbrdMap.put("k_num_slash", k_num_slash);
kbrdMap.put("k_num_asterisk", k_num_asterisk);
kbrdMap.put("k_num_minus", k_num_minus);
kbrdMap.put("k_num_9", k_num_9);
kbrdMap.put("k_num_8", k_num_8);
kbrdMap.put("k_num_7", k_num_7);
kbrdMap.put("k_num_6", k_num_6);
kbrdMap.put("k_num_5", k_num_5);
kbrdMap.put("k_num_4", k_num_4);
kbrdMap.put("k_num_3", k_num_3);
kbrdMap.put("k_num_2", k_num_2);
kbrdMap.put("k_num_1", k_num_1);
kbrdMap.put("k_num_0", k_num_0);
kbrdMap.put("k_num_period", k_num_period);
kbrdMap.put("k_num_enter", k_num_enter);
kbrdMap.put("k_num_plus", k_num_plus);
kbrdMap.put("l_game", l_game);
kbrdMap.put("l_caps", l_caps);
rulesVBox.getChildren().addListener((ListChangeListener<Node>) change -> {
change.next(); // Get changes
if (change.wasAdded()){ // If something added, turn on ability to remove such rule
@ -61,7 +177,7 @@ public class KeysLedsController implements Initializable {
}
@FXML
private void toggleBntAction(ActionEvent event){
private void anyKeyAction(ActionEvent event){
if (rulesVBox.getChildren().isEmpty()) // if we have rule, then we have selected rule (app architecture)
return;
Button btn = (Button) event.getSource();
@ -92,4 +208,35 @@ public class KeysLedsController implements Initializable {
set.put("Led", ledSet);
return set;
}
public List<LoRule> getInternalRules(){
List<LoRule> allRulesList = new ArrayList<>();
LoRule rule;
for (Node box : rulesVBox.getChildren()){
rule = ((RuleBox) box).getLoRule();
if (rule != null)
allRulesList.add(rule);
}
return allRulesList;
}
/**
* Restore from config file.
* */
public void setConfig(List<LoRule> rules){
if (rulesVBox.getChildren().size() > 0){
for (Node box : rulesVBox.getChildren())
((RuleBox) box).wipe();
rulesVBox.getChildren().clear();
}
List<Button> keyList;
for (LoRule rule : rules){
keyList = new ArrayList<>();
for (String keyId : rule.getKeyLedCode())
keyList.add(kbrdMap.get(keyId));
RuleBox box = new RuleBox(rule.getRed(), rule.getGreen(), rule.getBlue(), keyList);
rulesVBox.getChildren().add(box);
}
}
}

View file

@ -1,15 +1,22 @@
package logiled.Controllers;
import javafx.event.EventHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.stage.FileChooser;
import logiled.About.AboutWindow;
import logiled.MessagesConsumer;
import logiled.Config.SettingsFileFormat;
import logiled.ServiceWindow;
import logiled.USB.EffectsThread;
import logiled.USB.GameModeThread;
import logiled.USB.KeyLedThread;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
@ -32,7 +39,7 @@ public class MainController implements Initializable {
private Tab KeyLedTab, EffectsTab;
*/
@FXML
private Button applyBtn;
private Button applyBtn, openBtn, saveBtn, saveAsBtn;
@FXML
private Label infoLbl;
@ -40,14 +47,24 @@ public class MainController implements Initializable {
@FXML
private MenuItem aboutMenuItem;
// TODO: add block & release-button function
private ResourceBundle rb;
private String recentPath;
private File openedConfigFile;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.rb = resourceBundle;
aboutMenuItem.setOnAction(actionEvent -> new AboutWindow());
MessagesConsumer.getInstance().setInstance(infoLbl);
MessagesConsumer.getInstance().start();
openBtn.setOnAction(actionEvent -> openConfig());
saveBtn.setOnAction(ActionEvent -> saveConfig(false));
saveAsBtn.setOnAction(ActionEvent -> saveConfig(true));
applyBtn.setOnAction(actionEvent -> {
if (MainTabPane.getSelectionModel().getSelectedItem().getId().equals("KeyLedTab")) {
HashMap<String, List<byte[][]>> rules = KeysLedsController.getRules();
@ -78,4 +95,135 @@ public class MainController implements Initializable {
}
});
}
/**
* For 'Open' button
* */
private void openConfig(){
File congigFile = getOpenFileChooser();
if (congigFile == null)
return;
else
recentPath = congigFile.getParentFile().getAbsolutePath();
ObjectMapper mapper = new ObjectMapper();
SettingsFileFormat setup;
try{
setup = mapper.readerFor(SettingsFileFormat.class).readValue(new FileInputStream(congigFile));
KeysLedsController.setConfig(setup.getKeyLedRule());
EffectsController.setConfig(setup.getEffectHumanReadable());
GameModeController.setConfig(setup.getGameModeKeyCodes());
}
catch (IOException e){
ServiceWindow.getErrorNotification(rb.getString("error_any_title"), rb.getString("error_any_body"));
e.printStackTrace();
}
}
/**
* Show File Chooser for saving file
* @return file that has to be written.
* */
private File getOpenFileChooser(){
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(rb.getString("btn_save_as"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("LogiLed config (*.lcfg)", "*.lcfg"));
if (recentPath != null){
File stat = new File(recentPath);
if (! stat.exists())
recentPath = System.getProperty("user.home");
}
else
recentPath = System.getProperty("user.home");
fileChooser.setInitialDirectory(new File(recentPath));
return fileChooser.showOpenDialog(applyBtn.getScene().getWindow());
}
/**
* For 'Save' and 'Save As' buttons
* */
private void saveConfig(boolean isSaveAs){
SettingsFileFormat fileFormat = new SettingsFileFormat();
fileFormat.setKeyLedRule(KeysLedsController.getInternalRules());
fileFormat.setEffectHumanReadable(EffectsController.getEffect());
fileFormat.setGameModeKeyCodes(GameModeController.getInternalKeySet());
File tempFile;
if (isSaveAs) {
if ((tempFile = getSaveFileChooser()) == null) // In case nothing user clicked 'Cancel button' just leave this
return;
else
openedConfigFile = tempFile; // Because: if we already have config loaded, we won't loose it with this hint.
}
else {
// If nothing opened then show file chooser
if (openedConfigFile == null){
if ((openedConfigFile = getSaveFileChooser()) == null) // In case nothing user clicked 'Cancel button' just leave this
return;
else
recentPath = openedConfigFile.getParentFile().getAbsolutePath();
}
}
// Create JSON magic
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writerWithDefaultPrettyPrinter().writeValue(new FileOutputStream(openedConfigFile), fileFormat);
infoLbl.setText(rb.getString("info_file_saved"));
}
catch (Exception e){
ServiceWindow.getErrorNotification(rb.getString("error_any_title"), rb.getString("error_any_body"));
infoLbl.setText(rb.getString("info_file_not_saved"));
e.printStackTrace();
}
/*
try{
// DEBUG
String jsonResult = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(fileFormat);
//System.out.println(jsonResult);
ObjectMapper mapper = new ObjectMapper();
SettingsFileFormat ff = mapper.readerFor(SettingsFileFormat.class).readValue(jsonResult);
System.out.println("FF getKeyLedRule: ");
for (LoRule r: ff.getKeyLedRule()){
System.out.println(r.getRed()+" "+r.getGreen()+" "+r.getBlue()+" ");
for (String s: r.getKeyLedCode())
System.out.print(s+" ");
System.out.println();
}
System.out.println("FF getEffectHumanReadable: ");
for (Map.Entry<String, Byte> e : ff.getEffectHumanReadable().entrySet()){
System.out.println(e.getKey()+" "+e.getValue());
}
System.out.println("FF getGameModeKeyCodes: ");
for (String s: ff.getGameModeKeyCodes())
System.out.println(s);
}
catch (Exception e) {
e.printStackTrace();
}
*/
}
/**
* Show File Chooser for saving file
* @return file that has to be written.
* */
private File getSaveFileChooser(){
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(rb.getString("btn_save_as"));
fileChooser.setInitialFileName("keyboard settings.lcfg");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("LogiLed config (*.lcfg)", "*.lcfg"));
if (recentPath != null){
File stat = new File(recentPath);
if (! stat.exists())
recentPath = System.getProperty("user.home");
}
return fileChooser.showSaveDialog(applyBtn.getScene().getWindow());
}
}

View file

@ -0,0 +1,34 @@
package logiled.Controllers.Model;
import java.util.List;
public class LoRule {
private byte red;
private byte green;
private byte blue;
private String[] keyLedCode;
public LoRule(byte red, byte green, byte blue, String[] keyLedCode){
this.red = red;
this.green = green;
this.blue = blue;
this.keyLedCode = keyLedCode;
}
public byte getRed() {
return red;
}
public byte getGreen() {
return green;
}
public byte getBlue() {
return blue;
}
public String[] getKeyLedCode() {
return keyLedCode;
}
}

View file

@ -1,4 +1,4 @@
package logiled.Controllers;
package logiled.Controllers.Model;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
@ -8,17 +8,18 @@ import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import logiled.Controllers.Helpers.LoCodepage;
import java.util.*;
class RuleBox extends HBox { // todo: add class to selected toggle user data; provide interface to add buttons to selected toggle
public class RuleBox extends HBox { // todo: add class to selected toggle user data; provide interface to add buttons to selected toggle
private final static ToggleGroup radioGroup = new ToggleGroup();
/**
* Get object (rule) that is currently selected
* */
static RuleBox getSelected(){
public static RuleBox getSelected(){
Toggle selectedToggle;
if ((selectedToggle = radioGroup.getSelectedToggle()) == null)
return null;
@ -28,7 +29,7 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
* Select rule
* @param box : the rule that has to be selected.
* */
static void select(RuleBox box){
public static void select(RuleBox box){
box.radBtn.setSelected(true);
}
@ -36,7 +37,37 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
private final ColorPicker colorPicker;
private final RadioButton radBtn;
RuleBox(){
/**
* Add box and fulfill it (used when restoring from saved config-file)
* */
public RuleBox(byte red, byte green, byte blue, List<Button> rlBttnsLst){
this();
colorPicker.setValue(Color.color(Byte.toUnsignedInt(red)/255.0,
Byte.toUnsignedInt(green)/255.0,
Byte.toUnsignedInt(blue)/255.0));
for (Button keyBtn: rlBttnsLst){
keyBtn.setDisable(true);
keyBtn.setStyle(
String.format(".button:disabled {-fx-background-color: #bdf7ff; -fx-opacity: 1.0; -fx-text-fill: #%02x%02x%02x; -fx-border-color: #%02x%02x%02x;}",
red, green, blue,
red, green, blue)
);
Button key = new Button(keyBtn.getText()); // Set same name
key.setMnemonicParsing(false); // don't wipe underscore from UI
key.setUserData(new Object[] {keyBtn, keyBtn.getId()}); // Store button-'patent' and 'FX ID'
key.setOnAction(ActionEvent->{
keyBtn.setStyle("");
flowPaneBox.getChildren().remove(key);
keyBtn.setDisable(false);
});
flowPaneBox.getChildren().add(key);
}
}
/**
* Add new typical box (creates on button click)
* */
public RuleBox(){
super();
Insets insets = new Insets(3.0, 3.0, 3.0, 3.0);
// Radio button for selecting rule
@ -73,7 +104,7 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
/**
* Prepare this object to be deleted: release all buttons used etc.
* */
void wipe(){
public void wipe(){
for (Node node : flowPaneBox.getChildren()) {
Button key = (Button) ((Object[]) node.getUserData())[0];
key.setStyle("");
@ -83,7 +114,7 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
/**
* Add button to UI (appears for current rule)
* */
void addKey(Button keyBtn){
public void addKey(Button keyBtn){
keyBtn.setDisable(true);
keyBtn.setStyle(
@ -108,7 +139,7 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
/**
* Get information about this rule (keys)
* */
byte[][] getKeyCodes(){
public byte[][] getKeyCodes(){
final List<byte[]> keysList = new ArrayList<>();
final byte red = (byte) (colorPicker.getValue().getRed()*255);
@ -136,7 +167,7 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
/**
* Get information about this rule (Leds)
* */
byte[][] getLedCodes(){
public byte[][] getLedCodes(){
final List<byte[]> ledList = new ArrayList<>();
final byte red = (byte) (colorPicker.getValue().getRed()*255);
@ -161,4 +192,26 @@ class RuleBox extends HBox { // todo: add class to selected toggle user data;
return ledList.toArray(new byte[0][]);
}
public LoRule getLoRule(){
if (flowPaneBox.getChildren().size() == 0)
return null;
List<String> codes = new ArrayList<>();
for (int i = 0; i < flowPaneBox.getChildren().size(); i++) {
Object[] pair = (Object[]) flowPaneBox.getChildren().get(i).getUserData();
String id = (String) pair[1];
codes.add(id);
}
if (codes.size() == 0)
return null;
return new LoRule(
(byte) (colorPicker.getValue().getRed()*255),
(byte) (colorPicker.getValue().getGreen()*255),
(byte) (colorPicker.getValue().getBlue()*255),
codes.toArray(new String[0])
);
}
}

View file

@ -16,7 +16,7 @@ import java.util.Locale;
import java.util.ResourceBundle;
public class MainFx extends Application {
public static final String appVersion = "v0.3";
public static final String appVersion = "v0.4";
private static boolean traySupport = true;
@ -77,7 +77,7 @@ public class MainFx extends Application {
SystemTray tray = SystemTray.getSystemTray();
TrayIcon trayIcon = new TrayIcon(ImageIO.read(getClass().getResourceAsStream("/ico/appIcon_32.png")));
TrayIcon trayIcon = new TrayIcon(ImageIO.read(getClass().getResourceAsStream("/ico/appIcon_24.png")));
trayIcon.addActionListener(ActionEvent -> Platform.runLater(this::showStage));

View file

@ -0,0 +1,18 @@
package logiled;
import javafx.scene.control.Alert;
import javafx.scene.layout.Region;
public class ServiceWindow {
/**
* Create window with notification
* */
public static void getErrorNotification(String title, String body){
Alert alertBox = new Alert(Alert.AlertType.ERROR);
alertBox.setTitle(title);
alertBox.setHeaderText(null);
alertBox.setContentText(body);
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); // Java bug workaround for linux
alertBox.show();
}
}

View file

@ -1,6 +1,6 @@
package logiled.USB;
import logiled.Controllers.LoEffects;
import logiled.Controllers.Helpers.LoEffects;
import logiled.MessagesConsumer;
import java.util.HashMap;

View file

@ -4,7 +4,6 @@
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
@ -18,14 +17,14 @@
<children>
<ToolBar>
<items>
<Button fx:id="resetBtn" mnemonicParsing="false">
<tooltip>
<Tooltip text="%btn_reset" />
</tooltip>
<Button fx:id="resetBtn" mnemonicParsing="false" text="%btn_reset">
<graphic>
<SVGPath content="M2 12C2 16.97 6.03 21 11 21C13.39 21 15.68 20.06 17.4 18.4L15.9 16.9C14.63 18.25 12.86 19 11 19C4.76 19 1.64 11.46 6.05 7.05C10.46 2.64 18 5.77 18 12H15L19 16H19.1L23 12H20C20 7.03 15.97 3 11 3C6.03 3 2 7.03 2 12Z" />
</graphic></Button>
</items>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</ToolBar>
<HBox spacing="17.0">
<children>

View file

@ -2,8 +2,10 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
@ -13,343 +15,357 @@
<?import javafx.scene.shape.SVGPath?>
<?import javafx.scene.text.Font?>
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="logiled.Controllers.KeysLedsController">
<children>
<ToolBar>
<items>
<Button fx:id="addRuleBtn" mnemonicParsing="false">
<tooltip>
<Tooltip text="%btn_addRule" />
</tooltip>
<graphic>
<SVGPath content="M2,16H10V14H2M18,14V10H16V14H12V16H16V20H18V16H22V14M14,6H2V8H14M14,10H2V12H14V10Z" />
</graphic></Button>
<Button fx:id="remRuleBtn" mnemonicParsing="false">
<tooltip>
<Tooltip text="%btn_removeRule" />
</tooltip>
<graphic>
<SVGPath content="M2,6V8H14V6H2M2,10V12H11V10H2M14.17,10.76L12.76,12.17L15.59,15L12.76,17.83L14.17,19.24L17,16.41L19.83,19.24L21.24,17.83L18.41,15L21.24,12.17L19.83,10.76L17,13.59L14.17,10.76M2,14V16H11V14H2Z" />
</graphic></Button>
</items>
</ToolBar>
<VBox fx:id="rulesVBox" />
<HBox spacing="17.0">
<children>
<VBox>
<BorderPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="logiled.Controllers.KeysLedsController">
<top>
<ToolBar BorderPane.alignment="CENTER">
<items>
<Button fx:id="addRuleBtn" mnemonicParsing="false">
<tooltip>
<Tooltip text="%btn_addRule" />
</tooltip>
<graphic>
<SVGPath content="M2,16H10V14H2M18,14V10H16V14H12V16H16V20H18V16H22V14M14,6H2V8H14M14,10H2V12H14V10Z" />
</graphic>
</Button>
<Button fx:id="remRuleBtn" mnemonicParsing="false">
<tooltip>
<Tooltip text="%btn_removeRule" />
</tooltip>
<graphic>
<SVGPath content="M2,6V8H14V6H2M2,10V12H11V10H2M14.17,10.76L12.76,12.17L15.59,15L12.76,17.83L14.17,19.24L17,16.41L19.83,19.24L21.24,17.83L18.41,15L21.24,12.17L19.83,10.76L17,13.59L14.17,10.76M2,14V16H11V14H2Z" />
</graphic>
</Button>
</items>
</ToolBar>
</top>
<bottom>
<HBox spacing="17.0" BorderPane.alignment="CENTER">
<children>
<HBox spacing="2.0">
<VBox>
<children>
<Button fx:id="k_esc" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="ESC">
<HBox spacing="2.0">
<children>
<Button fx:id="k_esc" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="ESC">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" HBox.hgrow="NEVER" />
<Button fx:id="k_f1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F1">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" HBox.hgrow="NEVER" />
<Button fx:id="k_f1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F1">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F2">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F3">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F4">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" />
<Button fx:id="k_f5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F5">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F6">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F7">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F8">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" />
<Button fx:id="k_f9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F9">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f10" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F10">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f11" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F11">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f12" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F12">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_prtscr" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="PRTSC">
</Button>
<Button fx:id="k_f2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F2">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_scrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="SCRLK">
</Button>
<Button fx:id="k_f3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F3">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pause" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="PAUSE">
</Button>
<Button fx:id="k_f4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F4">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
<VBox.margin>
<Insets bottom="17.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_tilde" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="~" />
<Button fx:id="k_1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="1" />
<Button fx:id="k_2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="2" />
<Button fx:id="k_3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="3" />
<Button fx:id="k_4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="4" />
<Button fx:id="k_5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="5" />
<Button fx:id="k_6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="6" />
<Button fx:id="k_7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="7" />
<Button fx:id="k_8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="8" />
<Button fx:id="k_9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="9" />
<Button fx:id="k_0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="0" />
<Button fx:id="k_dash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="-" />
<Button fx:id="k_equal" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="=" />
<Button fx:id="k_backspace" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="125.0" text="←" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_ins" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="INS">
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" />
<Button fx:id="k_f5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F5">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_home" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="HOME">
</Button>
<Button fx:id="k_f6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F6">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pg_up" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="PG UP">
</Button>
<Button fx:id="k_f7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F7">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
<VBox.margin>
</Button>
<Button fx:id="k_f8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F8">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="40.0" />
<Button fx:id="k_f9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F9">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f10" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F10">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f11" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F11">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_f12" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F12">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_prtscr" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="PRTSC">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_scrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="SCRLK">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pause" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="PAUSE">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
<VBox.margin>
<Insets bottom="17.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_tilde" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="~" />
<Button fx:id="k_1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="1" />
<Button fx:id="k_2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="2" />
<Button fx:id="k_3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="3" />
<Button fx:id="k_4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="4" />
<Button fx:id="k_5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="5" />
<Button fx:id="k_6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="6" />
<Button fx:id="k_7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="7" />
<Button fx:id="k_8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="8" />
<Button fx:id="k_9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="9" />
<Button fx:id="k_0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="0" />
<Button fx:id="k_dash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="-" />
<Button fx:id="k_equal" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="=" />
<Button fx:id="k_backspace" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="125.0" text="←" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_ins" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="INS">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_home" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="HOME">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pg_up" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="PG UP">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_tab" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="60.0" text="TAB" />
<Button fx:id="k_q" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="Q" />
<Button fx:id="k_w" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="W" />
<Button fx:id="k_e" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="E" />
<Button fx:id="k_r" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="R" />
<Button fx:id="k_t" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="T" />
<Button fx:id="k_y" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="Y" />
<Button fx:id="k_u" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="U" />
<Button fx:id="k_i" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="I" />
<Button fx:id="k_o" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="O" />
<Button fx:id="k_p" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="P" />
<Button fx:id="k_bracket_open" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="[" />
<Button fx:id="k_bracket_close" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="]" />
<Button fx:id="k_backslash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="110.0" text="\\" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_del" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="DEL">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_end" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="END">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pg_dn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="PG DN">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
<children>
<Button fx:id="k_caps" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="70.0" text="CAPS" />
<Button fx:id="k_a" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="A" />
<Button fx:id="k_s" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="S" />
<Button fx:id="k_d" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="D" />
<Button fx:id="k_f" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="F" />
<Button fx:id="k_g" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="G" />
<Button fx:id="k_h" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="H" />
<Button fx:id="k_j" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="J" />
<Button fx:id="k_k" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="K" />
<Button fx:id="k_l" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="L" />
<Button fx:id="k_semicolon" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text=";" />
<Button fx:id="k_quotation" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="'" />
<Button fx:id="k_enter" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="147.0" text="ENTER" />
</children>
</HBox>
<HBox spacing="2.0">
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
<children>
<Button fx:id="k_l_shift" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="85.0" text="L SHIFT" />
<Button fx:id="k_z" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="Z" />
<Button fx:id="k_x" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="X" />
<Button fx:id="k_c" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="C" />
<Button fx:id="k_v" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="V" />
<Button fx:id="k_b" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="B" />
<Button fx:id="k_n" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="N" />
<Button fx:id="k_m" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="M" />
<Button fx:id="k_comma" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="," />
<Button fx:id="k_dot" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="." />
<Button fx:id="k_shash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="45.0" text="/" />
<Button fx:id="k_r_shift" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="179.0" text="R SHIFT" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="74.0" />
<Button fx:id="k_arr_up" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="↑" />
</children>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_l_ctrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="L CTRL">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_win" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="42.0" text="WIN">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_l_alt" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="ALT">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_space" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="270.0" text="—" />
<Button fx:id="k_r_alt" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="72.0" text="ALT GR">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_fn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="72.0" text="FN">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_menu" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="72.0" text="MENU">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_r_ctrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="84.0" text="R CTRL">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_arr_left" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="←" />
<Button fx:id="k_arr_down" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="↓" />
<Button fx:id="k_arr_right" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="55.0" text="→" />
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets bottom="2.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_tab" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="60.0" text="TAB" />
<Button fx:id="k_q" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="Q" />
<Button fx:id="k_w" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="W" />
<Button fx:id="k_e" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="E" />
<Button fx:id="k_r" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="R" />
<Button fx:id="k_t" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="T" />
<Button fx:id="k_y" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="Y" />
<Button fx:id="k_u" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="U" />
<Button fx:id="k_i" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="I" />
<Button fx:id="k_o" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="O" />
<Button fx:id="k_p" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="P" />
<Button fx:id="k_bracket_open" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="[" />
<Button fx:id="k_bracket_close" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="]" />
<Button fx:id="k_backslash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="110.0" text="\\" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_del" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="DEL">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_end" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="END">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_pg_dn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="PG DN">
<font>
<Font size="10.0" />
</font>
</Button>
</padding>
</HBox>
</children>
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</HBox>
<HBox spacing="2.0">
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</VBox>
<GridPane alignment="BOTTOM_LEFT" hgap="2.0" vgap="2.0" HBox.hgrow="NEVER">
<columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="51.0" valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
</rowConstraints>
<children>
<Button fx:id="k_caps" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="70.0" text="CAPS" />
<Button fx:id="k_a" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="A" />
<Button fx:id="k_s" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="S" />
<Button fx:id="k_d" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="D" />
<Button fx:id="k_f" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="F" />
<Button fx:id="k_g" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="G" />
<Button fx:id="k_h" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="H" />
<Button fx:id="k_j" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="J" />
<Button fx:id="k_k" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="K" />
<Button fx:id="k_l" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="L" />
<Button fx:id="k_semicolon" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text=";" />
<Button fx:id="k_quotation" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="'" />
<Button fx:id="k_enter" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="147.0" text="ENTER" />
</children>
</HBox>
<HBox spacing="2.0">
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
<children>
<Button fx:id="k_l_shift" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="85.0" text="L SHIFT" />
<Button fx:id="k_z" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="Z" />
<Button fx:id="k_x" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="X" />
<Button fx:id="k_c" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="C" />
<Button fx:id="k_v" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="V" />
<Button fx:id="k_b" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="B" />
<Button fx:id="k_n" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="N" />
<Button fx:id="k_m" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="M" />
<Button fx:id="k_comma" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="," />
<Button fx:id="k_dot" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="." />
<Button fx:id="k_shash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="45.0" text="/" />
<Button fx:id="k_r_shift" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="179.0" text="R SHIFT" />
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="74.0" />
<Button fx:id="k_arr_up" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="↑" />
</children>
</HBox>
<HBox spacing="2.0">
<children>
<Button fx:id="k_l_ctrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="L CTRL">
<Button fx:id="k_num" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="NUM" GridPane.rowIndex="1">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_win" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="42.0" text="WIN">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_l_alt" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="ALT">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_space" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="270.0" text="—" />
<Button fx:id="k_r_alt" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="72.0" text="ALT GR">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_fn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="72.0" text="FN">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_menu" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="72.0" text="MENU">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_r_ctrl" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="84.0" text="R CTRL">
<font>
<Font size="10.0" />
</font>
</Button>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1.0" prefWidth="17.0" />
<Button fx:id="k_arr_left" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="←" />
<Button fx:id="k_arr_down" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="↓" />
<Button fx:id="k_arr_right" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="55.0" text="→" />
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets bottom="2.0" />
</padding>
</HBox>
</children>
</VBox>
<GridPane alignment="BOTTOM_LEFT" hgap="2.0" vgap="2.0" HBox.hgrow="NEVER">
<columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
<ColumnConstraints halignment="CENTER" hgrow="NEVER" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="51.0" valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
<RowConstraints valignment="CENTER" vgrow="NEVER" />
</rowConstraints>
<children>
<Button fx:id="k_num" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="NUM" GridPane.rowIndex="1">
<Button fx:id="k_num_slash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="/" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button fx:id="k_num_asterisk" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="*" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Button fx:id="k_num_7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="7" GridPane.rowIndex="2" />
<Button fx:id="k_num_4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="4" GridPane.rowIndex="3" />
<Button fx:id="k_num_0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="102.0" text="0" GridPane.columnSpan="2" GridPane.rowIndex="5" />
<Button fx:id="k_num_1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="1" GridPane.rowIndex="4" />
<Button fx:id="k_num_8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="8" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Button fx:id="k_num_9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="9" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Button fx:id="k_num_5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="5" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Button fx:id="k_num_6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="6" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<Button fx:id="k_num_2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="2" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Button fx:id="k_num_3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="3" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<Button fx:id="k_num_minus" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="-" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<Button fx:id="k_num_plus" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="93.0" prefWidth="50.0" text="+" GridPane.columnIndex="3" GridPane.rowIndex="2" GridPane.rowSpan="2" />
<Button fx:id="k_num_enter" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="93.0" prefWidth="50.0" text="↵" GridPane.columnIndex="3" GridPane.rowIndex="4" GridPane.rowSpan="2" />
<Button fx:id="k_num_period" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="45.0" prefWidth="50.0" text="," GridPane.columnIndex="2" GridPane.rowIndex="5" />
<Button fx:id="l_caps" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="26.0" prefWidth="50.0" text="LED C">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="k_num_slash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="/" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button fx:id="k_num_asterisk" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="*" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Button fx:id="k_num_7" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="7" GridPane.rowIndex="2" />
<Button fx:id="k_num_4" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="4" GridPane.rowIndex="3" />
<Button fx:id="k_num_0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="102.0" text="0" GridPane.columnSpan="2" GridPane.rowIndex="5" />
<Button fx:id="k_num_1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="1" GridPane.rowIndex="4" />
<Button fx:id="k_num_8" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="8" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Button fx:id="k_num_9" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="9" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Button fx:id="k_num_5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="5" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Button fx:id="k_num_6" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="6" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<Button fx:id="k_num_2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="2" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Button fx:id="k_num_3" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="3" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<Button fx:id="k_num_minus" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="-" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<Button fx:id="k_num_plus" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="93.0" prefWidth="50.0" text="+" GridPane.columnIndex="3" GridPane.rowIndex="2" GridPane.rowSpan="2" />
<Button fx:id="k_num_enter" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="93.0" prefWidth="50.0" text="↵" GridPane.columnIndex="3" GridPane.rowIndex="4" GridPane.rowSpan="2" />
<Button fx:id="k_num_period" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="45.0" prefWidth="50.0" text="," GridPane.columnIndex="2" GridPane.rowIndex="5" />
<Button fx:id="l_caps" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="26.0" prefWidth="50.0" text="LED C">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="l_game" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#toggleBntAction" prefHeight="26.0" prefWidth="50.0" text="LED G" GridPane.columnIndex="1">
<font>
<Font size="10.0" />
</font>
</Button>
<Button fx:id="l_game" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#anyKeyAction" prefHeight="26.0" prefWidth="50.0" text="LED G" GridPane.columnIndex="1">
<font>
<Font size="10.0" />
</font>
</Button>
</children>
</GridPane>
</children>
</GridPane>
</children>
</HBox>
</children>
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
</VBox>
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
</HBox>
</bottom>
<center>
<ScrollPane fitToWidth="true" BorderPane.alignment="CENTER">
<content>
<VBox fx:id="rulesVBox">
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
</VBox>
</content>
</ScrollPane>
</center>
</BorderPane>

View file

@ -23,11 +23,7 @@
<menus>
<Menu mnemonicParsing="false" text="%menu_File">
<items>
<MenuItem mnemonicParsing="false" text="todo">
<graphic>
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" />
</graphic>
</MenuItem>
<MenuItem mnemonicParsing="false" text="todo" />
<Menu mnemonicParsing="false" text="Unspecified Menu">
<items>
<SeparatorMenuItem mnemonicParsing="false" />
@ -101,15 +97,36 @@
<SVGPath content="M14,10H2V12H14V10M14,6H2V8H14V6M2,16H10V14H2V16M21.5,11.5L23,13L16,20L11.5,15.5L13,14L16,17L21.5,11.5Z" />
</graphic>
</Button>
<Button fx:id="openBtn" mnemonicParsing="false">
<graphic>
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" />
</graphic>
<tooltip>
<Tooltip text="%btn_open" />
</tooltip>
</Button>
<Button fx:id="saveBtn" mnemonicParsing="false">
<graphic>
<SVGPath content="M17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H19C20.1 21 21 20.1 21 19V7L17 3M19 19H5V5H16.17L19 7.83V19M12 12C10.34 12 9 13.34 9 15S10.34 18 12 18 15 16.66 15 15 13.66 12 12 12M6 6H15V10H6V6Z" />
</graphic>
<tooltip>
<Tooltip text="%btn_save" />
</tooltip></Button>
<Button fx:id="saveAsBtn" mnemonicParsing="false">
<graphic>
<SVGPath content="M7 22H9V24H7V22M11 22H13V24H11V22M15 22H17V24H15V22M17 2H5C3.89 2 3 2.9 3 4V18C3 19.1 3.89 20 5 20H19C20.1 20 21 19.1 21 18V6L17 2M19 18H5V4H16.17L19 6.83V18M12 11C10.34 11 9 12.34 9 14S10.34 17 12 17 15 15.66 15 14 13.66 11 12 11M6 5H15V9H6V5Z" />
</graphic>
<tooltip>
<Tooltip text="%btn_save_as" />
</tooltip>
</Button>
</items>
</ToolBar>
<TabPane fx:id="MainTabPane" side="LEFT" tabClosingPolicy="UNAVAILABLE" VBox.vgrow="ALWAYS">
<tabs>
<Tab fx:id="KeyLedTab">
<content>
<ScrollPane fitToWidth="true">
<fx:include fx:id="KeysLeds" source="KeysLedsPane.fxml" VBox.vgrow="ALWAYS" />
</ScrollPane>
</content>
<graphic>
<SVGPath content="M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63Z" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -695,3 +695,11 @@ effect_wave_vertical_reverse=Wave vertical (reverse)
effect_wave_edge_to_center=Wave from edges to center
btn_reset=Reset
tray_close=Close
btn_save=Save
btn_save_as=Save as...
error_any_body=It's defenetelly an issue. But take a look on terminal.\n\
If it doesn't make sence just copy-paste it to application bug-tracker.
error_any_title=Ouch! Something bad happened.
btn_open=Open configuration
info_file_saved=File saved
info_file_not_saved=File not saved

View file

@ -21,3 +21,11 @@ effect_wave_center_to_edge=Волна от центра к краям
effect_wave_edge_to_center=Волна от краёв к центру
btn_reset=Сбросить
tray_close=Закрыть
btn_save=Сохранить
btn_save_as=Сохранить как...
error_any_title=Ох, что-то пошло не по плану.
error_any_body=Это определённо похоже на ошибку. Но глянь сперва к окно терминала.\n\
Если всё ещё не ясно что произошло, скопируй это в баг-трекер приложения.
btn_open=Открыть файл конфигурации
info_file_saved=Файл сохранён
info_file_not_saved=Файл не сохранён