diff --git a/client/src/main/java/ru/trader/Main.java b/client/src/main/java/ru/trader/Main.java index 94bfe3d..ac84a34 100644 --- a/client/src/main/java/ru/trader/Main.java +++ b/client/src/main/java/ru/trader/Main.java @@ -94,6 +94,8 @@ public class Main extends Application { Screeners.loadSettingsStage(getUrl(("settings.fxml"))); Screeners.loadSEditorStage(getUrl(("sEditor.fxml"))); Screeners.loadFilterStage(getUrl(("filter.fxml"))); + Screeners.loadItemAddStage(getUrl("itemAdd.fxml")); + Screeners.loadGroupAddStage(getUrl("groupAdd.fxml")); } private static URL getUrl(String filename) throws MalformedURLException { diff --git a/client/src/main/java/ru/trader/controllers/GroupAddController.java b/client/src/main/java/ru/trader/controllers/GroupAddController.java new file mode 100644 index 0000000..5cb4d01 --- /dev/null +++ b/client/src/main/java/ru/trader/controllers/GroupAddController.java @@ -0,0 +1,54 @@ +package ru.trader.controllers; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.control.ComboBox; +import javafx.scene.control.TextField; +import org.controlsfx.control.ButtonBar; +import org.controlsfx.control.action.Action; +import org.controlsfx.dialog.Dialog; +import org.controlsfx.dialog.DialogAction; +import ru.trader.core.GROUP_TYPE; +import ru.trader.model.GroupModel; +import ru.trader.model.MarketModel; +import ru.trader.view.support.Localization; + +public class GroupAddController { + private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false); + + @FXML + private ComboBox type; + @FXML + private TextField name; + + + @FXML + private void initialize() { + type.setItems(FXCollections.observableArrayList(GROUP_TYPE.values())); + type.getSelectionModel().selectFirst(); + name.clear(); + } + + public GroupModel showDialog(Parent parent, Parent content, MarketModel market) { + + Dialog dlg = new Dialog(parent, Localization.getString("dialog.group.title")); + dlg.setContent(content); + dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL); + dlg.setResizable(false); + GroupModel res = dlg.show() == OK ? add(market) : null; + return res; + } + + private GroupModel add(MarketModel market){ + GROUP_TYPE t = type.getValue(); + String id = name.getText(); + GroupModel res = null; + if (t != null && id.length() > 0){ + res = market.addGroup(id, t); + } + return res; + } + +} diff --git a/client/src/main/java/ru/trader/controllers/GroupEditorController.java b/client/src/main/java/ru/trader/controllers/GroupEditorController.java deleted file mode 100644 index 94fc0a7..0000000 --- a/client/src/main/java/ru/trader/controllers/GroupEditorController.java +++ /dev/null @@ -1,4 +0,0 @@ -package ru.trader.controllers; - -public class GroupEditorController { -} diff --git a/client/src/main/java/ru/trader/controllers/ItemAddController.java b/client/src/main/java/ru/trader/controllers/ItemAddController.java new file mode 100644 index 0000000..0daaa15 --- /dev/null +++ b/client/src/main/java/ru/trader/controllers/ItemAddController.java @@ -0,0 +1,67 @@ +package ru.trader.controllers; + +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.control.ComboBox; +import javafx.scene.control.TextField; +import org.controlsfx.control.ButtonBar; +import org.controlsfx.control.action.Action; +import org.controlsfx.dialog.Dialog; +import org.controlsfx.dialog.DialogAction; +import ru.trader.model.GroupModel; +import ru.trader.model.ItemModel; +import ru.trader.model.MarketModel; +import ru.trader.view.support.Localization; + +import java.util.Optional; + + +public class ItemAddController { + private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false); + + @FXML + private ComboBox group; + @FXML + private TextField name; + + @FXML + private void initialize() { + + } + + private void init(MarketModel market) { + group.setItems(market.getGroups()); + group.getSelectionModel().selectFirst(); + name.clear(); + } + + public ItemModel showDialog(Parent parent, Parent content, MarketModel market) { + init(market); + Dialog dlg = new Dialog(parent, Localization.getString("dialog.item.title")); + dlg.setContent(content); + dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL); + dlg.setResizable(false); + ItemModel res = dlg.show() == OK ? add(market) : null; + return res; + } + + private ItemModel add(MarketModel market){ + GroupModel g = group.getValue(); + String id = name.getText(); + ItemModel res = null; + if (g != null && id.length() > 0){ + res = market.add(id, g); + } + return res; + } + + + public void add(ActionEvent actionEvent) { + Optional _group = Screeners.showAddGroup(); + if (_group.isPresent()){ + group.setValue(_group.get()); + } + } +} diff --git a/client/src/main/java/ru/trader/controllers/ItemsController.java b/client/src/main/java/ru/trader/controllers/ItemsController.java index fa1d254..4f72283 100644 --- a/client/src/main/java/ru/trader/controllers/ItemsController.java +++ b/client/src/main/java/ru/trader/controllers/ItemsController.java @@ -87,11 +87,19 @@ public class ItemsController { addItem(item); } + @Override + public void remove(SystemModel system) { + if (!system.isEmpty()) refresh(); + } + @Override public void add(StationModel station) { refresh(); } + @Override + public void remove(StationModel station) { refresh();} + @Override public void add(OfferModel offer) { sort(); diff --git a/client/src/main/java/ru/trader/controllers/MainController.java b/client/src/main/java/ru/trader/controllers/MainController.java index 2120ae4..629e5fc 100644 --- a/client/src/main/java/ru/trader/controllers/MainController.java +++ b/client/src/main/java/ru/trader/controllers/MainController.java @@ -8,16 +8,14 @@ import javafx.scene.control.RadioMenuItem; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.BorderPane; import javafx.stage.FileChooser; -import org.controlsfx.dialog.Dialogs; +import org.controlsfx.control.action.Action; +import org.controlsfx.dialog.Dialog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; import ru.trader.Main; import ru.trader.World; -import ru.trader.model.ItemModel; -import ru.trader.model.MarketModel; -import ru.trader.model.StationModel; -import ru.trader.model.SystemModel; +import ru.trader.model.*; import ru.trader.view.support.Localization; import javax.xml.stream.XMLStreamException; @@ -126,17 +124,13 @@ public class MainController { } } + public Optional addGroup(){ + GroupModel group = Screeners.showAddGroup(market); + return Optional.ofNullable(group); + } public Optional addItem(){ - Optional res = Dialogs.create() - .title(Localization.getString("dialog.addItem.title")) - .message(Localization.getString("dialog.addItem.message")) - .showTextInput(); - ItemModel item = null; - if (res.isPresent()){ - //TODO: implement groups -// item = market.add(res.get()); - } + ItemModel item = Screeners.showAddItem(market); return Optional.ofNullable(item); } @@ -147,11 +141,19 @@ public class MainController { public void editSystem(ActionEvent actionEvent){ SystemModel system = offersController.getSystem(); - Screeners.showSystemsEditor(system); + if (system != null) { + Screeners.showSystemsEditor(system); + } } public void removeSystem(ActionEvent actionEvent){ - //TODO: implement + SystemModel system = offersController.getSystem(); + if (system != null) { + Action res = Screeners.showConfirm(String.format(Localization.getString("dialog.confirm.remove"), system.getName())); + if (res == Dialog.ACTION_YES) { + market.remove(system); + } + } } public void addStation(ActionEvent actionEvent) { @@ -162,15 +164,20 @@ public class MainController { } public void editStation(ActionEvent actionEvent) { - //TODO: disable edit station, if station is null StationModel station = offersController.getStation(); - if (station!=null) { + if (station != null) { Screeners.showEditStation(offersController.getStation()); } } public void removeStation(ActionEvent actionEvent){ - //TODO: implement + StationModel station = offersController.getStation(); + if (station != null) { + Action res = Screeners.showConfirm(String.format(Localization.getString("dialog.confirm.remove"), station.getName())); + if (res == Dialog.ACTION_YES) { + station.getSystem().remove(station); + } + } } public void editSettings(){ diff --git a/client/src/main/java/ru/trader/controllers/OffersController.java b/client/src/main/java/ru/trader/controllers/OffersController.java index 670f532..2d8e98b 100644 --- a/client/src/main/java/ru/trader/controllers/OffersController.java +++ b/client/src/main/java/ru/trader/controllers/OffersController.java @@ -4,12 +4,8 @@ import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.geometry.Insets; -import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.input.MouseButton; -import javafx.scene.layout.Background; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; import org.controlsfx.control.SegmentedButton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,7 +14,6 @@ import ru.trader.core.SERVICE_TYPE; import ru.trader.model.*; import ru.trader.model.support.BindingsHelper; import ru.trader.model.support.ChangeMarketListener; -import ru.trader.view.support.NumberField; import java.util.List; @@ -142,6 +137,8 @@ public class OffersController { cbRepair.setSelected(false); cbOutfit.setSelected(false); cbShipyard.setSelected(false); + cbMediumLandpad.setSelected(false); + cbLargeLandpad.setSelected(false); if (station != null){ distance.setText(String.valueOf(station.getDistance())); cbMarket.setSelected(station.hasService(SERVICE_TYPE.MARKET)); @@ -245,5 +242,14 @@ public class OffersController { removeOffer(offer); } } + + @Override + public void remove(StationModel station) { + stationsBar.getToggleGroup().getSelectedToggle().setSelected(false); + stationsBar.getButtons().removeIf(b -> b.getUserData().equals(station)); + refresh(); + sort(); + } + } } diff --git a/client/src/main/java/ru/trader/controllers/RouterController.java b/client/src/main/java/ru/trader/controllers/RouterController.java index 35145f9..f7b464b 100644 --- a/client/src/main/java/ru/trader/controllers/RouterController.java +++ b/client/src/main/java/ru/trader/controllers/RouterController.java @@ -89,10 +89,18 @@ public class RouterController { Main.SETTINGS.setJumps(n.intValue()); }); source.valueProperty().addListener((ov, o, n) -> { - sStation.setItems(n.getStationsList()); + if (n != null) { + sStation.setItems(n.getStationsList()); + } else { + sStation.setItems(FXCollections.emptyObservableList()); + } }); target.valueProperty().addListener((ov, o, n) -> { - tStation.setItems(n.getStationsList()); + if (n != null) { + tStation.setItems(n.getStationsList()); + } else { + tStation.setItems(FXCollections.emptyObservableList()); + } }); diff --git a/client/src/main/java/ru/trader/controllers/Screeners.java b/client/src/main/java/ru/trader/controllers/Screeners.java index b8a190f..172596f 100644 --- a/client/src/main/java/ru/trader/controllers/Screeners.java +++ b/client/src/main/java/ru/trader/controllers/Screeners.java @@ -32,6 +32,8 @@ public class Screeners { private static Parent settingsScreen; private static Parent sEditorScreen; private static Parent filterScreen; + private static Parent itemAddScreen; + private static Parent groupAddScreen; private static MainController mainController; private static ItemDescController itemDescController; @@ -43,6 +45,8 @@ public class Screeners { private static SettingsController settingsController; private static SystemsEditorController systemsEditorController; private static FilterController filterController; + private static ItemAddController itemAddController; + private static GroupAddController groupAddController; private static FXMLLoader initLoader(URL url){ FXMLLoader loader = new FXMLLoader(url, Localization.getResources()); @@ -138,6 +142,20 @@ public class Screeners { filterController = loader.getController(); } + public static void loadItemAddStage(URL fxml) throws IOException { + FXMLLoader loader = initLoader(fxml); + itemAddScreen = loader.load(); + addStylesheet(itemAddScreen); + itemAddController = loader.getController(); + } + + public static void loadGroupAddStage(URL fxml) throws IOException { + FXMLLoader loader = initLoader(fxml); + groupAddScreen = loader.load(); + addStylesheet(groupAddScreen); + groupAddController = loader.getController(); + } + public static void show(Node node){ mainController.getMainPane().setCenter(node); } @@ -151,6 +169,14 @@ public class Screeners { return Dialogs.create().owner(mainScreen).message(text).showConfirm(); } + public static GroupModel showAddGroup(MarketModel market){ + return groupAddController.showDialog(mainScreen, groupAddScreen, market); + } + + public static ItemModel showAddItem(MarketModel market){ + return itemAddController.showDialog(mainScreen, itemAddScreen, market); + } + public static void showSystemsEditor(SystemModel system){ systemsEditorController.showDialog(mainScreen, sEditorScreen, system); } @@ -188,6 +214,9 @@ public class Screeners { public static Optional showAddItem(){ return mainController.addItem(); } + public static Optional showAddGroup(){ + return mainController.addGroup(); + } public static void closeAll() { itemDescController.close(); diff --git a/client/src/main/java/ru/trader/model/GroupModel.java b/client/src/main/java/ru/trader/model/GroupModel.java new file mode 100644 index 0000000..3ea626f --- /dev/null +++ b/client/src/main/java/ru/trader/model/GroupModel.java @@ -0,0 +1,46 @@ +package ru.trader.model; + +import javafx.beans.property.ReadOnlyStringProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import ru.trader.core.Group; +import ru.trader.view.support.Localization; + +public class GroupModel { + + private final Group group; + private StringProperty name; + + + GroupModel(Group group) { + this.group = group; + } + + Group getGroup(){ + return group; + } + + public String getId() { + return group.getName(); + } + + public String getName() { + return name != null ? name.get() : buildName(); + } + + public ReadOnlyStringProperty nameProperty() { + if (name == null) { + name = new SimpleStringProperty(buildName()); + } + return name; + } + + private String buildName(){ + return Localization.getString("item.group." + group.getName(), group.getName()); + } + + @Override + public String toString() { + return getName(); + } +} diff --git a/client/src/main/java/ru/trader/model/MarketModel.java b/client/src/main/java/ru/trader/model/MarketModel.java index bafbee8..9b63fb0 100644 --- a/client/src/main/java/ru/trader/model/MarketModel.java +++ b/client/src/main/java/ru/trader/model/MarketModel.java @@ -28,6 +28,7 @@ public class MarketModel { private final ListProperty systems; // with NONE_SYSTEM private ListProperty systemsList; + private final ListProperty groups; private final ListProperty items; public MarketModel(Market market) { @@ -35,6 +36,7 @@ public class MarketModel { analyzer = World.buildAnalyzer(market); modeler = new ModelFabric(this); notificator = new Notificator(); + groups = new SimpleListProperty<>(BindingsHelper.observableList(market.getGroups(), modeler::get)); items = new SimpleListProperty<>(BindingsHelper.observableList(market.getItems(), modeler::get)); systems = new SimpleListProperty<>(BindingsHelper.observableList(market.get(), modeler::get)); systemsList = new SimpleListProperty<>(FXCollections.observableArrayList(ModelFabric.NONE_SYSTEM)); @@ -80,12 +82,30 @@ public class MarketModel { return system; } + public void remove(SystemModel system) { + LOG.info("Remove system {} from market {}", system, this); + notificator.sendRemove(system); + market.remove(system.getSystem()); + systems.remove(system); + } + + public ReadOnlyListProperty getGroups(){ + return groups; + } + + public GroupModel addGroup(String name, GROUP_TYPE type){ + GroupModel group = modeler.get(market.addGroup(name, type)); + LOG.info("Add group {} to market {}", group, this); + groups.add(group); + return group; + } + public ReadOnlyListProperty itemsProperty() { return items; } - public ItemModel add(String name, Group group) { - ItemModel item = modeler.get(market.addItem(name, group)); + public ItemModel add(String name, GroupModel group) { + ItemModel item = modeler.get(market.addItem(name, group.getGroup())); LOG.info("Add item {} to market {}", item, this); notificator.sendAdd(item); items.add(item); diff --git a/client/src/main/java/ru/trader/model/ModelFabric.java b/client/src/main/java/ru/trader/model/ModelFabric.java index 1a1d55b..23f75d9 100644 --- a/client/src/main/java/ru/trader/model/ModelFabric.java +++ b/client/src/main/java/ru/trader/model/ModelFabric.java @@ -67,6 +67,11 @@ public class ModelFabric { return model.getStation(); } + public GroupModel get(Group group){ + if (group == null) return null; + return new GroupModel(group); + } + public ItemModel get(Item item){ if (item == null) return null; ItemModel res=null; diff --git a/client/src/main/java/ru/trader/model/SystemModel.java b/client/src/main/java/ru/trader/model/SystemModel.java index f2892be..862b78d 100644 --- a/client/src/main/java/ru/trader/model/SystemModel.java +++ b/client/src/main/java/ru/trader/model/SystemModel.java @@ -99,6 +99,16 @@ public class SystemModel { return station; } + public void remove(StationModel station) { + LOG.info("Remove station {} from system {}", station, this); + market.getNotificator().sendRemove(station); + system.remove(station.getStation()); + } + + public boolean isEmpty(){ + return system.isEmpty(); + } + @Override public String toString() { if (LOG.isTraceEnabled()){ diff --git a/client/src/main/resources/lang/locale_en_US.properties b/client/src/main/resources/lang/locale_en_US.properties index 56dac4e..c738c81 100644 --- a/client/src/main/resources/lang/locale_en_US.properties +++ b/client/src/main/resources/lang/locale_en_US.properties @@ -35,6 +35,7 @@ routes.lands=Landings # Dialog dialog.confirm.save=Changes were not saved, save changes? +dialog.confirm.remove=Are you sure you want to delete %s? dialog.button.save=Save dialog.button.edit=Edit dialog.button.remove=Remove @@ -60,8 +61,13 @@ main.menu.settings.parameters=Preferences main.menu.settings.filter=Filter # add item dialog -dialog.addItem.title=Adding new commodity -dialog.addItem.message=Enter commodity name +dialog.item.title=Adding new commodity +dialog.item.id=ID: +dialog.item.group=Group: +# add group dialog +dialog.group.title=Adding new group +dialog.group.id=ID: +dialog.group.type=Type: # items.fxml @@ -105,7 +111,7 @@ router.pane.route=Route parameters router.pane.route.from=From: router.pane.route.to=To: router.pane.route.jumps=Jumps: -route.button.top=TOP 100 +router.button.top=TOP 100 router.pane.total=Total router.pane.total.profit=Profit: diff --git a/client/src/main/resources/lang/locale_ru_RU.properties b/client/src/main/resources/lang/locale_ru_RU.properties index ba27e52..af6f965 100644 --- a/client/src/main/resources/lang/locale_ru_RU.properties +++ b/client/src/main/resources/lang/locale_ru_RU.properties @@ -35,6 +35,7 @@ routes.lands=\u041F\u043E\u0441\u0430\u0434\u043E\u043A # Dialog dialog.confirm.save=\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043D\u0435 \u0431\u044B\u043B\u0438 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B, \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C? +dialog.confirm.remove=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C %s? dialog.button.save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C dialog.button.edit=\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C dialog.button.remove=\u0423\u0434\u0430\u043B\u0438\u0442\u044C @@ -61,8 +62,13 @@ main.menu.settings.parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u main.menu.settings.filter=\u0424\u0438\u043B\u044C\u0442\u0440 # add item dialog -dialog.addItem.title=\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0433\u043E \u0442\u043E\u0432\u0430\u0440\u0430 -dialog.addItem.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0442\u043E\u0432\u0430\u0440\u0430 +dialog.item.title=\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0433\u043E \u0442\u043E\u0432\u0430\u0440\u0430 +dialog.item.id=ID: +dialog.item.group=\u0413\u0440\u0443\u043F\u043F\u0430: +# add group dialog +dialog.group.title=\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0433\u0440\u0443\u043F\u043F\u044B +dialog.group.id=ID: +dialog.group.type=\u0422\u0438\u043F: # items.fxml @@ -105,7 +111,7 @@ router.pane.route=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043C\ router.pane.route.from=\u041E\u0442: router.pane.route.to=\u0414\u043E: router.pane.route.jumps=\u041F\u0440\u044B\u0436\u043A\u043E\u0432: -route.button.top=TOP 100 +router.button.top=TOP 100 router.pane.total=\u0418\u0442\u043E\u0433\u043E router.pane.total.profit=\u041F\u0440\u0438\u0431\u044B\u043B\u044C: diff --git a/client/src/main/resources/view/groupAdd.fxml b/client/src/main/resources/view/groupAdd.fxml new file mode 100644 index 0000000..dc8ff89 --- /dev/null +++ b/client/src/main/resources/view/groupAdd.fxml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/client/src/main/resources/view/itemAdd.fxml b/client/src/main/resources/view/itemAdd.fxml new file mode 100644 index 0000000..b0cdb2a --- /dev/null +++ b/client/src/main/resources/view/itemAdd.fxml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/client/src/main/resources/view/router.fxml b/client/src/main/resources/view/router.fxml index 49c6aa6..c24936c 100644 --- a/client/src/main/resources/view/router.fxml +++ b/client/src/main/resources/view/router.fxml @@ -56,11 +56,11 @@