Begin refactoring Navigation

This commit is contained in:
Chris Beams 2014-11-24 10:49:22 +01:00
parent 6de4e63973
commit 5a5bfd0826
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
13 changed files with 90 additions and 115 deletions

View file

@ -26,72 +26,71 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
public class Navigation { public class Navigation {
// New listeners can be added during iteration so we use CopyOnWriteArrayList to prevent invalid array
// modification private static final String CURRENT_PATH_KEY = "currentPath";
// TODO: MAIN->BUY is the default view for now; should be MAIN->HOME later
private static final FxmlView[] DEFAULT_PATH = new FxmlView[]{ FxmlView.MAIN, FxmlView.BUY };
// New listeners can be added during iteration so we use CopyOnWriteArrayList to
// prevent invalid array modification
private final List<Listener> listeners = new CopyOnWriteArrayList<>(); private final List<Listener> listeners = new CopyOnWriteArrayList<>();
private final Persistence persistence; private final Persistence persistence;
private FxmlView[] currentItems;
// Used for returning to the last important view private FxmlView[] currentPath;
// After setup is done we want to return to the last opened view (e.g. sell/buy)
private FxmlView[] itemsForReturning;
// Used for returning to the last important view. After setup is done we want to
// return to the last opened view (e.g. sell/buy)
private FxmlView[] returnPath;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public Navigation(Persistence persistence) { public Navigation(Persistence persistence) {
this.persistence = persistence; this.persistence = persistence;
} }
/////////////////////////////////////////////////////////////////////////////////////////// public void navigateTo(FxmlView... newPath) {
// Public methods if (newPath == null)
/////////////////////////////////////////////////////////////////////////////////////////// return;
public void navigationTo(FxmlView... items) {
List<FxmlView> temp = new ArrayList<>(); List<FxmlView> temp = new ArrayList<>();
if (items != null) { for (int i = 0; i < newPath.length; i++) {
for (int i = 0; i < items.length; i++) { FxmlView element = newPath[i];
FxmlView item = items[i]; temp.add(element);
temp.add(item); if (currentPath == null ||
if (currentItems == null || (currentPath != null &&
(currentItems != null && currentPath.length > i &&
currentItems.length > i && element != currentPath[i] &&
item != currentItems[i] && i != newPath.length - 1)) {
i != items.length - 1)) { List<FxmlView> temp2 = new ArrayList<>(temp);
List<FxmlView> temp2 = new ArrayList<>(temp); for (int n = i + 1; n < newPath.length; n++) {
for (int n = i + 1; n < items.length; n++) { FxmlView[] newTemp = new FxmlView[i + 1];
FxmlView[] newTemp = new FxmlView[i + 1]; currentPath = temp2.toArray(newTemp);
currentItems = temp2.toArray(newTemp); navigateTo(currentPath);
navigationTo(currentItems); element = newPath[n];
item = items[n]; temp2.add(element);
temp2.add(item);
}
} }
} }
currentItems = items;
persistence.write(this, "navigationItems", items);
listeners.stream().forEach((e) -> e.onNavigationRequested(items));
} }
currentPath = newPath;
persistence.write(this, CURRENT_PATH_KEY, currentPath);
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
} }
public void navigateToLastStoredItem() { public void navigateToLastOpenView() {
FxmlView[] items = (FxmlView[]) persistence.read(this, "navigationItems"); FxmlView[] lastPath = (FxmlView[]) persistence.read(this, CURRENT_PATH_KEY);
// TODO we set BUY as default yet, should be HOME later
if (items == null || items.length == 0)
items = new FxmlView[]{FxmlView.MAIN, FxmlView.BUY};
navigationTo(items); if (lastPath == null || lastPath.length == 0)
lastPath = DEFAULT_PATH;
navigateTo(lastPath);
} }
public static interface Listener {
/////////////////////////////////////////////////////////////////////////////////////////// void onNavigationRequested(FxmlView... path);
// Listeners }
///////////////////////////////////////////////////////////////////////////////////////////
public void addListener(Listener listener) { public void addListener(Listener listener) {
listeners.add(listener); listeners.add(listener);
@ -101,40 +100,16 @@ public class Navigation {
listeners.remove(listener); listeners.remove(listener);
} }
public FxmlView[] getReturnPath() {
/////////////////////////////////////////////////////////////////////////////////////////// return returnPath;
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public FxmlView[] getItemsForReturning() {
return itemsForReturning;
} }
public FxmlView[] getCurrentItems() { public FxmlView[] getCurrentPath() {
return currentItems; return currentPath;
} }
public void setReturnPath(FxmlView[] returnPath) {
/////////////////////////////////////////////////////////////////////////////////////////// this.returnPath = returnPath;
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setItemsForReturning(FxmlView[] itemsForReturning) {
this.itemsForReturning = itemsForReturning;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////////////////////
public static interface Listener {
void onNavigationRequested(FxmlView... items);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
} }

View file

@ -156,7 +156,7 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
model.numPendingTrades.addListener((ov2, prev2, numPendingTrades) -> model.numPendingTrades.addListener((ov2, prev2, numPendingTrades) ->
applyPendingTradesInfoIcon((int) numPendingTrades, portfolioButtonHolder)); applyPendingTradesInfoIcon((int) numPendingTrades, portfolioButtonHolder));
navigation.navigateToLastStoredItem(); navigation.navigateToLastOpenView();
transitions.fadeOutAndRemove(splashScreen, 1500); transitions.fadeOutAndRemove(splashScreen, 1500);
} }
@ -360,7 +360,7 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
} }
}); });
this.setOnAction(e -> navigation.navigationTo(FxmlView.MAIN, item)); this.setOnAction(e -> navigation.navigateTo(FxmlView.MAIN, item));
} }
} }
} }

