add prototype route tracker
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
package ru.trader.controllers;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import ru.trader.analysis.CrawlerSpecificator;
|
||||
import ru.trader.model.*;
|
||||
import ru.trader.view.support.Track;
|
||||
import ru.trader.view.support.ViewUtils;
|
||||
import ru.trader.view.support.autocomplete.AutoCompletion;
|
||||
import ru.trader.view.support.autocomplete.SystemsProvider;
|
||||
import ru.trader.view.support.cells.OfferListCell;
|
||||
import ru.trader.view.support.cells.OrderListCell;
|
||||
import ru.trader.view.support.cells.StationListCell;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -20,18 +26,45 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class RouteTrackController {
|
||||
|
||||
@FXML
|
||||
private Node editGroup;
|
||||
@FXML
|
||||
private Node infoGroup;
|
||||
@FXML
|
||||
private Node refuelGroup;
|
||||
@FXML
|
||||
private Node ordersGroup;
|
||||
@FXML
|
||||
private Label station;
|
||||
@FXML
|
||||
private Label system;
|
||||
@FXML
|
||||
private Label time;
|
||||
@FXML
|
||||
private Label refuel;
|
||||
@FXML
|
||||
private ListView<OrderModel> buyOrders;
|
||||
@FXML
|
||||
private ListView<OrderModel> sellOrders;
|
||||
@FXML
|
||||
private ListView<MissionModel> addMissionsList;
|
||||
@FXML
|
||||
private ListView<MissionModel> missionsList;
|
||||
@FXML
|
||||
private MissionsController missionsController;
|
||||
@FXML
|
||||
private Pane track;
|
||||
|
||||
private RouteModel route;
|
||||
private int index;
|
||||
private Track trackNode;
|
||||
|
||||
@FXML
|
||||
private void initialize(){
|
||||
MainController.getProfile().routeProperty().addListener(routeListener);
|
||||
missionsList.setItems(missionsController.getMissions());
|
||||
addMissionsList.setItems(missionsController.getMissions());
|
||||
buyOrders.setCellFactory(new OrderListCell(false));
|
||||
sellOrders.setCellFactory(new OrderListCell(true));
|
||||
editGroup.setVisible(false);
|
||||
}
|
||||
|
||||
public void setRoute(RouteModel route){
|
||||
@@ -39,23 +72,56 @@ public class RouteTrackController {
|
||||
this.route.currentEntryProperty().removeListener(currentEntryListener);
|
||||
}
|
||||
this.route = route;
|
||||
fillTrack();
|
||||
setIndex(route.getCurrentEntry());
|
||||
this.route.currentEntryProperty().addListener(currentEntryListener);
|
||||
}
|
||||
|
||||
public void setIndex(int index){
|
||||
this.index = index;
|
||||
missionsController.setStation(route.get(index).getStation());
|
||||
trackNode.setActive(index);
|
||||
}
|
||||
|
||||
private void fillTrack(){
|
||||
if (trackNode != null) trackNode.activeProperty().removeListener(activeEntryListener);
|
||||
trackNode = new Track(route);
|
||||
track.getChildren().setAll(trackNode.getNode());
|
||||
trackNode.activeProperty().addListener(activeEntryListener);
|
||||
}
|
||||
|
||||
private void update(){
|
||||
int index = trackNode.getActive();
|
||||
if (index == -1) return;
|
||||
RouteEntryModel entry = route.get(index);
|
||||
missionsController.setStation(entry.getStation());
|
||||
ObservableList<StationModel> stations = FXCollections.observableArrayList(route.getStations(index));
|
||||
missionsController.getBuyerProvider().setPossibleSuggestions(stations);
|
||||
missionsController.getReceiverProvider().setPossibleSuggestions(stations);
|
||||
List<ItemModel> items = route.getSellOffers(index).stream().map(OfferModel::getItem).collect(Collectors.toList());
|
||||
missionsController.getItem().getItems().setAll(items);
|
||||
|
||||
station.setText(entry.getStation().getName());
|
||||
system.setText(entry.getStation().getSystem().getName());
|
||||
time.setText(ViewUtils.timeToString(entry.getTime()));
|
||||
refuel.setText(String.valueOf(entry.getRefill()));
|
||||
buyOrders.setItems(entry.orders());
|
||||
sellOrders.setItems(entry.sellOrders());
|
||||
missionsList.setItems(entry.missions());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void toggleEdit(){
|
||||
if (editGroup.isVisible()){
|
||||
editGroup.setVisible(false);
|
||||
infoGroup.setVisible(true);
|
||||
} else {
|
||||
editGroup.setVisible(true);
|
||||
infoGroup.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void addMissions(){
|
||||
int startIndex = route.isLoop() ? 0 : index;
|
||||
int startIndex = route.isLoop() ? 0 : trackNode.getActive();
|
||||
route.addAll(startIndex, missionsList.getItems());
|
||||
}
|
||||
|
||||
@@ -68,6 +134,7 @@ public class RouteTrackController {
|
||||
}
|
||||
|
||||
private final ChangeListener<? super Number> currentEntryListener = (ov, o, n) -> ViewUtils.doFX(() -> setIndex(n.intValue()));
|
||||
private final InvalidationListener activeEntryListener = ov -> ViewUtils.doFX(this::update);
|
||||
private final ChangeListener<RouteModel> routeListener = (ov, o, n) -> {
|
||||
if (n != null){
|
||||
ViewUtils.doFX(() -> setRoute(n));
|
||||
|
||||
@@ -79,6 +79,18 @@ public class RouteEntryModel {
|
||||
return entry.isTransit();
|
||||
}
|
||||
|
||||
public boolean isBuy(){
|
||||
return !orders.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isSell(){
|
||||
return !sellOrders.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isMissionTarget(){
|
||||
return !missions.isEmpty();
|
||||
}
|
||||
|
||||
public ObservableList<OrderModel> orders() {
|
||||
return orders;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ public class RouteModel {
|
||||
return entries.get(index);
|
||||
}
|
||||
|
||||
public Collection<RouteEntryModel> getEntries(){
|
||||
return entries;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return _route.getDistance();
|
||||
}
|
||||
|
||||
129
client/src/main/java/ru/trader/view/support/Track.java
Normal file
129
client/src/main/java/ru/trader/view/support/Track.java
Normal file
@@ -0,0 +1,129 @@
|
||||
package ru.trader.view.support;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import ru.trader.model.RouteEntryModel;
|
||||
import ru.trader.model.RouteModel;
|
||||
import ru.trader.model.StationModel;
|
||||
import ru.trader.view.support.cells.DistanceCell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Track {
|
||||
private final static String CSS_ROUTE = "route";
|
||||
private final static String CSS_ICONS = "route-icons";
|
||||
private final static String CSS_TRACK = "route-track";
|
||||
private final static String CSS_TRACK_TEXT = "route-track-text";
|
||||
private final static String CSS_SYSTEM = "route-system";
|
||||
private final static String CSS_ACTIVE_SYSTEM = "route-active";
|
||||
private final static String CSS_TEXT = "route-text";
|
||||
private final static String CSS_SYSTEM_TEXT = "route-system-text";
|
||||
private final static String CSS_STATION_TEXT = "route-station-text";
|
||||
|
||||
private final RouteModel route;
|
||||
private final HBox node = new HBox();
|
||||
private final IntegerProperty active;
|
||||
private final List<Node> entryNodes;
|
||||
|
||||
public Track(RouteModel route) {
|
||||
this.route = route;
|
||||
entryNodes = new ArrayList<>(route.getJumps());
|
||||
active = new SimpleIntegerProperty(-1);
|
||||
node.getStyleClass().add(CSS_ROUTE);
|
||||
build();
|
||||
}
|
||||
|
||||
private void build(){
|
||||
StationModel prev = null;
|
||||
for (RouteEntryModel entry : route.getEntries()) {
|
||||
if (prev != null){
|
||||
VBox track = new VBox();
|
||||
VBox.setVgrow(track, Priority.ALWAYS);
|
||||
track.getStyleClass().add(CSS_TRACK);
|
||||
|
||||
Text t = new Text(DistanceCell.distanceToString(entry.getStation().getDistance(prev)));
|
||||
t.getStyleClass().add(CSS_TRACK_TEXT);
|
||||
track.getChildren().addAll(t, Glyph.create("FontAwesome|LONG_ARROW_RIGHT"));
|
||||
|
||||
node.getChildren().addAll(track);
|
||||
}
|
||||
HBox entryNode = new HBox();
|
||||
HBox stationNode = new HBox();
|
||||
VBox icons = new VBox();
|
||||
VBox.setVgrow(icons, Priority.ALWAYS);
|
||||
|
||||
stationNode.getStyleClass().add(CSS_SYSTEM);
|
||||
icons.getStyleClass().add(CSS_ICONS);
|
||||
|
||||
stationNode.getChildren().add(buildText(entry.getStation(), entry.isTransit()));
|
||||
|
||||
if (entry.isBuy()){
|
||||
icons.getChildren().add(Glyph.create("FontAwesome|UPLOAD"));
|
||||
}
|
||||
if (entry.getRefill() > 0){
|
||||
icons.getChildren().add(Glyph.create("FontAwesome|REFRESH"));
|
||||
}
|
||||
if (entry.isSell()){
|
||||
icons.getChildren().add(Glyph.create("FontAwesome|DOWNLOAD"));
|
||||
}
|
||||
entryNode.getChildren().addAll(stationNode, icons);
|
||||
node.getChildren().addAll(entryNode);
|
||||
final int curIndex = entryNodes.size();
|
||||
entryNode.setOnMouseClicked(e -> {
|
||||
if (e.getButton() == MouseButton.PRIMARY){
|
||||
setActive(curIndex);
|
||||
}
|
||||
});
|
||||
entryNodes.add(entryNode);
|
||||
prev = entry.getStation();
|
||||
}
|
||||
}
|
||||
|
||||
private VBox buildText(StationModel station, boolean transit){
|
||||
Text systemText = new Text(station.getSystem().getName());
|
||||
systemText.getStyleClass().add(CSS_SYSTEM_TEXT);
|
||||
|
||||
VBox text = new VBox(2);
|
||||
VBox.setVgrow(text, Priority.ALWAYS);
|
||||
text.getStyleClass().add(CSS_TEXT);
|
||||
text.getChildren().addAll(systemText);
|
||||
|
||||
if (!transit) {
|
||||
Text stationText = new Text(station.getName());
|
||||
stationText.getStyleClass().add(CSS_STATION_TEXT);
|
||||
Text distanceText = new Text(String.format("%.0f Ls", station.getDistance()));
|
||||
distanceText.getStyleClass().add(CSS_STATION_TEXT);
|
||||
text.getChildren().addAll(stationText, distanceText);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public int getActive() {
|
||||
return active.get();
|
||||
}
|
||||
|
||||
public IntegerProperty activeProperty() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(int index){
|
||||
if (this.active.get() != -1){
|
||||
entryNodes.get(this.active.get()).getStyleClass().remove(CSS_ACTIVE_SYSTEM);
|
||||
}
|
||||
this.active.setValue(index);
|
||||
entryNodes.get(index).getStyleClass().add(CSS_ACTIVE_SYSTEM);
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,38 @@
|
||||
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="ru.trader.controllers.RouteTrackController"
|
||||
spacing="4" >
|
||||
<fx:include fx:id="missions" source="missions.fxml"/>
|
||||
<HBox>
|
||||
<ListView fx:id="missionsList" />
|
||||
<Button prefWidth="30" onAction="#removeMission"><graphic><Glyph text="FontAwesome|MINUS"/></graphic></Button>
|
||||
<Button prefWidth="80" text="Добавить" onAction="#addMissions" />
|
||||
</HBox>
|
||||
<HBox fx:id="track" minHeight="100"/>
|
||||
<ToggleButton minWidth="30" onAction="#toggleEdit">
|
||||
<graphic><Glyph text="FontAwesome|EDIT"/></graphic>
|
||||
</ToggleButton>
|
||||
<StackPane>
|
||||
<VBox fx:id="editGroup">
|
||||
<fx:include fx:id="missions" source="missions.fxml"/>
|
||||
<HBox>
|
||||
<ListView fx:id="addMissionsList" maxHeight="150"/>
|
||||
<Button prefWidth="30" onAction="#removeMission"><graphic><Glyph text="FontAwesome|MINUS"/></graphic></Button>
|
||||
<Button prefWidth="80" text="Добавить" onAction="#addMissions" />
|
||||
</HBox>
|
||||
</VBox>
|
||||
<VBox fx:id="infoGroup">
|
||||
<HBox><Label text="Система:" /><Label fx:id="system" /></HBox>
|
||||
<HBox><Label text="Станция:" /><Label fx:id="station" /></HBox>
|
||||
<HBox><Label text="Время:" /><Label fx:id="time" /></HBox>
|
||||
<HBox fx:id="refuelGroup"><Label text="Заправить:" /><Label fx:id="refuel" /></HBox>
|
||||
<HBox fx:id="ordersGroup" maxHeight="120">
|
||||
<VBox>
|
||||
<Label text="Продать:" />
|
||||
<ListView fx:id="sellOrders"/>
|
||||
</VBox>
|
||||
<VBox>
|
||||
<Label text="Купить:" />
|
||||
<ListView fx:id="buyOrders"/>
|
||||
</VBox>
|
||||
</HBox>
|
||||
<VBox fx:id="missionsGroup" maxHeight="120">
|
||||
<Label text="Сдать миссии:" />
|
||||
<ListView fx:id="missionsList" maxHeight="150"/>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</StackPane>
|
||||
</VBox>
|
||||
|
||||
@@ -55,47 +55,52 @@ HBox.fields-group hbox-margin{
|
||||
|
||||
|
||||
/* Path */
|
||||
.path {
|
||||
.route, .path {
|
||||
-fx-alignment: center-left;
|
||||
-fx-spacing: 5px;
|
||||
-fx-fill-height: true;
|
||||
}
|
||||
|
||||
.path-system {
|
||||
.route-system, .path-system {
|
||||
-fx-alignment: center-left;
|
||||
-fx-text-alignment: left;
|
||||
}
|
||||
|
||||
.path-text {
|
||||
.route-text, .path-text {
|
||||
-fx-alignment: center;
|
||||
}
|
||||
|
||||
.path-system-text {
|
||||
.route-system-text, .path-system-text {
|
||||
}
|
||||
|
||||
.path-station-text {
|
||||
.route-station-text, .path-station-text {
|
||||
-fx-font-size: 8pt;
|
||||
}
|
||||
|
||||
.path-icons {
|
||||
.route-icons, .path-icons {
|
||||
-fx-alignment: center;
|
||||
}
|
||||
|
||||
.path-track {
|
||||
.route-track, .path-track {
|
||||
-fx-padding: 0 8;
|
||||
-fx-alignment: center;
|
||||
}
|
||||
|
||||
.path-track .glyph-font {
|
||||
.route-track .glyph-font, .path-track .glyph-font {
|
||||
-fx-font-family: FontAwesome;
|
||||
-fx-font-size: 16pt;
|
||||
}
|
||||
|
||||
|
||||
.path-track-text {
|
||||
.route-track-text, .path-track-text {
|
||||
-fx-font-size: 7pt;
|
||||
}
|
||||
|
||||
.route-active {
|
||||
-fx-border-style: solid;
|
||||
-fx-background-color: lightskyblue;
|
||||
}
|
||||
|
||||
.path-pane {
|
||||
-fx-padding: 10;
|
||||
-fx-alignment: center-left;
|
||||
|
||||
Reference in New Issue
Block a user