diff --git a/src/main/java/ctbrec/ui/RecordedModelsTab.java b/src/main/java/ctbrec/ui/RecordedModelsTab.java index d36f6427..d0f5c029 100644 --- a/src/main/java/ctbrec/ui/RecordedModelsTab.java +++ b/src/main/java/ctbrec/ui/RecordedModelsTab.java @@ -24,6 +24,7 @@ import ctbrec.Model; import ctbrec.Recording; import ctbrec.recorder.Recorder; import ctbrec.sites.Site; +import ctbrec.ui.autofilltextbox.AutoFillTextField; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -41,7 +42,7 @@ import javafx.scene.control.ScrollPane; import javafx.scene.control.Tab; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; -import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; import javafx.scene.control.cell.CheckBoxTableCell; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.Clipboard; @@ -72,7 +73,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener { ContextMenu popup; Label modelLabel = new Label("Model"); - TextField model = new TextField(); + AutoFillTextField model; Button addModelButton = new Button("Record"); public RecordedModelsTab(String title, Recorder recorder, List sites) { @@ -136,12 +137,18 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener { scrollPane.setContent(table); HBox addModelBox = new HBox(5); - addModelBox.getChildren().addAll(modelLabel, model, addModelButton); modelLabel.setPadding(new Insets(5, 0, 0, 0)); + ObservableList suggestions = FXCollections.observableArrayList(); + sites.forEach(site -> suggestions.add(site.getName())); + model = new AutoFillTextField(suggestions); model.setPrefWidth(300); model.setPromptText("e.g. MyFreeCams:ModelName"); + model.onActionHandler(e -> addModel(e)); + model.setTooltip(new Tooltip("To add a model enter SiteName:ModelName\n" + + "press ENTER to confirm a suggested site name")); BorderPane.setMargin(addModelBox, new Insets(5)); addModelButton.setOnAction((e) -> addModel(e)); + addModelBox.getChildren().addAll(modelLabel, model, addModelButton); BorderPane root = new BorderPane(); root.setPadding(new Insets(5)); diff --git a/src/main/java/ctbrec/ui/autofilltextbox/AutoFillTextField.java b/src/main/java/ctbrec/ui/autofilltextbox/AutoFillTextField.java new file mode 100644 index 00000000..bf986360 --- /dev/null +++ b/src/main/java/ctbrec/ui/autofilltextbox/AutoFillTextField.java @@ -0,0 +1,65 @@ +package ctbrec.ui.autofilltextbox; + + +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +public class AutoFillTextField extends TextField { + + private ObservableList suggestions; + private EventHandler handler; + + public AutoFillTextField(ObservableList suggestions) { + this.suggestions = suggestions; + addEventHandler(KeyEvent.KEY_RELEASED, (evt) -> { + if (evt.getCode().isLetterKey() || evt.getCode().isDigitKey()) { + autocomplete(false); + } else if (evt.getCode() == KeyCode.ENTER) { + if (getSelection().getLength() > 0) { + selectRange(0, 0); + insertText(lengthProperty().get(), ":"); + positionCaret(lengthProperty().get()); + evt.consume(); + } else { + handler.handle(new ActionEvent(this, null)); + } + } else if (evt.getCode() == KeyCode.SPACE && evt.isControlDown()) { + autocomplete(true); + } + }); + } + + private void autocomplete(boolean fulltextSearch) { + String oldtext = getOldText(); + if(oldtext.isEmpty()) { + return; + } + for (String sug : suggestions) { + boolean startsWith = sug.toLowerCase().startsWith(oldtext.toLowerCase()); + boolean textMatch = fulltextSearch && sug.toLowerCase().contains(oldtext.toLowerCase()); + if(startsWith || textMatch) { + setText(sug); + int pos = oldtext.length(); + positionCaret(pos); + selectRange(pos, sug.length()); + break; + } + } + } + + private String getOldText() { + if(getSelection().getLength() > 0) { + return getText().substring(0, getSelection().getStart()); + } else { + return getText(); + } + } + + public void onActionHandler(EventHandler handler) { + this.handler = handler; + } +}