View file

@ -58,10 +58,10 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == accountSettingsTab) if (newValue == accountSettingsTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS); FxmlView.ACCOUNT_SETTINGS);
else else
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ARBITRATOR_SETTINGS); FxmlView.ARBITRATOR_SETTINGS);
}; };
@ -72,18 +72,18 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener); root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
if (navigation.getCurrentItems().length == 2 && if (navigation.getCurrentPath().length == 2 &&
navigation.getCurrentItems()[1] == FxmlView.ACCOUNT) { navigation.getCurrentPath()[1] == FxmlView.ACCOUNT) {
if (model.getNeedRegistration()) { if (model.getNeedRegistration()) {
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETUP); FxmlView.ACCOUNT_SETUP);
} }
else { else {
if (root.getSelectionModel().getSelectedItem() == accountSettingsTab) if (root.getSelectionModel().getSelectedItem() == accountSettingsTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS); FxmlView.ACCOUNT_SETTINGS);
else else
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ARBITRATOR_SETTINGS); FxmlView.ARBITRATOR_SETTINGS);
} }
} }

View file

@ -89,10 +89,10 @@ class AccountSettingsView extends ActivatableViewAndModel {
@Override @Override
public void doActivate() { public void doActivate() {
navigation.addListener(listener); navigation.addListener(listener);
FxmlView[] items = navigation.getCurrentItems(); FxmlView[] items = navigation.getCurrentPath();
if (items.length == 3 && if (items.length == 3 &&
items[2] == FxmlView.ACCOUNT_SETTINGS) { items[2] == FxmlView.ACCOUNT_SETTINGS) {
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS, FxmlView.FIAT_ACCOUNT); FxmlView.ACCOUNT_SETTINGS, FxmlView.FIAT_ACCOUNT);
} }
else { else {
@ -164,7 +164,7 @@ class MenuItem extends ToggleButton {
setGraphic(icon); setGraphic(icon);
setOnAction((event) -> navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, setOnAction((event) -> navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS, navigationItem)); FxmlView.ACCOUNT_SETTINGS, navigationItem));
selectedProperty().addListener((ov, oldValue, newValue) -> { selectedProperty().addListener((ov, oldValue, newValue) -> {

View file

@ -146,10 +146,10 @@ class AccountSetupWizard extends ActivatableView implements Wizard {
else if (currentStep instanceof RegistrationView) { else if (currentStep instanceof RegistrationView) {
registration.onCompleted(); registration.onCompleted();
if (navigation.getItemsForReturning() != null) if (navigation.getReturnPath() != null)
navigation.navigationTo(navigation.getItemsForReturning()); navigation.navigateTo(navigation.getReturnPath());
else else
navigation.navigationTo(FxmlView.MAIN, FxmlView.BUY); navigation.navigateTo(FxmlView.MAIN, FxmlView.BUY);
} }
} }

View file

@ -58,9 +58,9 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == withdrawalTab) if (newValue == withdrawalTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL); navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL);
else if (newValue == transactionsTab) else if (newValue == transactionsTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS); navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS);
}; };
} }
@ -70,9 +70,9 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == transactionsTab) if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS); navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS);
else else
navigation.navigationTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL); navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL);
} }
@Override @Override

View file

@ -61,12 +61,12 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == offersTab) if (newValue == offersTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS);
else if (newValue == openTradesTab) else if (newValue == openTradesTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO,
FxmlView.PENDING_TRADES); FxmlView.PENDING_TRADES);
else if (newValue == closedTradesTab) else if (newValue == closedTradesTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.CLOSED_TRADES); navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.CLOSED_TRADES);
}; };
} }
@ -76,9 +76,9 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (tradeManager.getPendingTrades().size() == 0) if (tradeManager.getPendingTrades().size() == 0)
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS);
else else
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.PENDING_TRADES); navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.PENDING_TRADES);
} }
@Override @Override

View file

@ -181,7 +181,7 @@ class PendingTradesView extends ActivatableViewAndModel<AnchorPane, PendingTrade
setSummaryControlsVisible(false); setSummaryControlsVisible(false);
model.withdraw(withdrawAddressTextField.getText()); model.withdraw(withdrawAddressTextField.getText());
Platform.runLater(() -> Platform.runLater(() ->
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO,
FxmlView.CLOSED_TRADES)); FxmlView.CLOSED_TRADES));
} }

View file

@ -60,10 +60,10 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == preferencesTab) if (newValue == preferencesTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.SETTINGS, navigation.navigateTo(FxmlView.MAIN, FxmlView.SETTINGS,
FxmlView.PREFERENCES); FxmlView.PREFERENCES);
else if (newValue == networkSettingsTab) else if (newValue == networkSettingsTab)
navigation.navigationTo(FxmlView.MAIN, FxmlView.SETTINGS, navigation.navigateTo(FxmlView.MAIN, FxmlView.SETTINGS,
FxmlView.NETWORK_SETTINGS); FxmlView.NETWORK_SETTINGS);
}; };
} }
@ -74,11 +74,11 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == preferencesTab) if (root.getSelectionModel().getSelectedItem() == preferencesTab)
navigation.navigationTo(FxmlView.MAIN, navigation.navigateTo(FxmlView.MAIN,
FxmlView.SETTINGS, FxmlView.SETTINGS,
FxmlView.PREFERENCES); FxmlView.PREFERENCES);
else else
navigation.navigationTo(FxmlView.MAIN, navigation.navigateTo(FxmlView.MAIN,
FxmlView.SETTINGS, FxmlView.SETTINGS,
FxmlView.NETWORK_SETTINGS); FxmlView.NETWORK_SETTINGS);
} }

View file

@ -98,7 +98,7 @@ public class TradeView extends ActivatableView<TabPane, Void> {
}); });
navigation.addListener(listener); navigation.addListener(listener);
navigation.navigationTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK);
} }
@Override @Override
@ -110,14 +110,14 @@ public class TradeView extends ActivatableView<TabPane, Void> {
public void createOffer(Coin amount, Fiat price) { public void createOffer(Coin amount, Fiat price) {
this.amount = amount; this.amount = amount;
this.price = price; this.price = price;
navigation.navigationTo(FxmlView.MAIN, navigationItem, FxmlView.CREATE_OFFER); navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.CREATE_OFFER);
} }
public void takeOffer(Coin amount, Fiat price, Offer offer) { public void takeOffer(Coin amount, Fiat price, Offer offer) {
this.amount = amount; this.amount = amount;
this.price = price; this.price = price;
this.offer = offer; this.offer = offer;
navigation.navigationTo(FxmlView.MAIN, navigationItem, FxmlView.TAKE_OFFER); navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.TAKE_OFFER);
} }
private View loadView(FxmlView navigationItem) { private View loadView(FxmlView navigationItem) {
@ -173,14 +173,14 @@ public class TradeView extends ActivatableView<TabPane, Void> {
offerBookView.enableCreateOfferButton(); offerBookView.enableCreateOfferButton();
// update the navigation state // update the navigation state
navigation.navigationTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK);
} }
private void onTakeOfferViewRemoved() { private void onTakeOfferViewRemoved() {
takeOfferView = null; takeOfferView = null;
// update the navigation state // update the navigation state
navigation.navigationTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK);
} }
} }

View file

@ -222,7 +222,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
} }
private void openAccountSettings() { private void openAccountSettings() {
navigation.navigationTo(FxmlView.MAIN, navigation.navigateTo(FxmlView.MAIN,
FxmlView.ACCOUNT, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS, FxmlView.ACCOUNT_SETTINGS,
FxmlView.RESTRICTIONS); FxmlView.RESTRICTIONS);
@ -232,7 +232,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
TabPane tabPane = ((TabPane) (root.getParent().getParent())); TabPane tabPane = ((TabPane) (root.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS);
} }
private void setupListeners() { private void setupListeners() {

View file

@ -203,8 +203,8 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
getProperties().put("type", "OK"); getProperties().put("type", "OK");
Dialog.Actions.OK.handle(actionEvent); Dialog.Actions.OK.handle(actionEvent);
overlayManager.removeBlurContent(); overlayManager.removeBlurContent();
navigation.setItemsForReturning(navigation.getCurrentItems()); navigation.setReturnPath(navigation.getCurrentPath());
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETUP); FxmlView.ACCOUNT_SETUP);
} }
}); });
@ -255,7 +255,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
actions); actions);
if (Popups.isYes(response)) if (Popups.isYes(response))
navigation.navigationTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS, FxmlView.ACCOUNT_SETTINGS,
FxmlView.RESTRICTIONS); FxmlView.RESTRICTIONS);
else else

View file

@ -281,7 +281,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
getProperties().put("type", "CLOSE"); getProperties().put("type", "CLOSE");
try { try {
close(); close();
navigation.navigationTo(FxmlView.MAIN, FxmlView.PORTFOLIO, navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO,
FxmlView.PENDING_TRADES); FxmlView.PENDING_TRADES);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();