Merge branch 'cbeams'

Overview of major changes:

 - Introduce top-level `viewfx` package for general-purpose MVVM-style
   infrastructure classes. Note that this package naming will likely
   change, especially if and when we extract it to a physically-separate
   library.

 - Introduce View and Model class hierarchies that capture the various
   lifecycle and model management concerns throughout the existing
   Bitsquare application (see `viewfx.view` and `viewfx.model` packages)

 - Introduce @FxmlView and FxmlViewLoader to support declarative,
   convention-over-configuration support for FXML-based views.
   Eventually, this approach will allow for seamless mixing of FXML- and
   non-FXML based view implementations within the same application.

 - Introduce a type-safe approach to intra-view navigation: eliminate
   the Navigation.Item enum in favor of navigating directly from one
   view to another using *View class literals. This change is closely
   tied to the @FxmlView approach described above.

Many additional smaller changes are included as well; see individual
commits for details.

* cbeams: (75 commits)
  Rename viewfx.view.support.guice.{Guice=>Injector}ViewFactory
  Use instanceof checks on views instead of class equality
  Add CachingViewLoaderTests
  Revert "Remove System#exit call from BitsquareApp#stop"
  Change signature of ViewLoader#load to accept Class
  Complete implementation and testing of @FxmlView support
  Remove System#exit call from BitsquareApp#stop
  fix checkArgument
  Use irc instead of fiat classes
  Remove hardcoded path from ViewLoaderTests
  Fix conditional logic in AccountView#activate
  Polish AccountSettingsView
  Introduce @FxmlView, replace Navigation.Item
  Begin refactoring Navigation
  Rename enum gui.{Navigation#Item => FxmlView}
  Introduce viewfx.view.support.CachingViewLoader
  Extract ViewLoader interface and introduce FxmlViewLoader
  Fix broken tests and app exceptions due to ViewLoader changes
  Bind ViewFactory interface to GuiceViewFactory impl
  Move i.b.gui.ViewLoader.java => viewfx.view.support.ViewLoader
  ...
This commit is contained in:
Chris Beams 2014-11-25 22:13:36 +01:00
commit 58335f036e
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
192 changed files with 3988 additions and 6716 deletions

View file

@ -48,6 +48,8 @@
<emptyLine /> <emptyLine />
<package name="javax.swing" withSubpackages="true" static="false" /> <package name="javax.swing" withSubpackages="true" static="false" />
<emptyLine /> <emptyLine />
<package name="viewfx" withSubpackages="true" static="false" />
<emptyLine />
<package name="javafx" withSubpackages="true" static="false" /> <package name="javafx" withSubpackages="true" static="false" />
<emptyLine /> <emptyLine />
<package name="com.sun.javafx" withSubpackages="true" static="false" /> <package name="com.sun.javafx" withSubpackages="true" static="false" />
@ -87,4 +89,3 @@
<option name="USE_PER_PROJECT_SETTINGS" value="true" /> <option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component> </component>
</project> </project>

View file

@ -17,6 +17,7 @@ version = '0.1.0-SNAPSHOT'
sourceCompatibility = 1.8 sourceCompatibility = 1.8
sourceSets.main.resources.srcDirs += 'src/main/java' sourceSets.main.resources.srcDirs += 'src/main/java'
sourceSets.test.resources.srcDirs += 'src/test/java'
mainClassName = "io.bitsquare.app.gui.BitsquareAppMain" mainClassName = "io.bitsquare.app.gui.BitsquareAppMain"
@ -58,6 +59,7 @@ dependencies {
compile 'org.jetbrains:annotations:13.0' compile 'org.jetbrains:annotations:13.0'
compile 'eu.hansolo.enzo:Enzo:0.1.5' compile 'eu.hansolo.enzo:Enzo:0.1.5'
testCompile 'junit:junit:4.11' testCompile 'junit:junit:4.11'
testCompile "org.mockito:mockito-core:1.+"
testCompile 'org.springframework:spring-test:4.1.1.RELEASE' testCompile 'org.springframework:spring-test:4.1.1.RELEASE'
} }

View file

@ -20,7 +20,7 @@ package io.bitsquare.app;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.btc.UserAgent; import io.bitsquare.btc.UserAgent;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.ViewCB; import io.bitsquare.gui.main.MainView;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import io.bitsquare.util.spring.JOptCommandLinePropertySource; import io.bitsquare.util.spring.JOptCommandLinePropertySource;
@ -122,7 +122,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
setProperty(Persistence.DIR_KEY, appDataDir); setProperty(Persistence.DIR_KEY, appDataDir);
setProperty(Persistence.PREFIX_KEY, appName + "_pref"); setProperty(Persistence.PREFIX_KEY, appName + "_pref");
setProperty(ViewCB.TITLE_KEY, appName); setProperty(MainView.TITLE_KEY, appName);
}}); }});
} }

View file

@ -22,8 +22,7 @@ import joptsimple.OptionParser;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static java.lang.String.format; import static java.lang.String.*;
import static java.lang.String.join;
public abstract class BitsquareExecutable { public abstract class BitsquareExecutable {
public static final int EXIT_SUCCESS = 0; public static final int EXIT_SUCCESS = 0;

View file

@ -19,11 +19,9 @@ package io.bitsquare.app.gui;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.account.AccountSettings; import io.bitsquare.account.AccountSettings;
import io.bitsquare.gui.GuiceControllerFactory;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.SystemTray; import io.bitsquare.gui.SystemTray;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -40,6 +38,11 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.guice.InjectorViewFactory;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.image.*; import javafx.scene.image.*;
@ -64,7 +67,7 @@ public class BitsquareApp extends Application {
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
bitsquareAppModule = new BitsquareAppModule(env, primaryStage); bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
injector = Guice.createInjector(bitsquareAppModule); injector = Guice.createInjector(bitsquareAppModule);
injector.getInstance(GuiceControllerFactory.class).setInjector(injector); injector.getInstance(InjectorViewFactory.class).setInjector(injector);
// route uncaught exceptions to a user-facing dialog // route uncaught exceptions to a user-facing dialog
@ -93,10 +96,10 @@ public class BitsquareApp extends Application {
// load the main view and create the main scene // load the main view and create the main scene
ViewLoader viewLoader = injector.getInstance(ViewLoader.class); ViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
ViewLoader.Item loaded = viewLoader.load(Navigation.Item.MAIN.getFxmlUrl(), false); View view = viewLoader.load(MainView.class);
Scene scene = new Scene((Parent) loaded.view, 1000, 600); Scene scene = new Scene((Parent) view.getRoot(), 1000, 600);
scene.getStylesheets().setAll( scene.getStylesheets().setAll(
"/io/bitsquare/gui/bitsquare.css", "/io/bitsquare/gui/bitsquare.css",
"/io/bitsquare/gui/images.css"); "/io/bitsquare/gui/images.css");

View file

@ -30,7 +30,6 @@ import joptsimple.OptionSet;
import static io.bitsquare.app.BitsquareEnvironment.*; import static io.bitsquare.app.BitsquareEnvironment.*;
import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*; import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
import static io.bitsquare.network.Node.*; import static io.bitsquare.network.Node.*;
import static java.lang.String.format;
public class BitsquareAppMain extends BitsquareExecutable { public class BitsquareAppMain extends BitsquareExecutable {

View file

@ -19,9 +19,6 @@ package io.bitsquare.arbitrator;
import java.io.Serializable; import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//TODO still open if we use that really... //TODO still open if we use that really...
/** /**
@ -30,8 +27,6 @@ import org.slf4j.LoggerFactory;
public class Reputation implements Serializable { public class Reputation implements Serializable {
private static final long serialVersionUID = -3073174320050879490L; private static final long serialVersionUID = -3073174320050879490L;
private static final Logger log = LoggerFactory.getLogger(Reputation.class);
//TODO //TODO
public Reputation() { public Reputation() {
} }

View file

@ -1,104 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import java.net.URL;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* If caching is used for loader we use the CachedViewController for turning the controller into sleep mode if not
* active and awake it at reactivation.
* * @param <T> The PresentationModel used in that class
*/
public class CachedViewCB<T extends PresentationModel> extends ViewCB<T> {
private static final Logger log = LoggerFactory.getLogger(CachedViewCB.class);
public CachedViewCB(T presentationModel) {
super(presentationModel);
}
public CachedViewCB() {
super();
}
/**
* Get called form GUI framework when the UI is ready.
* In caching controllers the initialize is only used for static UI setup.
* The activate() method is called to start resources like.
*
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
if (root != null) {
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene
// lets terminate
log.trace("Lifecycle: sceneProperty changed: " + this.getClass().getSimpleName() + " / oldValue=" +
oldValue + " / newValue=" + newValue);
if (oldValue == null && newValue != null)
activate();
else if (oldValue != null && newValue == null)
deactivate();
});
}
if (presentationModel != null)
presentationModel.initialize();
}
/**
* Used to activate resources (adding listeners, starting timers or animations,...)
*/
public void activate() {
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
if (presentationModel != null)
presentationModel.activate();
}
/**
* Used for deactivating resources (removing listeners, stopping timers or animations,...)
*/
public void deactivate() {
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
if (presentationModel != null)
presentationModel.deactivate();
}
/**
* In caching controllers the terminate calls the deactivate method.
*/
@Override
public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
super.terminate();
if (presentationModel != null)
presentationModel.terminate();
}
}

View file

@ -19,6 +19,7 @@ package io.bitsquare.gui;
import io.bitsquare.BitsquareModule; import io.bitsquare.BitsquareModule;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.trade.offerbook.OfferBook; import io.bitsquare.gui.main.trade.offerbook.OfferBook;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Transitions; import io.bitsquare.gui.util.Transitions;
@ -27,9 +28,19 @@ import io.bitsquare.gui.util.validation.BtcValidator;
import io.bitsquare.gui.util.validation.FiatValidator; import io.bitsquare.gui.util.validation.FiatValidator;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator; import io.bitsquare.gui.util.validation.PasswordValidator;
import io.bitsquare.locale.BSResources;
import com.google.inject.Singleton;
import com.google.inject.name.Names; import com.google.inject.name.Names;
import java.util.ResourceBundle;
import viewfx.view.ViewFactory;
import viewfx.view.ViewLoader;
import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.fxml.FxmlViewLoader;
import viewfx.view.support.guice.InjectorViewFactory;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@ -45,8 +56,12 @@ public class GuiModule extends BitsquareModule {
@Override @Override
protected void configure() { protected void configure() {
bind(GuiceControllerFactory.class).asEagerSingleton(); bind(InjectorViewFactory.class).in(Singleton.class);
bind(ViewLoader.class).asEagerSingleton(); bind(ViewFactory.class).to(InjectorViewFactory.class);
bind(ResourceBundle.class).toInstance(BSResources.getResourceBundle());
bind(ViewLoader.class).to(FxmlViewLoader.class).asEagerSingleton();
bind(CachingViewLoader.class).asEagerSingleton();
bind(OfferBook.class).asEagerSingleton(); bind(OfferBook.class).asEagerSingleton();
bind(Navigation.class).asEagerSingleton(); bind(Navigation.class).asEagerSingleton();
@ -63,6 +78,6 @@ public class GuiModule extends BitsquareModule {
bind(Stage.class).toInstance(primaryStage); bind(Stage.class).toInstance(primaryStage);
Popups.primaryStage = primaryStage; Popups.primaryStage = primaryStage;
bindConstant().annotatedWith(Names.named(ViewCB.TITLE_KEY)).to(env.getRequiredProperty(ViewCB.TITLE_KEY)); bindConstant().annotatedWith(Names.named(MainView.TITLE_KEY)).to(env.getRequiredProperty(MainView.TITLE_KEY));
} }
} }

View file

@ -17,89 +17,90 @@
package io.bitsquare.gui; package io.bitsquare.gui;
import io.bitsquare.BitsquareException; import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.trade.BuyView;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.net.URL; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger; import viewfx.view.View;
import org.slf4j.LoggerFactory; import viewfx.view.ViewPath;
public class Navigation { public class Navigation {
private static final Logger log = LoggerFactory.getLogger(Navigation.class);
// New listeners can be added during iteration so we use CopyOnWriteArrayList to prevent invalid array private static final String CURRENT_PATH_KEY = "currentPath";
// modification
private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, BuyView.class);
// 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 Item[] currentItems;
// Used for returning to the last important view private ViewPath currentPath;
// After setup is done we want to return to the last opened view (e.g. sell/buy)
private Item[] 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 ViewPath returnPath;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public Navigation(Persistence persistence) { public Navigation(Persistence persistence) {
this.persistence = persistence; this.persistence = persistence;
} }
/////////////////////////////////////////////////////////////////////////////////////////// public void navigateTo(Class<? extends View>... viewClasses) {
// Public methods navigateTo(ViewPath.to(viewClasses));
/////////////////////////////////////////////////////////////////////////////////////////// }
public void navigationTo(Item... items) { public void navigateTo(ViewPath newPath) {
List<Item> temp = new ArrayList<>(); if (newPath == null)
if (items != null) { return;
for (int i = 0; i < items.length; i++) {
Item item = items[i]; ArrayList<Class<? extends View>> temp = new ArrayList<>();
temp.add(item); for (int i = 0; i < newPath.size(); i++) {
if (currentItems == null || Class<? extends View> viewClass = newPath.get(i);
(currentItems != null && temp.add(viewClass);
currentItems.length > i && if (currentPath == null ||
item != currentItems[i] && (currentPath != null &&
i != items.length - 1)) { currentPath.size() > i &&
List<Item> temp2 = new ArrayList<>(temp); viewClass != currentPath.get(i) &&
for (int n = i + 1; n < items.length; n++) { i != newPath.size() - 1)) {
Item[] newTemp = new Item[i + 1]; ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp);
currentItems = temp2.toArray(newTemp); for (int n = i + 1; n < newPath.size(); n++) {
navigationTo(currentItems); Class<? extends View>[] newTemp = new Class[i + 1];
item = items[n]; currentPath = ViewPath.to(temp2.toArray(newTemp));
temp2.add(item); navigateTo(currentPath);
} viewClass = newPath.get(n);
temp2.add(viewClass);
} }
} }
currentItems = items;
persistence.write(this, "navigationItems", items);
listeners.stream().forEach((e) -> e.onNavigationRequested(items));
} }
currentPath = newPath;
persistence.write(this, CURRENT_PATH_KEY, (List<? extends Serializable>)currentPath);
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
} }
public void navigateToLastStoredItem() { public void navigateToLastOpenView() {
Item[] items = (Item[]) persistence.read(this, "navigationItems"); ViewPath lastPath = (ViewPath) 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 Item[]{Item.MAIN, Item.BUY};
navigationTo(items); if (lastPath == null || lastPath.size() == 0)
lastPath = DEFAULT_VIEW_PATH;
navigateTo(lastPath);
} }
public static interface Listener {
/////////////////////////////////////////////////////////////////////////////////////////// void onNavigationRequested(ViewPath path);
// Listeners }
///////////////////////////////////////////////////////////////////////////////////////////
public void addListener(Listener listener) { public void addListener(Listener listener) {
listeners.add(listener); listeners.add(listener);
@ -109,146 +110,15 @@ public class Navigation {
listeners.remove(listener); listeners.remove(listener);
} }
public ViewPath getReturnPath() {
/////////////////////////////////////////////////////////////////////////////////////////// return returnPath;
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public Item[] getItemsForReturning() {
return itemsForReturning;
} }
public Item[] getCurrentItems() { public ViewPath getCurrentPath() {
return currentItems; return currentPath;
} }
public void setReturnPath(ViewPath returnPath) {
/////////////////////////////////////////////////////////////////////////////////////////// this.returnPath = returnPath;
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setItemsForReturning(Item[] itemsForReturning) {
this.itemsForReturning = itemsForReturning;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////////////////////
public static interface Listener {
void onNavigationRequested(Item... items);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
public static enum Item {
///////////////////////////////////////////////////////////////////////////////////////////
// Application
///////////////////////////////////////////////////////////////////////////////////////////
MAIN("/io/bitsquare/gui/main/MainView.fxml"),
///////////////////////////////////////////////////////////////////////////////////////////
// Main menu screens
///////////////////////////////////////////////////////////////////////////////////////////
HOME("/io/bitsquare/gui/main/home/HomeView.fxml", "Overview"),
BUY("/io/bitsquare/gui/main/trade/BuyView.fxml", "Buy BTC"),
SELL("/io/bitsquare/gui/main/trade/SellView.fxml", "Sell BTC"),
PORTFOLIO("/io/bitsquare/gui/main/portfolio/PortfolioView.fxml", "Portfolio"),
FUNDS("/io/bitsquare/gui/main/funds/FundsView.fxml", "Funds"),
MSG("/io/bitsquare/gui/main/msg/MsgView.fxml", "Messages"),
SETTINGS("/io/bitsquare/gui/main/settings/SettingsView.fxml", "Settings"),
ACCOUNT("/io/bitsquare/gui/main/account/AccountView.fxml", "Account"),
///////////////////////////////////////////////////////////////////////////////////////////
// Sub menus
///////////////////////////////////////////////////////////////////////////////////////////
// buy/sell (trade)
OFFER_BOOK("/io/bitsquare/gui/main/trade/offerbook/OfferBookView.fxml"),
CREATE_OFFER("/io/bitsquare/gui/main/trade/createoffer/CreateOfferView.fxml"),
TAKE_OFFER("/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.fxml"),
// portfolio
OFFERS("/io/bitsquare/gui/main/portfolio/offer/OffersView.fxml"),
PENDING_TRADES("/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.fxml"),
CLOSED_TRADES("/io/bitsquare/gui/main/portfolio/closed/ClosedTradesView.fxml"),
// funds
WITHDRAWAL("/io/bitsquare/gui/main/funds/withdrawal/WithdrawalView.fxml"),
TRANSACTIONS("/io/bitsquare/gui/main/funds/transactions/TransactionsView.fxml"),
// settings
PREFERENCES("/io/bitsquare/gui/main/settings/application/PreferencesView.fxml"),
NETWORK_SETTINGS("/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml"),
// account
ACCOUNT_SETUP("/io/bitsquare/gui/main/account/setup/AccountSetupView.fxml"),
ACCOUNT_SETTINGS("/io/bitsquare/gui/main/account/settings/AccountSettingsView.fxml"),
ARBITRATOR_SETTINGS("/io/bitsquare/gui/main/account/arbitrator/ArbitratorSettingsView.fxml"),
///////////////////////////////////////////////////////////////////////////////////////////
// Content in sub menus
///////////////////////////////////////////////////////////////////////////////////////////
// account content
SEED_WORDS("/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.fxml"),
ADD_PASSWORD("/io/bitsquare/gui/main/account/content/password/PasswordView.fxml"),
CHANGE_PASSWORD("/io/bitsquare/gui/main/account/content/password/PasswordView.fxml"),
RESTRICTIONS("/io/bitsquare/gui/main/account/content/restrictions/RestrictionsView.fxml"),
REGISTRATION("/io/bitsquare/gui/main/account/content/registration/RegistrationView.fxml"),
FIAT_ACCOUNT("/io/bitsquare/gui/main/account/content/irc/IrcAccountView.fxml"),
///////////////////////////////////////////////////////////////////////////////////////////
// Popups
///////////////////////////////////////////////////////////////////////////////////////////
// arbitrator
ARBITRATOR_PROFILE("/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.fxml"),
ARBITRATOR_BROWSER("/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserView.fxml"),
ARBITRATOR_REGISTRATION(
"/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.fxml"),
// for testing, does not actually exist
BOGUS("/io/bitsquare/BogusView.fxml");
private final String displayName;
private final String fxmlUrl;
Item(String fxmlUrl) {
this(fxmlUrl, "NONE");
}
Item(String fxmlUrl, String displayName) {
this.displayName = displayName;
this.fxmlUrl = fxmlUrl;
}
public URL getFxmlUrl() {
URL url = Navigation.class.getResource(fxmlUrl);
if (url == null)
throw new BitsquareException("'%s' could not be loaded as a resource", fxmlUrl);
return url;
}
public String getDisplayName() {
return displayName;
}
public String getId() {
return fxmlUrl.substring(fxmlUrl.lastIndexOf("/") + 1, fxmlUrl.lastIndexOf("View.fxml")).toLowerCase();
}
} }
} }

View file

@ -22,11 +22,7 @@ import com.google.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OverlayManager { public class OverlayManager {
private static final Logger log = LoggerFactory.getLogger(OverlayManager.class);
private final List<OverlayListener> listeners = new ArrayList<>(); private final List<OverlayListener> listeners = new ArrayList<>();

View file

@ -1,58 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PresentationModel<T extends UIModel> {
private static final Logger log = LoggerFactory.getLogger(PresentationModel.class);
protected T model;
public PresentationModel(T model) {
this.model = model;
}
public PresentationModel() {
}
public void initialize() {
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
if (model != null)
model.initialize();
}
public void activate() {
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
if (model != null)
model.activate();
}
public void deactivate() {
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
if (model != null)
model.deactivate();
}
public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
if (model != null)
model.terminate();
}
}

View file

@ -1,106 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Non caching version for code behind classes using the PM pattern
*
* @param <T> The PresentationModel used in that class
*/
public class ViewCB<T extends PresentationModel> implements Initializable {
private static final Logger log = LoggerFactory.getLogger(ViewCB.class);
public static final String TITLE_KEY = "view.title";
protected T presentationModel;
protected Initializable childController;
protected Initializable parent;
@FXML protected Parent root;
protected ViewCB(T presentationModel) {
this.presentationModel = presentationModel;
}
protected ViewCB() {
}
/**
* Get called form GUI framework when the UI is ready.
*
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
if (root != null) {
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene
// lets terminate
if (oldValue != null && newValue == null)
terminate();
});
}
if (presentationModel != null)
presentationModel.initialize();
}
/**
* Called automatically when view gets removed. Used for house keeping (removing listeners,
* stopping timers or animations,...).
*/
public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
if (presentationModel != null)
presentationModel.terminate();
}
/**
* @param parent Controller who has created this.getClass().getSimpleName() instance (via
* navigateToView/FXMLLoader).
*/
public void setParent(Initializable parent) {
log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " +
parent);
this.parent = parent;
}
/**
* @param navigationItem NavigationItem to be loaded.
* @return The ViewController of the loaded view.
*/
protected Initializable loadView(Navigation.Item navigationItem) {
log.trace("Lifecycle: loadViewAndGetChildController " + this.getClass().getSimpleName() + " / navigationItem " +
"= " + navigationItem);
return null;
}
}

View file

@ -1,84 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import io.bitsquare.BitsquareException;
import io.bitsquare.locale.BSResources;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.*;
import javafx.util.BuilderFactory;
/**
* Guice support for fxml controllers
* Support caching to speed up switches between UI screens.
*/
public class ViewLoader {
private final Map<URL, Item> cache = new HashMap<>();
private final BuilderFactory builderFactory = new JavaFXBuilderFactory();
private final GuiceControllerFactory controllerFactory;
@Inject
public ViewLoader(GuiceControllerFactory controllerFactory) {
this.controllerFactory = controllerFactory;
}
public Item load(URL url) {
return load(url, true);
}
public Item load(URL url, boolean useCaching) {
Item item;
if (useCaching && cache.containsKey(url)) {
return cache.get(url);
}
FXMLLoader loader = new FXMLLoader(url, BSResources.getResourceBundle(), builderFactory, controllerFactory);
try {
item = new Item(loader.load(), loader.getController());
cache.put(url, item);
return item;
} catch (IOException e) {
throw new BitsquareException(e, "Failed to load view at %s", url);
}
}
public static class Item {
public final Node view;
public final Initializable controller;
Item(Node view, Initializable controller) {
this.view = view;
this.controller = controller;
}
}
}

View file

@ -32,11 +32,7 @@ import javafx.scene.effect.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.paint.*; import javafx.scene.paint.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BalanceTextField extends AnchorPane { public class BalanceTextField extends AnchorPane {
private static final Logger log = LoggerFactory.getLogger(BalanceTextField.class);
private final TextField textField; private final TextField textField;
private final Tooltip progressIndicatorTooltip; private final Tooltip progressIndicatorTooltip;

View file

@ -39,9 +39,6 @@ import javafx.scene.text.*;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Convenience Component for info icon, info text and link display in a GridPane. * Convenience Component for info icon, info text and link display in a GridPane.
* Only the properties needed are supported. * Only the properties needed are supported.
@ -49,7 +46,6 @@ import org.slf4j.LoggerFactory;
* but add the children nodes to the gridPane. * but add the children nodes to the gridPane.
*/ */
public class InfoDisplay extends Parent { public class InfoDisplay extends Parent {
private static final Logger log = LoggerFactory.getLogger(InfoDisplay.class);
private final StringProperty text = new SimpleStringProperty(); private final StringProperty text = new SimpleStringProperty();
private final IntegerProperty rowIndex = new SimpleIntegerProperty(0); private final IntegerProperty rowIndex = new SimpleIntegerProperty(0);

View file

@ -31,9 +31,6 @@ import javafx.stage.Window;
import org.controlsfx.control.PopOver; import org.controlsfx.control.PopOver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* TextField with validation support. * TextField with validation support.
* If validator is set it supports on focus out validation with that validator. If a more sophisticated validation is * If validator is set it supports on focus out validation with that validator. If a more sophisticated validation is
@ -48,7 +45,6 @@ import org.slf4j.LoggerFactory;
//TODO There are some rare situation where it behaves buggy. Needs further investigation and improvements. Also //TODO There are some rare situation where it behaves buggy. Needs further investigation and improvements. Also
// consider replacement with controlsFX components. // consider replacement with controlsFX components.
public class InputTextField extends TextField { public class InputTextField extends TextField {
private static final Logger log = LoggerFactory.getLogger(InputTextField.class);
private final Effect invalidEffect = new DropShadow(BlurType.THREE_PASS_BOX, Color.RED, 4, 0.0, 0, 0); private final Effect invalidEffect = new DropShadow(BlurType.THREE_PASS_BOX, Color.RED, 4, 0.0, 0, 0);

View file

@ -19,9 +19,6 @@ package io.bitsquare.gui.components;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.hansolo.enzo.notification.Notification; import eu.hansolo.enzo.notification.Notification;
import eu.hansolo.enzo.notification.NotificationBuilder; import eu.hansolo.enzo.notification.NotificationBuilder;
import eu.hansolo.enzo.notification.NotifierBuilder; import eu.hansolo.enzo.notification.NotifierBuilder;
@ -30,7 +27,6 @@ import eu.hansolo.enzo.notification.NotifierBuilder;
* Not sure if we stick with the eu.hansolo.enzo.notification.Notification implementation, so keep it behind a service * Not sure if we stick with the eu.hansolo.enzo.notification.Notification implementation, so keep it behind a service
*/ */
public class SystemNotification { public class SystemNotification {
private static final Logger log = LoggerFactory.getLogger(SystemNotification.class);
private static final Notification.Notifier notifier = NotifierBuilder.create().build(); private static final Notification.Notifier notifier = NotifierBuilder.create().build();
public static void openInfoNotification(String title, String message) { public static void openInfoNotification(String title, String message) {

View file

@ -27,11 +27,7 @@ import javafx.scene.layout.*;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextFieldWithCopyIcon extends AnchorPane { public class TextFieldWithCopyIcon extends AnchorPane {
private static final Logger log = LoggerFactory.getLogger(TextFieldWithCopyIcon.class);
private final StringProperty text = new SimpleStringProperty(); private final StringProperty text = new SimpleStringProperty();

View file

@ -23,11 +23,7 @@ import javafx.geometry.Insets;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TitledGroupBg extends Pane { public class TitledGroupBg extends Pane {
private static final Logger log = LoggerFactory.getLogger(TitledGroupBg.class);
private final Label label; private final Label label;
private final StringProperty text = new SimpleStringProperty(); private final StringProperty text = new SimpleStringProperty();

View file

@ -23,11 +23,7 @@ import javafx.geometry.Insets;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TitledSeparator extends Pane { public class TitledSeparator extends Pane {
private static final Logger log = LoggerFactory.getLogger(TitledSeparator.class);
private final Label label; private final Label label;
private final StringProperty text = new SimpleStringProperty(); private final StringProperty text = new SimpleStringProperty();

View file

@ -35,11 +35,7 @@ import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.behavior.KeyBinding; import com.sun.javafx.scene.control.behavior.KeyBinding;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase; import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>> { class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>> {
private static final Logger log = LoggerFactory.getLogger(ProcessStepBarSkin.class);
private final ProcessStepBar<T> controller; private final ProcessStepBar<T> controller;
private LabelWithBorder currentLabelWithBorder; private LabelWithBorder currentLabelWithBorder;

View file

@ -17,7 +17,7 @@
--> -->
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<StackPane fx:id="root" fx:controller="io.bitsquare.gui.main.MainViewCB" <StackPane fx:id="root" fx:controller="io.bitsquare.gui.main.MainView"
prefHeight="750" prefWidth="1000" stylesheets="/io/bitsquare/gui/bitsquare.css" prefHeight="750" prefWidth="1000" stylesheets="/io/bitsquare/gui/bitsquare.css"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
</StackPane> </StackPane>

View file

@ -19,18 +19,28 @@ package io.bitsquare.gui.main;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.gui.FxmlController;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.components.SystemNotification; import io.bitsquare.gui.components.SystemNotification;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.funds.FundsView;
import io.bitsquare.gui.main.home.HomeView;
import io.bitsquare.gui.main.msg.MsgView;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.settings.SettingsView;
import io.bitsquare.gui.main.trade.BuyView;
import io.bitsquare.gui.main.trade.SellView;
import io.bitsquare.gui.util.Transitions; import io.bitsquare.gui.util.Transitions;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableView;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -42,10 +52,12 @@ import javafx.scene.layout.*;
import javafx.scene.paint.*; import javafx.scene.paint.*;
import javafx.scene.text.*; import javafx.scene.text.*;
import static io.bitsquare.gui.Navigation.Item.*;
import static javafx.scene.layout.AnchorPane.*; import static javafx.scene.layout.AnchorPane.*;
public class MainViewCB extends FxmlController<Pane, MainModel> { @FxmlView
public class MainView extends ActivatableView<StackPane, MainViewModel> {
public static final String TITLE_KEY = "view.title";
private final ToggleGroup navButtons = new ToggleGroup(); private final ToggleGroup navButtons = new ToggleGroup();
@ -56,8 +68,8 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
private final String title; private final String title;
@Inject @Inject
public MainViewCB(MainModel model, ViewLoader viewLoader, Navigation navigation, OverlayManager overlayManager, public MainView(MainViewModel model, ViewLoader viewLoader, Navigation navigation, OverlayManager overlayManager,
Transitions transitions, @Named(TITLE_KEY) String title) { Transitions transitions, @Named(MainView.TITLE_KEY) String title) {
super(model); super(model);
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation; this.navigation = navigation;
@ -74,19 +86,19 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
} }
@Override @Override
public void doInitialize() { protected void activate() {
ToggleButton homeButton = new NavButton(HOME) {{ ToggleButton homeButton = new NavButton(HomeView.class, "Overview") {{
setDisable(true); // during irc demo setDisable(true); // during irc demo
}}; }};
ToggleButton buyButton = new NavButton(BUY); ToggleButton buyButton = new NavButton(BuyView.class, "Buy BTC");
ToggleButton sellButton = new NavButton(SELL); ToggleButton sellButton = new NavButton(SellView.class, "Sell BTC");
ToggleButton portfolioButton = new NavButton(PORTFOLIO); ToggleButton portfolioButton = new NavButton(PortfolioView.class, "Portfolio");
ToggleButton fundsButton = new NavButton(FUNDS); ToggleButton fundsButton = new NavButton(FundsView.class, "Funds");
ToggleButton msgButton = new NavButton(MSG) {{ ToggleButton msgButton = new NavButton(MsgView.class, "Messages") {{
setDisable(true); // during irc demo setDisable(true); // during irc demo
}}; }};
ToggleButton settingsButton = new NavButton(SETTINGS); ToggleButton settingsButton = new NavButton(SettingsView.class, "Settings");
ToggleButton accountButton = new NavButton(ACCOUNT); ToggleButton accountButton = new NavButton(AccountView.class, "Account");
Pane portfolioButtonHolder = new Pane(portfolioButton); Pane portfolioButtonHolder = new Pane(portfolioButton);
Pane bankAccountComboBoxHolder = new Pane(); Pane bankAccountComboBoxHolder = new Pane();
@ -119,21 +131,19 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
setId("base-content-container"); setId("base-content-container");
}}; }};
navigation.addListener(navItems -> { navigation.addListener(viewPath -> {
if (navItems == null || navItems.length != 2 || navItems[0] != Navigation.Item.MAIN) if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0)
return; return;
ViewLoader.Item loaded = viewLoader.load(navItems[1].getFxmlUrl()); Class<? extends View> viewClass = viewPath.tip();
contentContainer.getChildren().setAll(loaded.view); View view = viewLoader.load(viewClass);
if (loaded.controller instanceof ViewCB) contentContainer.getChildren().setAll(view.getRoot());
((ViewCB) loaded.controller).setParent(this);
navButtons.getToggles().stream() navButtons.getToggles().stream()
.filter(toggle -> toggle instanceof ToggleButton) .filter(toggle -> toggle instanceof NavButton)
.filter(button -> navItems[1].getDisplayName().equals(((ToggleButton) button).getText())) .filter(button -> viewClass == ((NavButton) button).viewClass)
.findFirst() .findFirst()
.orElseThrow(() -> .orElseThrow(() -> new BitsquareException("No button matching %s found", viewClass))
new BitsquareException("No button matching %s found", navItems[1].getDisplayName()))
.setSelected(true); .setSelected(true);
}); });
@ -154,7 +164,7 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
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);
} }
@ -332,11 +342,15 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
private class NavButton extends ToggleButton { private class NavButton extends ToggleButton {
public NavButton(Navigation.Item item) { private final Class<? extends View> viewClass;
super(item.getDisplayName(), new ImageView() {{
setId("image-nav-" + item.getId()); public NavButton(Class<? extends View> viewClass, String title) {
super(title, new ImageView() {{
setId("image-nav-" + viewId(viewClass));
}}); }});
this.viewClass = viewClass;
this.setToggleGroup(navButtons); this.setToggleGroup(navButtons);
this.setId("nav-button"); this.setId("nav-button");
this.setPadding(new Insets(0, -10, -10, -10)); this.setPadding(new Insets(0, -10, -10, -10));
@ -351,14 +365,24 @@ public class MainViewCB extends FxmlController<Pane, MainModel> {
this.setMaxSize(50, 50); this.setMaxSize(50, 50);
this.setGraphicTextGap(newValue ? -1 : 0); this.setGraphicTextGap(newValue ? -1 : 0);
if (newValue) { if (newValue) {
this.getGraphic().setId("image-nav-" + item.getId() + "-active"); this.getGraphic().setId("image-nav-" + viewId(viewClass) + "-active");
} }
else { else {
this.getGraphic().setId("image-nav-" + item.getId()); this.getGraphic().setId("image-nav-" + viewId(viewClass));
} }
}); });
this.setOnAction(e -> navigation.navigationTo(Navigation.Item.MAIN, item)); this.setOnAction(e -> navigation.navigateTo(MainView.class, viewClass));
} }
}
private static String viewId(Class<? extends View> viewClass) {
String viewName = viewClass.getSimpleName();
String suffix = "View";
int suffixIdx = viewName.indexOf(suffix);
if (suffixIdx != viewName.length() - suffix.length())
throw new IllegalArgumentException("Cannot get ID for " + viewClass + ": class must end in " + suffix);
return viewName.substring(0, suffixIdx).toLowerCase();
} }
} }

View file

@ -20,7 +20,6 @@ package io.bitsquare.gui.main;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.btc.BitcoinNetwork; import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.Model;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.msg.MessageService; import io.bitsquare.msg.MessageService;
import io.bitsquare.network.BootstrapState; import io.bitsquare.network.BootstrapState;
@ -31,6 +30,8 @@ import io.bitsquare.user.User;
import com.google.inject.Inject; import com.google.inject.Inject;
import viewfx.model.ViewModel;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoubleProperty;
@ -51,8 +52,8 @@ import org.slf4j.LoggerFactory;
import rx.Observable; import rx.Observable;
class MainModel implements Model { class MainViewModel implements ViewModel {
private static final Logger log = LoggerFactory.getLogger(MainModel.class); private static final Logger log = LoggerFactory.getLogger(MainViewModel.class);
final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(-1); final DoubleProperty networkSyncProgress = new SimpleDoubleProperty(-1);
final IntegerProperty numPendingTrades = new SimpleIntegerProperty(0); final IntegerProperty numPendingTrades = new SimpleIntegerProperty(0);
@ -83,8 +84,9 @@ class MainModel implements Model {
@Inject @Inject
public MainModel(User user, WalletService walletService, MessageService messageService, TradeManager tradeManager, public MainViewModel(User user, WalletService walletService, MessageService messageService,
BitcoinNetwork bitcoinNetwork, BSFormatter formatter, Persistence persistence) { TradeManager tradeManager, BitcoinNetwork bitcoinNetwork, BSFormatter formatter,
Persistence persistence) {
this.user = user; this.user = user;
this.walletService = walletService; this.walletService = walletService;
this.messageService = messageService; this.messageService = messageService;
@ -93,10 +95,7 @@ class MainModel implements Model {
this.bitcoinNetwork = bitcoinNetwork; this.bitcoinNetwork = bitcoinNetwork;
user.getCurrentBankAccount().addListener((observable, oldValue, newValue) -> persistence.write(user)); user.getCurrentBankAccount().addListener((observable, oldValue, newValue) -> persistence.write(user));
}
@Override
public void initialize() {
bootstrapState.addListener((ov, oldValue, newValue) -> { bootstrapState.addListener((ov, oldValue, newValue) -> {
if (newValue == BootstrapState.DISCOVERY_DIRECT_SUCCEEDED || if (newValue == BootstrapState.DISCOVERY_DIRECT_SUCCEEDED ||
newValue == BootstrapState.DISCOVERY_AUTO_PORT_FORWARDING_SUCCEEDED || newValue == BootstrapState.DISCOVERY_AUTO_PORT_FORWARDING_SUCCEEDED ||
@ -151,6 +150,7 @@ class MainModel implements Model {
bankAccountsComboBoxPrompt.set(user.getBankAccounts().isEmpty() ? "No accounts" : ""); bankAccountsComboBoxPrompt.set(user.getBankAccounts().isEmpty() ? "No accounts" : "");
} }
public Observable<?> initBackend() { public Observable<?> initBackend() {
walletService.getDownloadProgress().subscribe( walletService.getDownloadProgress().subscribe(

View file

@ -1,83 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.UIModel;
import io.bitsquare.user.User;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class AccountModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(AccountModel.class);
private final User user;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountModel(User user) {
this.user = user;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
boolean getNeedRegistration() {
return user.getAccountId() == null;
}
}

View file

@ -1,78 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.PresentationModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class AccountPM extends PresentationModel<AccountModel> {
private static final Logger log = LoggerFactory.getLogger(AccountPM.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountPM(AccountModel model) {
super(model);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
boolean getNeedRegistration() {
return model.getNeedRegistration();
}
}

View file

@ -19,7 +19,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.AccountViewCB" <TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.AccountView"
prefHeight="630.0" prefWidth="1000.0" prefHeight="630.0" prefWidth="1000.0"
AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"

View file

@ -0,0 +1,123 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.arbitrator.ArbitratorSettingsView;
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
import io.bitsquare.gui.main.account.setup.AccountSetupWizard;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.ViewPath;
import viewfx.view.support.ActivatableView;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.*;
@FxmlView
public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
@FXML Tab accountSettingsTab, arbitratorSettingsTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
private final ViewLoader viewLoader;
private final Navigation navigation;
@Inject
private AccountView(AccountViewModel model, ViewLoader viewLoader, Navigation navigation) {
super(model);
this.viewLoader = viewLoader;
this.navigation = navigation;
}
@Override
public void initialize() {
navigationListener = viewPath -> {
if (viewPath.size() == 3 && viewPath.indexOf(AccountView.class) == 1)
loadView(viewPath.tip());
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == accountSettingsTab)
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class);
else
navigation.navigateTo(MainView.class, AccountView.class, ArbitratorSettingsView.class);
};
}
@Override
public void activate() {
navigation.addListener(navigationListener);
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
if (navigation.getCurrentPath().size() == 2 &&
navigation.getCurrentPath().get(1) == AccountView.class) {
if (model.getNeedRegistration()) {
navigation.navigateTo(MainView.class, AccountView.class, AccountSetupWizard.class);
}
else {
if (root.getSelectionModel().getSelectedItem() == accountSettingsTab)
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class);
else
navigation.navigateTo(MainView.class, AccountView.class, ArbitratorSettingsView.class);
}
}
}
@Override
public void deactivate() {
navigation.removeListener(navigationListener);
root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
}
private void loadView(Class<? extends View> viewClass) {
Tab tab;
View view = viewLoader.load(viewClass);
if (view instanceof AccountSettingsView) {
tab = accountSettingsTab;
tab.setText("Account settings");
arbitratorSettingsTab.setDisable(false);
}
else if (view instanceof AccountSetupWizard) {
tab = accountSettingsTab;
tab.setText("Account setup");
arbitratorSettingsTab.setDisable(true);
}
else if (view instanceof ArbitratorSettingsView) {
tab = arbitratorSettingsTab;
}
else {
throw new IllegalArgumentException("View not supported: " + view);
}
// for IRC demo we deactivate the arbitratorSettingsTab
arbitratorSettingsTab.setDisable(true);
tab.setContent(view.getRoot());
root.getSelectionModel().select(tab);
}
}

View file

@ -1,175 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AccountViewCB extends CachedViewCB<AccountPM> {
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
@FXML Tab accountSettingsTab, arbitratorSettingsTab;
private final ViewLoader viewLoader;
private final Navigation navigation;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountViewCB(AccountPM presentationModel, ViewLoader viewLoader, Navigation navigation) {
super(presentationModel);
this.viewLoader = viewLoader;
this.navigation = navigation;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
navigationListener = navigationItems -> {
if (navigationItems != null &&
navigationItems.length == 3 &&
navigationItems[1] == Navigation.Item.ACCOUNT)
loadView(navigationItems[2]);
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == accountSettingsTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETTINGS);
else
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ARBITRATOR_SETTINGS);
};
super.initialize(url, rb);
}
@Override
public void activate() {
super.activate();
navigation.addListener(navigationListener);
((TabPane) root).getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
if (navigation.getCurrentItems().length == 2 &&
navigation.getCurrentItems()[1] == Navigation.Item.ACCOUNT) {
if (presentationModel.getNeedRegistration()) {
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETUP);
}
else {
if (((TabPane) root).getSelectionModel().getSelectedItem() == accountSettingsTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETTINGS);
else
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ARBITRATOR_SETTINGS);
}
}
}
@Override
public void deactivate() {
super.deactivate();
navigation.removeListener(navigationListener);
((TabPane) root).getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
super.loadView(navigationItem);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
final Tab tab;
switch (navigationItem) {
case ACCOUNT_SETTINGS:
tab = accountSettingsTab;
tab.setText("Account settings");
arbitratorSettingsTab.setDisable(false);
break;
case ACCOUNT_SETUP:
tab = accountSettingsTab;
tab.setText("Account setup");
arbitratorSettingsTab.setDisable(true);
break;
case ARBITRATOR_SETTINGS:
tab = arbitratorSettingsTab;
break;
default:
throw new IllegalArgumentException("navigation item of type " + navigationItem + " is not allowed");
}
// for IRC demo we deactivate the arbitratorSettingsTab
arbitratorSettingsTab.setDisable(true);
tab.setContent(loaded.view);
((TabPane) root).getSelectionModel().select(tab);
Initializable childController = loaded.controller;
((ViewCB) childController).setParent(this);
return childController;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
}

View file

@ -0,0 +1,38 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.user.User;
import com.google.inject.Inject;
import viewfx.model.ViewModel;
class AccountViewModel implements ViewModel {
private final User user;
@Inject
public AccountViewModel(User user) {
this.user = user;
}
boolean getNeedRegistration() {
return user.getAccountId() == null;
}
}

View file

@ -21,7 +21,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.ArbitratorSettingsViewCB" <AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.ArbitratorSettingsView"
prefHeight="660.0" prefWidth="1000.0" prefHeight="660.0" prefWidth="1000.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
<VBox spacing="20"> <VBox spacing="20">

View file

@ -0,0 +1,76 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.arbitrator;
import io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationView;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.AbstractView;
import viewfx.view.support.CachingViewLoader;
import javafx.fxml.FXML;
import javafx.scene.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
@FxmlView
public class ArbitratorSettingsView extends AbstractView {
private final ViewLoader viewLoader;
private final Stage primaryStage;
@Inject
private ArbitratorSettingsView(CachingViewLoader viewLoader, Stage primaryStage) {
this.viewLoader = viewLoader;
this.primaryStage = primaryStage;
}
@FXML
public void onArbitratorRegistration() {
View view = viewLoader.load(ArbitratorRegistrationView.class);
showStage(view);
}
@FXML
public void onArbitratorEdit() {
View view = viewLoader.load(ArbitratorRegistrationView.class);
showStage(view);
((ArbitratorRegistrationView) view).setEditMode(true);
}
private void showStage(View view) {
Stage stage = new Stage();
stage.setTitle("Arbitrator");
stage.setMinWidth(800);
stage.setMinHeight(400);
stage.setWidth(800);
stage.setHeight(600);
stage.setX(primaryStage.getX() + 50);
stage.setY(primaryStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage);
Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
stage.setScene(scene);
stage.show();
}
}

View file

@ -1,131 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.arbitrator;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationViewCB;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
// TODO Arbitration is very basic yet
public class ArbitratorSettingsViewCB extends CachedViewCB {
private final ViewLoader viewLoader;
private final Navigation navigation;
private final Stage primaryStage;
private ArbitratorRegistrationViewCB arbitratorRegistrationViewCB;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ArbitratorSettingsViewCB(ViewLoader viewLoader, Navigation navigation, Stage primaryStage) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
this.primaryStage = primaryStage;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false);
arbitratorRegistrationViewCB = (ArbitratorRegistrationViewCB) loaded.controller;
final Stage stage = new Stage();
stage.setTitle("Arbitrator");
stage.setMinWidth(800);
stage.setMinHeight(400);
stage.setWidth(800);
stage.setHeight(600);
stage.setX(primaryStage.getX() + 50);
stage.setY(primaryStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage);
Scene scene = new Scene((Parent) loaded.view, 800, 600);
stage.setScene(scene);
stage.show();
return arbitratorRegistrationViewCB;
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onArbitratorRegistration() {
loadView(Navigation.Item.ARBITRATOR_REGISTRATION);
}
@FXML
public void onArbitratorEdit() {
loadView(Navigation.Item.ARBITRATOR_REGISTRATION);
arbitratorRegistrationViewCB.setEditMode(true);
}
}

View file

@ -18,7 +18,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserViewCB" <AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserView"
prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0" prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -0,0 +1,139 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.arbitrator.browser;
import io.bitsquare.account.AccountSettings;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.msg.MessageService;
import io.bitsquare.msg.listeners.ArbitratorListener;
import io.bitsquare.persistence.Persistence;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableView;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
@FxmlView
public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements ArbitratorListener {
@FXML Button prevButton, nextButton, selectButton, closeButton;
@FXML Pane arbitratorProfile;
private Arbitrator currentArbitrator;
private ArbitratorProfileView arbitratorProfileView;
private int index = -1;
private final List<Arbitrator> allArbitrators = new ArrayList<>();
private final ViewLoader viewLoader;
private final AccountSettings accountSettings;
private final Persistence persistence;
private final MessageService messageService;
@Inject
public ArbitratorBrowserView(ViewLoader viewLoader, AccountSettings accountSettings, Persistence persistence,
MessageService messageService) {
this.viewLoader = viewLoader;
this.accountSettings = accountSettings;
this.persistence = persistence;
this.messageService = messageService;
}
@Override
public void initialize() {
messageService.addArbitratorListener(this);
messageService.getArbitrators(LanguageUtil.getDefaultLanguageLocale());
View view = viewLoader.load(ArbitratorProfileView.class);
root.getChildren().set(0, view.getRoot());
arbitratorProfileView = (ArbitratorProfileView) view;
checkButtonState();
}
@Override
public void onArbitratorAdded(Arbitrator arbitrator) {
}
@Override
public void onArbitratorsReceived(List<Arbitrator> arbitrators) {
allArbitrators.clear();
allArbitrators.addAll(arbitrators);
if (!allArbitrators.isEmpty()) {
index = 0;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileView.applyArbitrator(currentArbitrator);
checkButtonState();
}
}
@Override
public void onArbitratorRemoved(Arbitrator arbitrator) {
}
@FXML
public void onPrevious() {
if (index > 0) {
index--;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileView.applyArbitrator(currentArbitrator);
}
checkButtonState();
}
@FXML
public void onNext() {
if (index < allArbitrators.size() - 1) {
index++;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileView.applyArbitrator(currentArbitrator);
}
checkButtonState();
}
@FXML
public void onSelect() {
accountSettings.addAcceptedArbitrator(currentArbitrator);
persistence.write(accountSettings);
}
@FXML
public void onClose() {
Stage stage = (Stage) root.getScene().getWindow();
stage.close();
}
private void checkButtonState() {
prevButton.setDisable(index < 1);
nextButton.setDisable(index == allArbitrators.size() - 1 || index == -1);
}
}

View file

@ -1,222 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.arbitrator.browser;
import io.bitsquare.account.AccountSettings;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileViewCB;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.msg.MessageService;
import io.bitsquare.msg.listeners.ArbitratorListener;
import io.bitsquare.persistence.Persistence;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
// TODO Arbitration is very basic yet
public class ArbitratorBrowserViewCB extends CachedViewCB implements ArbitratorListener {
private final ViewLoader viewLoader;
private final AccountSettings accountSettings;
private final Persistence persistence;
private final MessageService messageService;
private final List<Arbitrator> allArbitrators = new ArrayList<>();
private Arbitrator currentArbitrator;
private ArbitratorProfileViewCB arbitratorProfileViewCB;
private int index = -1;
@FXML Button prevButton, nextButton, selectButton, closeButton;
@FXML Pane arbitratorProfile;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorBrowserViewCB(ViewLoader viewLoader, AccountSettings accountSettings, Persistence persistence,
MessageService messageService) {
this.viewLoader = viewLoader;
this.accountSettings = accountSettings;
this.persistence = persistence;
this.messageService = messageService;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
messageService.addArbitratorListener(this);
messageService.getArbitrators(LanguageUtil.getDefaultLanguageLocale());
loadView(Navigation.Item.ARBITRATOR_PROFILE);
checkButtonState();
super.initialize(url, rb);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
/* public Initializable loadViewAndGetChildController(Navigation.Item item) {
final ViewLoader loader = new ViewLoader(getClass().getResource(item.getFxmlUrl()));
try {
final Node view = loader.load();
arbitratorProfileViewCB = loader.getController();
arbitratorProfileViewCB.setParentController(this);
((Pane) root).getChildren().set(0, view);
return arbitratorProfileViewCB;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}*/
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
super.loadView(navigationItem);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
((Pane) root).getChildren().set(0, loaded.view);
Initializable childController = arbitratorProfileViewCB = (ArbitratorProfileViewCB) loaded.controller;
((ViewCB) childController).setParent(this);
return childController;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: ArbitratorListener
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onArbitratorAdded(Arbitrator arbitrator) {
}
@Override
public void onArbitratorsReceived(List<Arbitrator> arbitrators) {
allArbitrators.clear();
allArbitrators.addAll(arbitrators);
if (!allArbitrators.isEmpty()) {
index = 0;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileViewCB.applyArbitrator(currentArbitrator);
checkButtonState();
}
}
@Override
public void onArbitratorRemoved(Arbitrator arbitrator) {
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onPrevious() {
if (index > 0) {
index--;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileViewCB.applyArbitrator(currentArbitrator);
}
checkButtonState();
}
@FXML
public void onNext() {
if (index < allArbitrators.size() - 1) {
index++;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileViewCB.applyArbitrator(currentArbitrator);
}
checkButtonState();
}
@FXML
public void onSelect() {
accountSettings.addAcceptedArbitrator(currentArbitrator);
persistence.write(accountSettings);
}
@FXML
public void onClose() {
Stage stage = (Stage) root.getScene().getWindow();
stage.close();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void checkButtonState() {
prevButton.setDisable(index < 1);
nextButton.setDisable(index == allArbitrators.size() - 1 || index == -1);
}
}

View file

@ -19,7 +19,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileViewCB" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView"
hgap="5.0" vgap="5.0" AnchorPane.bottomAnchor="80.0" AnchorPane.leftAnchor="10.0" hgap="5.0" vgap="5.0" AnchorPane.bottomAnchor="80.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -18,86 +18,31 @@
package io.bitsquare.gui.main.account.arbitrator.profile; package io.bitsquare.gui.main.account.arbitrator.profile;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.settings.Preferences;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
// TODO Arbitration is very basic yet @FxmlView
public class ArbitratorProfileViewCB extends CachedViewCB { public class ArbitratorProfileView extends AbstractView {
private final Preferences preferences;
private final Persistence persistence;
private final BSFormatter formatter;
@FXML Label nameLabel; @FXML Label nameLabel;
@FXML TextField nameTextField, languagesTextField, reputationTextField,
feeTextField, methodsTextField, passiveServiceFeeTextField,
idVerificationsTextField, webPageTextField, maxTradeVolumeTextField;
@FXML TextArea descriptionTextArea; @FXML TextArea descriptionTextArea;
@FXML TextField nameTextField, languagesTextField, reputationTextField, feeTextField, methodsTextField,
passiveServiceFeeTextField, idVerificationsTextField, webPageTextField, maxTradeVolumeTextField;
private final BSFormatter formatter;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public ArbitratorProfileViewCB(Preferences preferences, Persistence persistence, public ArbitratorProfileView(BSFormatter formatter) {
BSFormatter formatter) {
this.preferences = preferences;
this.persistence = persistence;
// ApplicationPreferences persistedApplicationPreferences = (ApplicationPreferences) storage
// .read(settings.getClass().getName());
// settings.applyPersistedSettings(persistedApplicationPreferences);
this.formatter = formatter; this.formatter = formatter;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void applyArbitrator(Arbitrator arbitrator) { public void applyArbitrator(Arbitrator arbitrator) {
if (arbitrator != null && arbitrator.getIdType() != null) { if (arbitrator != null && arbitrator.getIdType() != null) {
String name = ""; String name = "";
@ -125,6 +70,5 @@ public class ArbitratorProfileViewCB extends CachedViewCB {
descriptionTextArea.setText(arbitrator.getDescription()); descriptionTextArea.setText(arbitrator.getDescription());
} }
} }
} }

View file

@ -21,7 +21,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" <AnchorPane fx:id="root"
fx:controller="io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationViewCB" fx:controller="io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationView"
prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0" prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -20,7 +20,6 @@ package io.bitsquare.gui.main.account.arbitrator.registration;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.arbitrator.Reputation; import io.bitsquare.arbitrator.Reputation;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator; import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -38,70 +37,61 @@ import org.bitcoinj.core.Wallet;
import org.bitcoinj.core.WalletEventListener; import org.bitcoinj.core.WalletEventListener;
import org.bitcoinj.script.Script; import org.bitcoinj.script.Script;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableView;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
import org.slf4j.Logger; @FxmlView
import org.slf4j.LoggerFactory; public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void> {
// TODO Arbitration is very basic yet @FXML Accordion accordion;
public class ArbitratorRegistrationViewCB extends CachedViewCB { @FXML TextArea descriptionTextArea;
private static final Logger log = LoggerFactory.getLogger(ArbitratorRegistrationViewCB.class); @FXML Button saveProfileButton, paymentDoneButton;
@FXML Label nameLabel, infoLabel, copyIcon, confirmationLabel;
@FXML ComboBox<Locale> languageComboBox;
@FXML ComboBox<Arbitrator.ID_TYPE> idTypeComboBox;
@FXML ComboBox<Arbitrator.METHOD> methodsComboBox;
@FXML ConfidenceProgressIndicator progressIndicator;
@FXML ComboBox<Arbitrator.ID_VERIFICATION> idVerificationsComboBox;
@FXML TitledPane profileTitledPane, paySecurityDepositTitledPane;
@FXML TextField nameTextField, idTypeTextField, languagesTextField, maxTradeVolumeTextField,
passiveServiceFeeTextField, minPassiveServiceFeeTextField, arbitrationFeeTextField,
minArbitrationFeeTextField, methodsTextField, idVerificationsTextField, webPageTextField,
securityDepositAddressTextField, balanceTextField;
private boolean isEditMode;
private Arbitrator.ID_TYPE idType;
private List<Locale> languageList = new ArrayList<>();
private List<Arbitrator.METHOD> methodList = new ArrayList<>();
private List<Arbitrator.ID_VERIFICATION> idVerificationList = new ArrayList<>();
private Arbitrator arbitrator = new Arbitrator();
private final Persistence persistence; private final Persistence persistence;
private final WalletService walletService; private final WalletService walletService;
private final MessageService messageService; private final MessageService messageService;
private final User user; private final User user;
private final BSFormatter formatter; private final BSFormatter formatter;
private Arbitrator arbitrator = new Arbitrator();
private boolean isEditMode;
private List<Locale> languageList = new ArrayList<>();
private List<Arbitrator.METHOD> methodList = new ArrayList<>();
private List<Arbitrator.ID_VERIFICATION> idVerificationList = new ArrayList<>();
private Arbitrator.ID_TYPE idType;
@FXML Accordion accordion;
@FXML TitledPane profileTitledPane, paySecurityDepositTitledPane;
@FXML Button saveProfileButton, paymentDoneButton;
@FXML Label nameLabel, infoLabel, copyIcon, confirmationLabel;
@FXML ComboBox<Locale> languageComboBox;
@FXML ComboBox<Arbitrator.ID_TYPE> idTypeComboBox;
@FXML ComboBox<Arbitrator.METHOD> methodsComboBox;
@FXML ComboBox<Arbitrator.ID_VERIFICATION> idVerificationsComboBox;
@FXML TextField nameTextField, idTypeTextField, languagesTextField, maxTradeVolumeTextField,
passiveServiceFeeTextField, minPassiveServiceFeeTextField, arbitrationFeeTextField,
minArbitrationFeeTextField, methodsTextField, idVerificationsTextField, webPageTextField,
securityDepositAddressTextField, balanceTextField;
@FXML TextArea descriptionTextArea;
@FXML ConfidenceProgressIndicator progressIndicator;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private ArbitratorRegistrationViewCB(Persistence persistence, WalletService walletService, private ArbitratorRegistrationView(Persistence persistence, WalletService walletService,
MessageService messageService, User user, BSFormatter formatter) { MessageService messageService, User user, BSFormatter formatter) {
this.persistence = persistence; this.persistence = persistence;
this.walletService = walletService; this.walletService = walletService;
this.messageService = messageService; this.messageService = messageService;
@ -109,15 +99,8 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
this.formatter = formatter; this.formatter = formatter;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
super.initialize(url, rb);
accordion.setExpandedPane(profileTitledPane); accordion.setExpandedPane(profileTitledPane);
Arbitrator persistedArbitrator = (Arbitrator) persistence.read(arbitrator); Arbitrator persistedArbitrator = (Arbitrator) persistence.read(arbitrator);
@ -137,7 +120,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
return locale.getDisplayLanguage(); return locale.getDisplayLanguage();
} }
@Override @Override
public Locale fromString(String s) { public Locale fromString(String s) {
return null; return null;
@ -147,13 +129,11 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
idTypeComboBox.setItems(FXCollections.observableArrayList( idTypeComboBox.setItems(FXCollections.observableArrayList(
new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class)))); new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class))));
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() { idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() {
@Override @Override
public String toString(Arbitrator.ID_TYPE item) { public String toString(Arbitrator.ID_TYPE item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.ID_TYPE fromString(String s) { public Arbitrator.ID_TYPE fromString(String s) {
return null; return null;
@ -163,13 +143,11 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD
.class)))); .class))));
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() { methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() {
@Override @Override
public String toString(Arbitrator.METHOD item) { public String toString(Arbitrator.METHOD item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.METHOD fromString(String s) { public Arbitrator.METHOD fromString(String s) {
return null; return null;
@ -179,13 +157,11 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
idVerificationsComboBox.setItems( idVerificationsComboBox.setItems(
FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class)))); FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class))));
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() { idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() {
@Override @Override
public String toString(Arbitrator.ID_VERIFICATION item) { public String toString(Arbitrator.ID_VERIFICATION item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.ID_VERIFICATION fromString(String s) { public Arbitrator.ID_VERIFICATION fromString(String s) {
return null; return null;
@ -193,28 +169,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
}); });
} }
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setEditMode(boolean isEditMode) { public void setEditMode(boolean isEditMode) {
this.isEditMode = isEditMode; this.isEditMode = isEditMode;
@ -225,11 +179,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML @FXML
public void onSelectIDType() { public void onSelectIDType() {
idType = idTypeComboBox.getSelectionModel().getSelectedItem(); idType = idTypeComboBox.getSelectionModel().getSelectedItem();
@ -286,7 +235,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
methodsTextField.setText(""); methodsTextField.setText("");
} }
@FXML @FXML
public void onAddIDVerification() { public void onAddIDVerification() {
Arbitrator.ID_VERIFICATION idVerification = idVerificationsComboBox.getSelectionModel().getSelectedItem(); Arbitrator.ID_VERIFICATION idVerification = idVerificationsComboBox.getSelectionModel().getSelectedItem();
@ -329,11 +277,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
public void onPaymentDone() { public void onPaymentDone() {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupPaySecurityDepositScreen() { private void setupPaySecurityDepositScreen() {
infoLabel.setText("You need to pay 2 x the max. trading volume as security deposit.\n\nThat payment will be " + infoLabel.setText("You need to pay 2 x the max. trading volume as security deposit.\n\nThat payment will be " +
"locked into a MultiSig fund and be refunded when you leave the arbitration pool.\nIn case of fraud " + "locked into a MultiSig fund and be refunded when you leave the arbitration pool.\nIn case of fraud " +
@ -426,7 +369,6 @@ public class ArbitratorRegistrationViewCB extends CachedViewCB {
} }
} }
private Arbitrator getEditedArbitrator() { private Arbitrator getEditedArbitrator() {
String pubKeyAsHex = walletService.getArbitratorDepositAddressEntry().getPubKeyAsHexString(); String pubKeyAsHex = walletService.getArbitratorDepositAddressEntry().getPubKeyAsHexString();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey()); String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey());

View file

@ -1,78 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class ChangePasswordModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(ChangePasswordModel.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ChangePasswordModel() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
}

View file

@ -22,7 +22,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.changepassword.ChangePasswordViewCB" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.changepassword.ChangePasswordView"
hgap="5.0" vgap="5.0" hgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -0,0 +1,83 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
@FxmlView
public class ChangePasswordView extends InitializableView<GridPane, ChangePasswordViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
private Wizard parent;
@Inject
private ChangePasswordView(ChangePasswordViewModel model) {
super(model);
}
@Override
public void initialize() {
passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(model.repeatedPasswordField);
saveButton.disableProperty().bind(model.saveButtonDisabled);
}
@Override
public void setParent(Wizard parent) {
this.parent = parent;
}
@Override
public void hideWizardNavigation() {
buttonsHBox.getChildren().remove(skipButton);
}
@FXML
private void onSaved() {
if (model.requestSavePassword())
parent.nextStep(this);
else
log.debug(model.getErrorMessage()); // TODO use validating TF
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_PASSWORD);
}
@FXML
private void onSkipped() {
parent.nextStep(this);
}
}

View file

@ -1,130 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(ChangePasswordViewCB.class);
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ChangePasswordViewCB(ChangePasswordPM presentationModel) {
super(presentationModel);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField);
saveButton.disableProperty().bind(presentationModel.saveButtonDisabled);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void useSettingsContext(boolean useSettingsContext) {
if (useSettingsContext)
buttonsHBox.getChildren().remove(skipButton);
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
private void onSaved() {
boolean result = presentationModel.requestSavePassword();
if (result) {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
else {
log.debug(presentationModel.getErrorMessage()); // TODO use validating TF
}
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_PASSWORD);
}
@FXML
private void onSkipped() {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
}

View file

@ -17,22 +17,19 @@
package io.bitsquare.gui.main.account.content.changepassword; package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator; import io.bitsquare.gui.util.validation.PasswordValidator;
import com.google.inject.Inject; import com.google.inject.Inject;
import viewfx.model.ViewModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import org.slf4j.Logger; class ChangePasswordViewModel implements ViewModel {
import org.slf4j.LoggerFactory;
class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
private static final Logger log = LoggerFactory.getLogger(ChangePasswordPM.class);
private final PasswordValidator passwordValidator; private final PasswordValidator passwordValidator;
@ -43,13 +40,8 @@ class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
final BooleanProperty saveButtonDisabled = new SimpleBooleanProperty(true); final BooleanProperty saveButtonDisabled = new SimpleBooleanProperty(true);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private ChangePasswordPM(ChangePasswordModel model, PasswordValidator passwordValidator) { public ChangePasswordViewModel(PasswordValidator passwordValidator) {
super(model);
this.passwordValidator = passwordValidator; this.passwordValidator = passwordValidator;
passwordField.addListener((ov) -> saveButtonDisabled.set(!validate())); passwordField.addListener((ov) -> saveButtonDisabled.set(!validate()));
@ -57,56 +49,23 @@ class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
boolean requestSavePassword() { boolean requestSavePassword() {
if (validate()) { if (validate()) {
model.savePassword(passwordField.get()); savePassword(passwordField.get());
return true; return true;
} }
return false; return false;
} }
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
String getErrorMessage() { String getErrorMessage() {
return errorMessage; return errorMessage;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private boolean validate() { private boolean validate() {
InputValidator.ValidationResult result = passwordValidator.validate(passwordField.get()); InputValidator.ValidationResult result = passwordValidator.validate(passwordField.get());
if (result.isValid) { if (result.isValid) {

View file

@ -20,7 +20,6 @@ package io.bitsquare.gui.main.account.content.fiat;
import io.bitsquare.account.AccountSettings; import io.bitsquare.account.AccountSettings;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.UIModel;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.CurrencyUtil;
@ -32,6 +31,9 @@ import com.google.inject.Inject;
import java.util.Currency; import java.util.Currency;
import viewfx.model.Activatable;
import viewfx.model.DataModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -41,11 +43,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import org.slf4j.Logger; class FiatAccountDataModel implements Activatable, DataModel {
import org.slf4j.LoggerFactory;
class FiatAccountModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(FiatAccountModel.class);
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
@ -70,51 +68,24 @@ class FiatAccountModel extends UIModel {
final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions()); final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
FiatAccountModel(User user, Persistence persistence, AccountSettings accountSettings) { public FiatAccountDataModel(User user, Persistence persistence, AccountSettings accountSettings) {
this.persistence = persistence; this.persistence = persistence;
this.user = user; this.user = user;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@Override @Override
public void activate() { public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts()); allBankAccounts.setAll(user.getBankAccounts());
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate(); // no-op
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
void saveBankAccount() { void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(), BankAccount bankAccount = new BankAccount(type.get(),
@ -168,19 +139,11 @@ class FiatAccountModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getAllCountriesFor(Region selectedRegion) { ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion)); return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setType(BankAccountType type) { void setType(BankAccountType type) {
this.type.set(type); this.type.set(type);
@ -203,10 +166,6 @@ class FiatAccountModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void reset() { private void reset() {
title.set(null); title.set(null);
holderName.set(null); holderName.set(null);

View file

@ -24,7 +24,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.fiat.FiatAccountViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.fiat.FiatAccountView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -19,12 +19,9 @@ package io.bitsquare.gui.main.account.content.fiat;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
@ -32,15 +29,16 @@ import io.bitsquare.locale.BSResources;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.Region; import io.bitsquare.locale.Region;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Currency; import java.util.Currency;
import java.util.List; import java.util.List;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.Wizard;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -51,14 +49,10 @@ import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static javafx.beans.binding.Bindings.createBooleanBinding; import static javafx.beans.binding.Bindings.createBooleanBinding;
public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements ContextAware { @FxmlView
public class FiatAccountView extends ActivatableViewAndModel<GridPane, FiatAccountViewModel> implements Wizard.Step {
private static final Logger log = LoggerFactory.getLogger(FiatAccountViewCB.class);
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML ComboBox<Region> regionComboBox; @FXML ComboBox<Region> regionComboBox;
@ -68,96 +62,66 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
@FXML ComboBox<BankAccount> selectionComboBox; @FXML ComboBox<BankAccount> selectionComboBox;
@FXML ComboBox<BankAccountType> typesComboBox; @FXML ComboBox<BankAccountType> typesComboBox;
@FXML ComboBox<Currency> currencyComboBox; @FXML ComboBox<Currency> currencyComboBox;
private Wizard parent;
private final OverlayManager overlayManager; private final OverlayManager overlayManager;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
FiatAccountViewCB(FiatAccountPm presentationModel, OverlayManager overlayManager) { public FiatAccountView(FiatAccountViewModel model, OverlayManager overlayManager) {
super(presentationModel); super(model);
this.overlayManager = overlayManager; this.overlayManager = overlayManager;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
typesComboBox.setItems(presentationModel.getAllTypes()); typesComboBox.setItems(model.getAllTypes());
typesComboBox.setConverter(presentationModel.getTypesConverter()); typesComboBox.setConverter(model.getTypesConverter());
selectionComboBox.setConverter(presentationModel.getSelectionConverter()); selectionComboBox.setConverter(model.getSelectionConverter());
currencyComboBox.setItems(presentationModel.getAllCurrencies()); currencyComboBox.setItems(model.getAllCurrencies());
currencyComboBox.setConverter(presentationModel.getCurrencyConverter()); currencyComboBox.setConverter(model.getCurrencyConverter());
regionComboBox.setItems(presentationModel.getAllRegions()); regionComboBox.setItems(model.getAllRegions());
regionComboBox.setConverter(presentationModel.getRegionConverter()); regionComboBox.setConverter(model.getRegionConverter());
countryComboBox.setConverter(presentationModel.getCountryConverter()); countryComboBox.setConverter(model.getCountryConverter());
nameOfBankTextField.setValidator(presentationModel.getBankAccountNumberValidator()); nameOfBankTextField.setValidator(model.getBankAccountNumberValidator());
holderNameTextField.setValidator(presentationModel.getBankAccountNumberValidator()); holderNameTextField.setValidator(model.getBankAccountNumberValidator());
primaryIDTextField.setValidator(presentationModel.getBankAccountNumberValidator()); primaryIDTextField.setValidator(model.getBankAccountNumberValidator());
secondaryIDTextField.setValidator(presentationModel.getBankAccountNumberValidator()); secondaryIDTextField.setValidator(model.getBankAccountNumberValidator());
super.initialize(url, rb);
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate();
setupListeners(); setupListeners();
setupBindings(); setupBindings();
selectionComboBox.setItems(presentationModel.getAllBankAccounts()); selectionComboBox.setItems(model.getAllBankAccounts());
} }
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void useSettingsContext(boolean useSettingsContext) { public void setParent(Wizard parent) {
if (useSettingsContext) this.parent = parent;
buttonsHBox.getChildren().remove(completedButton);
} }
@Override
/////////////////////////////////////////////////////////////////////////////////////////// public void hideWizardNavigation() {
// UI handlers buttonsHBox.getChildren().remove(completedButton);
/////////////////////////////////////////////////////////////////////////////////////////// }
@FXML @FXML
void onSelectAccount() { void onSelectAccount() {
if (selectionComboBox.getSelectionModel().getSelectedItem() != null) if (selectionComboBox.getSelectionModel().getSelectedItem() != null)
presentationModel.selectBankAccount(selectionComboBox.getSelectionModel().getSelectedItem()); model.selectBankAccount(selectionComboBox.getSelectionModel().getSelectedItem());
} }
@FXML @FXML
void onSelectType() { void onSelectType() {
presentationModel.setType(typesComboBox.getSelectionModel().getSelectedItem()); model.setType(typesComboBox.getSelectionModel().getSelectedItem());
} }
@FXML @FXML
void onSelectCurrency() { void onSelectCurrency() {
presentationModel.setCurrency(currencyComboBox.getSelectionModel().getSelectedItem()); model.setCurrency(currencyComboBox.getSelectionModel().getSelectedItem());
} }
@FXML @FXML
@ -165,19 +129,19 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
countryComboBox.setVisible(true); countryComboBox.setVisible(true);
Region region = regionComboBox.getSelectionModel().getSelectedItem(); Region region = regionComboBox.getSelectionModel().getSelectedItem();
if (region != null) if (region != null)
countryComboBox.setItems(presentationModel.getAllCountriesFor(region)); countryComboBox.setItems(model.getAllCountriesFor(region));
} }
@FXML @FXML
void onSelectCountry() { void onSelectCountry() {
Country country = countryComboBox.getSelectionModel().getSelectedItem(); Country country = countryComboBox.getSelectionModel().getSelectedItem();
if (country != null) if (country != null)
presentationModel.setCountry(country); model.setCountry(country);
} }
@FXML @FXML
void onSave() { void onSave() {
InputValidator.ValidationResult result = presentationModel.requestSaveBankAccount(); InputValidator.ValidationResult result = model.requestSaveBankAccount();
if (result.isValid) { if (result.isValid) {
selectionComboBox.getSelectionModel().select(null); selectionComboBox.getSelectionModel().select(null);
Popups.openInfoPopup("Your payments account has been saved.", Popups.openInfoPopup("Your payments account has been saved.",
@ -187,13 +151,12 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
@FXML @FXML
void onCompleted() { void onCompleted() {
if (parent instanceof MultiStepNavigation) parent.nextStep(this);
((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML
void onRemoveAccount() { void onRemoveAccount() {
presentationModel.removeBankAccount(); model.removeBankAccount();
selectionComboBox.getSelectionModel().select(null); selectionComboBox.getSelectionModel().select(null);
} }
@ -208,26 +171,22 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListeners() { private void setupListeners() {
presentationModel.type.addListener((ov, oldValue, newValue) -> { model.type.addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
typesComboBox.getSelectionModel().select(typesComboBox.getItems().indexOf(newValue)); typesComboBox.getSelectionModel().select(typesComboBox.getItems().indexOf(newValue));
else else
typesComboBox.getSelectionModel().clearSelection(); typesComboBox.getSelectionModel().clearSelection();
}); });
presentationModel.currency.addListener((ov, oldValue, newValue) -> { model.currency.addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
currencyComboBox.getSelectionModel().select(currencyComboBox.getItems().indexOf(newValue)); currencyComboBox.getSelectionModel().select(currencyComboBox.getItems().indexOf(newValue));
else else
currencyComboBox.getSelectionModel().clearSelection(); currencyComboBox.getSelectionModel().clearSelection();
}); });
presentationModel.country.addListener((ov, oldValue, newValue) -> { model.country.addListener((ov, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
int regionIndex = regionComboBox.getItems().indexOf(newValue.getRegion()); int regionIndex = regionComboBox.getItems().indexOf(newValue.getRegion());
if (regionIndex >= 0 && regionIndex < regionComboBox.getItems().size()) if (regionIndex >= 0 && regionIndex < regionComboBox.getItems().size())
@ -243,7 +202,7 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
} }
}); });
presentationModel.getCountryNotInAcceptedCountriesList().addListener((ov, oldValue, newValue) -> { model.getCountryNotInAcceptedCountriesList().addListener((ov, oldValue, newValue) -> {
if (newValue) { if (newValue) {
overlayManager.blurContent(); overlayManager.blurContent();
List<Action> actions = new ArrayList<>(); List<Action> actions = new ArrayList<>();
@ -271,33 +230,32 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
actions); actions);
if (Popups.isYes(response)) if (Popups.isYes(response))
presentationModel.addCountryToAcceptedCountriesList(); model.addCountryToAcceptedCountriesList();
} }
}); });
presentationModel.getAllBankAccounts().addListener((ListChangeListener<BankAccount>) change -> model.getAllBankAccounts().addListener((ListChangeListener<BankAccount>) change ->
completedButton.setDisable(presentationModel.getAllBankAccounts().isEmpty())); completedButton.setDisable(model.getAllBankAccounts().isEmpty()));
completedButton.setDisable(presentationModel.getAllBankAccounts().isEmpty()); completedButton.setDisable(model.getAllBankAccounts().isEmpty());
} }
private void setupBindings() { private void setupBindings() {
// input // input
nameOfBankTextField.textProperty().bindBidirectional(presentationModel.title); nameOfBankTextField.textProperty().bindBidirectional(model.title);
holderNameTextField.textProperty().bindBidirectional(presentationModel.holderName); holderNameTextField.textProperty().bindBidirectional(model.holderName);
primaryIDTextField.textProperty().bindBidirectional(presentationModel.primaryID); primaryIDTextField.textProperty().bindBidirectional(model.primaryID);
secondaryIDTextField.textProperty().bindBidirectional(presentationModel.secondaryID); secondaryIDTextField.textProperty().bindBidirectional(model.secondaryID);
primaryIDTextField.promptTextProperty().bind(presentationModel.primaryIDPrompt); primaryIDTextField.promptTextProperty().bind(model.primaryIDPrompt);
secondaryIDTextField.promptTextProperty().bind(presentationModel.secondaryIDPrompt); secondaryIDTextField.promptTextProperty().bind(model.secondaryIDPrompt);
selectionComboBox.promptTextProperty().bind(presentationModel.selectionPrompt); selectionComboBox.promptTextProperty().bind(model.selectionPrompt);
selectionComboBox.disableProperty().bind(presentationModel.selectionDisable); selectionComboBox.disableProperty().bind(model.selectionDisable);
saveButton.disableProperty().bind(presentationModel.saveButtonDisable); saveButton.disableProperty().bind(model.saveButtonDisable);
removeBankAccountButton.disableProperty().bind(createBooleanBinding(() -> removeBankAccountButton.disableProperty().bind(createBooleanBinding(() ->
(selectionComboBox.getSelectionModel().selectedIndexProperty().get() == -1), (selectionComboBox.getSelectionModel().selectedIndexProperty().get() == -1),
selectionComboBox.getSelectionModel().selectedIndexProperty())); selectionComboBox.getSelectionModel().selectedIndexProperty()));
} }
} }

View file

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.account.content.fiat;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.validation.BankAccountNumberValidator; import io.bitsquare.gui.util.validation.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -30,6 +29,9 @@ import com.google.inject.Inject;
import java.util.Currency; import java.util.Currency;
import viewfx.model.ViewModel;
import viewfx.model.support.ActivatableWithDelegate;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -40,11 +42,7 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.slf4j.Logger; class FiatAccountViewModel extends ActivatableWithDelegate<FiatAccountDataModel> implements ViewModel {
import org.slf4j.LoggerFactory;
class FiatAccountPm extends PresentationModel<FiatAccountModel> {
private static final Logger log = LoggerFactory.getLogger(FiatAccountPm.class);
private final BankAccountNumberValidator bankAccountNumberValidator; private final BankAccountNumberValidator bankAccountNumberValidator;
@ -62,96 +60,60 @@ class FiatAccountPm extends PresentationModel<FiatAccountModel> {
final ObjectProperty<Currency> currency = new SimpleObjectProperty<>(); final ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
FiatAccountPm(FiatAccountModel model, BankAccountNumberValidator bankAccountNumberValidator) { public FiatAccountViewModel(FiatAccountDataModel delegate, BankAccountNumberValidator bankAccountNumberValidator) {
super(model); super(delegate);
this.bankAccountNumberValidator = bankAccountNumberValidator; this.bankAccountNumberValidator = bankAccountNumberValidator;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
// input // input
title.bindBidirectional(model.title); title.bindBidirectional(delegate.title);
holderName.bindBidirectional(model.holderName); holderName.bindBidirectional(delegate.holderName);
primaryID.bindBidirectional(model.primaryID); primaryID.bindBidirectional(delegate.primaryID);
secondaryID.bindBidirectional(model.secondaryID); secondaryID.bindBidirectional(delegate.secondaryID);
type.bindBidirectional(model.type); type.bindBidirectional(delegate.type);
country.bindBidirectional(model.country); country.bindBidirectional(delegate.country);
currency.bindBidirectional(model.currency); currency.bindBidirectional(delegate.currency);
primaryIDPrompt.bind(model.primaryIDPrompt); primaryIDPrompt.bind(delegate.primaryIDPrompt);
secondaryIDPrompt.bind(model.secondaryIDPrompt); secondaryIDPrompt.bind(delegate.secondaryIDPrompt);
selectionPrompt.set("No bank account available"); selectionPrompt.set("No bank account available");
selectionDisable.set(true); selectionDisable.set(true);
model.title.addListener((ov, oldValue, newValue) -> validateInput()); delegate.title.addListener((ov, oldValue, newValue) -> validateInput());
holderName.addListener((ov, oldValue, newValue) -> validateInput()); holderName.addListener((ov, oldValue, newValue) -> validateInput());
primaryID.addListener((ov, oldValue, newValue) -> validateInput()); primaryID.addListener((ov, oldValue, newValue) -> validateInput());
secondaryID.addListener((ov, oldValue, newValue) -> validateInput()); secondaryID.addListener((ov, oldValue, newValue) -> validateInput());
super.initialize();
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate(); delegate.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
model.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
applyAllBankAccounts(); applyAllBankAccounts();
} }
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
InputValidator.ValidationResult requestSaveBankAccount() { InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput(); InputValidator.ValidationResult result = validateInput();
if (result.isValid) { if (result.isValid) {
model.saveBankAccount(); delegate.saveBankAccount();
} }
return result; return result;
} }
void removeBankAccount() { void removeBankAccount() {
model.removeBankAccount(); delegate.removeBankAccount();
} }
void addCountryToAcceptedCountriesList() { void addCountryToAcceptedCountriesList() {
model.addCountryToAcceptedCountriesList(); delegate.addCountryToAcceptedCountriesList();
} }
void selectBankAccount(BankAccount bankAccount) { void selectBankAccount(BankAccount bankAccount) {
model.selectBankAccount(bankAccount); delegate.selectBankAccount(bankAccount);
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Converters
///////////////////////////////////////////////////////////////////////////////////////////
StringConverter<BankAccountType> getTypesConverter() { StringConverter<BankAccountType> getTypesConverter() {
return new StringConverter<BankAccountType>() { return new StringConverter<BankAccountType>() {
@Override @Override
@ -225,32 +187,28 @@ class FiatAccountPm extends PresentationModel<FiatAccountModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<BankAccountType> getAllTypes() { ObservableList<BankAccountType> getAllTypes() {
return model.allTypes; return delegate.allTypes;
} }
ObservableList<BankAccount> getAllBankAccounts() { ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts; return delegate.allBankAccounts;
} }
ObservableList<Currency> getAllCurrencies() { ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies; return delegate.allCurrencies;
} }
ObservableList<Region> getAllRegions() { ObservableList<Region> getAllRegions() {
return model.allRegions; return delegate.allRegions;
} }
BooleanProperty getCountryNotInAcceptedCountriesList() { BooleanProperty getCountryNotInAcceptedCountriesList() {
return model.countryNotInAcceptedCountriesList; return delegate.countryNotInAcceptedCountriesList;
} }
ObservableList<Country> getAllCountriesFor(Region selectedRegion) { ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return model.getAllCountriesFor(selectedRegion); return delegate.getAllCountriesFor(selectedRegion);
} }
BankAccountNumberValidator getBankAccountNumberValidator() { BankAccountNumberValidator getBankAccountNumberValidator() {
@ -258,32 +216,24 @@ class FiatAccountPm extends PresentationModel<FiatAccountModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setType(BankAccountType type) { void setType(BankAccountType type) {
model.setType(type); delegate.setType(type);
validateInput(); validateInput();
} }
void setCountry(Country country) { void setCountry(Country country) {
model.setCountry(country); delegate.setCountry(country);
validateInput(); validateInput();
} }
void setCurrency(Currency currency) { void setCurrency(Currency currency) {
model.setCurrency(currency); delegate.setCurrency(currency);
validateInput(); validateInput();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void applyAllBankAccounts() { private void applyAllBankAccounts() {
if (model.allBankAccounts.isEmpty()) { if (delegate.allBankAccounts.isEmpty()) {
selectionPrompt.set("No bank account available"); selectionPrompt.set("No bank account available");
selectionDisable.set(true); selectionDisable.set(true);
} }
@ -294,23 +244,23 @@ class FiatAccountPm extends PresentationModel<FiatAccountModel> {
} }
private InputValidator.ValidationResult validateInput() { private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = bankAccountNumberValidator.validate(model.title.get()); InputValidator.ValidationResult result = bankAccountNumberValidator.validate(delegate.title.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.holderName.get()); result = bankAccountNumberValidator.validate(delegate.holderName.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.primaryID.get()); result = bankAccountNumberValidator.validate(delegate.primaryID.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.secondaryID.get()); result = bankAccountNumberValidator.validate(delegate.secondaryID.get());
if (result.isValid) { if (result.isValid) {
if (model.currency.get() == null) if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a currency"); "You have not selected a currency");
if (result.isValid) { if (result.isValid) {
if (model.country.get() == null) if (delegate.country.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a country of the payments account"); "You have not selected a country of the payments account");
if (result.isValid) { if (result.isValid) {
if (model.type.get() == null) if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a payments method"); "You have not selected a payments method");
} }

View file

@ -22,7 +22,6 @@ import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.arbitrator.Reputation; import io.bitsquare.arbitrator.Reputation;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.UIModel;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.CurrencyUtil;
@ -44,6 +43,9 @@ import java.util.Currency;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import viewfx.model.Activatable;
import viewfx.model.DataModel;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -51,11 +53,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import org.slf4j.Logger; class IrcAccountDataModel implements Activatable, DataModel {
import org.slf4j.LoggerFactory;
class IrcAccountModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(IrcAccountModel.class);
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
@ -72,28 +70,13 @@ class IrcAccountModel extends UIModel {
final ObservableList<BankAccount> allBankAccounts = FXCollections.observableArrayList(); final ObservableList<BankAccount> allBankAccounts = FXCollections.observableArrayList();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
IrcAccountModel(User user, Persistence persistence, AccountSettings accountSettings, public IrcAccountDataModel(User user, Persistence persistence, AccountSettings accountSettings,
MessageService messageService) { MessageService messageService) {
this.persistence = persistence; this.persistence = persistence;
this.user = user; this.user = user;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.messageService = messageService; this.messageService = messageService;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
if (accountSettings.getAcceptedArbitrators().isEmpty()) if (accountSettings.getAcceptedArbitrators().isEmpty())
addMockArbitrator(); addMockArbitrator();
@ -101,27 +84,14 @@ class IrcAccountModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts()); allBankAccounts.setAll(user.getBankAccounts());
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate(); // no-op
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
void saveBankAccount() { void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(), BankAccount bankAccount = new BankAccount(type.get(),
currency.get(), currency.get(),
@ -137,19 +107,11 @@ class IrcAccountModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getAllCountriesFor(Region selectedRegion) { ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion)); return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setType(BankAccountType type) { void setType(BankAccountType type) {
this.type.set(type); this.type.set(type);
} }
@ -159,10 +121,6 @@ class IrcAccountModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void reset() { private void reset() {
nickName.set(null); nickName.set(null);

View file

@ -24,7 +24,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.irc.IrcAccountViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.irc.IrcAccountView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -18,38 +18,31 @@
package io.bitsquare.gui.main.account.content.irc; package io.bitsquare.gui.main.account.content.irc;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
import java.net.URL;
import java.util.Currency; import java.util.Currency;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel;
import viewfx.view.Wizard;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.util.Callback; import javafx.util.Callback;
import org.slf4j.Logger; /**
import org.slf4j.LoggerFactory; * Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat.
/*
Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat.
*/ */
public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements ContextAware { @FxmlView
public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccountViewModel> implements Wizard.Step {
private static final Logger log = LoggerFactory.getLogger(IrcAccountViewCB.class);
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML InputTextField ircNickNameTextField; @FXML InputTextField ircNickNameTextField;
@ -57,27 +50,19 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
@FXML ComboBox<BankAccountType> typesComboBox; @FXML ComboBox<BankAccountType> typesComboBox;
@FXML ComboBox<Currency> currencyComboBox; @FXML ComboBox<Currency> currencyComboBox;
private Wizard parent;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
IrcAccountViewCB(IrcAccountPm presentationModel) { public IrcAccountView(IrcAccountViewModel model) {
super(presentationModel); super(model);
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void doActivate() {
ircNickNameTextField.setValidator(presentationModel.getNickNameValidator()); ircNickNameTextField.setValidator(model.getNickNameValidator());
typesComboBox.setItems(presentationModel.getAllTypes()); typesComboBox.setItems(model.getAllTypes());
typesComboBox.setConverter(presentationModel.getTypesConverter()); typesComboBox.setConverter(model.getTypesConverter());
// we use a custom cell for deactivating non IRC items, later we use the standard cell and the StringConverter // we use a custom cell for deactivating non IRC items, later we use the standard cell and the StringConverter
typesComboBox.setCellFactory(new Callback<ListView<BankAccountType>, ListCell<BankAccountType>>() { typesComboBox.setCellFactory(new Callback<ListView<BankAccountType>, ListCell<BankAccountType>>() {
@Override @Override
@ -88,7 +73,7 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
protected void updateItem(BankAccountType item, boolean empty) { protected void updateItem(BankAccountType item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
setText(presentationModel.getBankAccountType(item)); setText(model.getBankAccountType(item));
if (item == null || empty) { if (item == null || empty) {
setGraphic(null); setGraphic(null);
@ -103,8 +88,8 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
}); });
typesComboBox.getSelectionModel().select(0); typesComboBox.getSelectionModel().select(0);
currencyComboBox.setItems(presentationModel.getAllCurrencies()); currencyComboBox.setItems(model.getAllCurrencies());
currencyComboBox.setConverter(presentationModel.getCurrencyConverter()); currencyComboBox.setConverter(model.getCurrencyConverter());
// we use a custom cell for deactivating non EUR items, later we use the standard cell and the StringConverter // we use a custom cell for deactivating non EUR items, later we use the standard cell and the StringConverter
currencyComboBox.setCellFactory(new Callback<ListView<Currency>, ListCell<Currency>>() { currencyComboBox.setCellFactory(new Callback<ListView<Currency>, ListCell<Currency>>() {
@Override @Override
@ -132,13 +117,6 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
}); });
currencyComboBox.getSelectionModel().select(0); currencyComboBox.getSelectionModel().select(0);
super.initialize(url, rb);
}
@Override
public void activate() {
super.activate();
setupListeners(); setupListeners();
setupBindings(); setupBindings();
@ -153,48 +131,29 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
"bank transfer.")); "bank transfer."));
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void setParent(Wizard parent) {
super.deactivate(); this.parent = parent;
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void terminate() { public void hideWizardNavigation() {
super.terminate();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void useSettingsContext(boolean useSettingsContext) {
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML @FXML
void onSelectType() { void onSelectType() {
presentationModel.setType(typesComboBox.getSelectionModel().getSelectedItem()); model.setType(typesComboBox.getSelectionModel().getSelectedItem());
} }
@FXML @FXML
void onSelectCurrency() { void onSelectCurrency() {
presentationModel.setCurrency(currencyComboBox.getSelectionModel().getSelectedItem()); model.setCurrency(currencyComboBox.getSelectionModel().getSelectedItem());
} }
@FXML @FXML
void onSave() { void onSave() {
InputValidator.ValidationResult result = presentationModel.requestSaveBankAccount(); if (model.requestSaveBankAccount().isValid)
if (result.isValid && parent instanceof MultiStepNavigation) parent.nextStep(this);
((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML
@ -212,19 +171,16 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
"connection."); "connection.");
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListeners() { private void setupListeners() {
presentationModel.type.addListener((ov, oldValue, newValue) -> { model.type.addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
typesComboBox.getSelectionModel().select(typesComboBox.getItems().indexOf(newValue)); typesComboBox.getSelectionModel().select(typesComboBox.getItems().indexOf(newValue));
else else
typesComboBox.getSelectionModel().clearSelection(); typesComboBox.getSelectionModel().clearSelection();
}); });
presentationModel.currency.addListener((ov, oldValue, newValue) -> { model.currency.addListener((ov, oldValue, newValue) -> {
if (newValue != null) if (newValue != null)
currencyComboBox.getSelectionModel().select(currencyComboBox.getItems().indexOf(newValue)); currencyComboBox.getSelectionModel().select(currencyComboBox.getItems().indexOf(newValue));
else else
@ -234,10 +190,8 @@ public class IrcAccountViewCB extends CachedViewCB<IrcAccountPm> implements Cont
private void setupBindings() { private void setupBindings() {
// input // input
ircNickNameTextField.textProperty().bindBidirectional(presentationModel.ircNickName); ircNickNameTextField.textProperty().bindBidirectional(model.ircNickName);
saveButton.disableProperty().bind(presentationModel.saveButtonDisable); saveButton.disableProperty().bind(model.saveButtonDisable);
} }
} }

View file

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.account.content.irc;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.validation.BankAccountNumberValidator; import io.bitsquare.gui.util.validation.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -28,6 +27,9 @@ import com.google.inject.Inject;
import java.util.Currency; import java.util.Currency;
import viewfx.model.ViewModel;
import viewfx.model.support.ActivatableWithDelegate;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -37,11 +39,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.slf4j.Logger; class IrcAccountViewModel extends ActivatableWithDelegate<IrcAccountDataModel> implements ViewModel {
import org.slf4j.LoggerFactory;
class IrcAccountPm extends PresentationModel<IrcAccountModel> {
private static final Logger log = LoggerFactory.getLogger(IrcAccountPm.class);
private final InputValidator nickNameValidator; private final InputValidator nickNameValidator;
@ -51,71 +49,32 @@ class IrcAccountPm extends PresentationModel<IrcAccountModel> {
final ObjectProperty<Currency> currency = new SimpleObjectProperty<>(); final ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
IrcAccountPm(IrcAccountModel model, BankAccountNumberValidator nickNameValidator) { public IrcAccountViewModel(IrcAccountDataModel delegate, BankAccountNumberValidator nickNameValidator) {
super(model); super(delegate);
this.nickNameValidator = nickNameValidator; this.nickNameValidator = nickNameValidator;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
// input // input
ircNickName.bindBidirectional(model.nickName); ircNickName.bindBidirectional(delegate.nickName);
type.bindBidirectional(model.type); type.bindBidirectional(delegate.type);
currency.bindBidirectional(model.currency); currency.bindBidirectional(delegate.currency);
model.nickName.addListener((ov, oldValue, newValue) -> validateInput()); delegate.nickName.addListener((ov, oldValue, newValue) -> validateInput());
super.initialize();
} }
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
InputValidator.ValidationResult requestSaveBankAccount() { InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput(); InputValidator.ValidationResult result = validateInput();
if (result.isValid) { if (result.isValid) {
model.saveBankAccount(); delegate.saveBankAccount();
} }
return result; return result;
} }
ObservableList<BankAccount> getAllBankAccounts() { ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts; return delegate.allBankAccounts;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Converters
///////////////////////////////////////////////////////////////////////////////////////////
StringConverter<BankAccountType> getTypesConverter() { StringConverter<BankAccountType> getTypesConverter() {
return new StringConverter<BankAccountType>() { return new StringConverter<BankAccountType>() {
@Override @Override
@ -149,16 +108,12 @@ class IrcAccountPm extends PresentationModel<IrcAccountModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<BankAccountType> getAllTypes() { ObservableList<BankAccountType> getAllTypes() {
return model.allTypes; return delegate.allTypes;
} }
ObservableList<Currency> getAllCurrencies() { ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies; return delegate.allCurrencies;
} }
InputValidator getNickNameValidator() { InputValidator getNickNameValidator() {
@ -166,33 +121,25 @@ class IrcAccountPm extends PresentationModel<IrcAccountModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setType(BankAccountType type) { void setType(BankAccountType type) {
model.setType(type); delegate.setType(type);
validateInput(); validateInput();
} }
void setCurrency(Currency currency) { void setCurrency(Currency currency) {
model.setCurrency(currency); delegate.setCurrency(currency);
validateInput(); validateInput();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private InputValidator.ValidationResult validateInput() { private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = nickNameValidator.validate(model.nickName.get()); InputValidator.ValidationResult result = nickNameValidator.validate(delegate.nickName.get());
if (model.currency.get() == null) if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a currency"); "You have not selected a currency");
if (result.isValid) { if (result.isValid) {
if (model.type.get() == null) if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a payments method"); "You have not selected a payments method");
} }

View file

@ -1,79 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class PasswordModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(PasswordModel.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private PasswordModel() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
}

View file

@ -22,7 +22,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.password.PasswordViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.password.PasswordView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -0,0 +1,83 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
@FxmlView
public class PasswordView extends InitializableView<GridPane, PasswordViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
private Wizard parent;
@Inject
private PasswordView(PasswordViewModel model) {
super(model);
}
@Override
public void initialize() {
passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(model.repeatedPasswordField);
saveButton.disableProperty().bind(model.saveButtonDisabled);
}
@Override
public void setParent(Wizard parent) {
this.parent = parent;
}
@Override
public void hideWizardNavigation() {
buttonsHBox.getChildren().remove(skipButton);
}
@FXML
private void onSaved() {
if (model.requestSavePassword())
parent.nextStep(this);
else
log.debug(model.getErrorMessage()); // TODO use validating passwordTF
}
@FXML
private void onSkipped() {
parent.nextStep(this);
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_PASSWORD);
}
}

View file

@ -1,130 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(PasswordViewCB.class);
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private PasswordViewCB(PasswordPM presentationModel) {
super(presentationModel);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField);
saveButton.disableProperty().bind(presentationModel.saveButtonDisabled);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void useSettingsContext(boolean useSettingsContext) {
if (useSettingsContext)
buttonsHBox.getChildren().remove(skipButton);
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
private void onSaved() {
boolean result = presentationModel.requestSavePassword();
if (result) {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
else {
// TODO use validating passwordTF
log.debug(presentationModel.getErrorMessage());
}
}
@FXML
private void onSkipped() {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_PASSWORD);
}
}

View file

@ -17,22 +17,19 @@
package io.bitsquare.gui.main.account.content.password; package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator; import io.bitsquare.gui.util.validation.PasswordValidator;
import com.google.inject.Inject; import com.google.inject.Inject;
import viewfx.model.ViewModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import org.slf4j.Logger; class PasswordViewModel implements ViewModel {
import org.slf4j.LoggerFactory;
class PasswordPM extends PresentationModel<PasswordModel> {
private static final Logger log = LoggerFactory.getLogger(PasswordPM.class);
private final PasswordValidator passwordValidator; private final PasswordValidator passwordValidator;
@ -43,13 +40,8 @@ class PasswordPM extends PresentationModel<PasswordModel> {
final BooleanProperty saveButtonDisabled = new SimpleBooleanProperty(true); final BooleanProperty saveButtonDisabled = new SimpleBooleanProperty(true);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private PasswordPM(PasswordModel model, PasswordValidator passwordValidator) { public PasswordViewModel(PasswordValidator passwordValidator) {
super(model);
this.passwordValidator = passwordValidator; this.passwordValidator = passwordValidator;
passwordField.addListener((ov) -> saveButtonDisabled.set(!validate())); passwordField.addListener((ov) -> saveButtonDisabled.set(!validate()));
@ -57,56 +49,23 @@ class PasswordPM extends PresentationModel<PasswordModel> {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
boolean requestSavePassword() { boolean requestSavePassword() {
if (validate()) { if (validate()) {
model.savePassword(passwordField.get()); savePassword(passwordField.get());
return true; return true;
} }
return false; return false;
} }
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
String getErrorMessage() { String getErrorMessage() {
return errorMessage; return errorMessage;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private boolean validate() { private boolean validate() {
InputValidator.ValidationResult result = passwordValidator.validate(passwordField.get()); InputValidator.ValidationResult result = passwordValidator.validate(passwordField.get());
if (result.isValid) { if (result.isValid) {

View file

@ -21,7 +21,6 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener; import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -35,6 +34,8 @@ import com.google.inject.Inject;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import viewfx.model.DataModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -45,8 +46,8 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
class RegistrationModel extends UIModel { class RegistrationDataModel implements DataModel {
private static final Logger log = LoggerFactory.getLogger(RegistrationModel.class); private static final Logger log = LoggerFactory.getLogger(RegistrationDataModel.class);
private final WalletService walletService; private final WalletService walletService;
private final User user; private final User user;
@ -60,26 +61,12 @@ class RegistrationModel extends UIModel {
final StringProperty payFeeErrorMessage = new SimpleStringProperty(); final StringProperty payFeeErrorMessage = new SimpleStringProperty();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RegistrationModel(WalletService walletService, User user, Persistence persistence) { public RegistrationDataModel(WalletService walletService, User user, Persistence persistence) {
this.walletService = walletService; this.walletService = walletService;
this.user = user; this.user = user;
this.persistence = persistence; this.persistence = persistence;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
super.initialize();
if (walletService != null && walletService.getWallet() != null) { if (walletService != null && walletService.getWallet() != null) {
addressEntry = walletService.getRegistrationAddressEntry(); addressEntry = walletService.getRegistrationAddressEntry();
@ -93,29 +80,6 @@ class RegistrationModel extends UIModel {
} }
} }
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Methods
///////////////////////////////////////////////////////////////////////////////////////////
void payFee() { void payFee() {
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() { FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
@Override @Override
@ -147,10 +111,6 @@ class RegistrationModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
WalletService getWalletService() { WalletService getWalletService() {
return walletService; return walletService;
} }
@ -168,10 +128,6 @@ class RegistrationModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void updateBalance(@NotNull Coin balance) { private void updateBalance(@NotNull Coin balance) {
isWalletFunded.set(balance.compareTo(getFeeAsCoin()) >= 0); isWalletFunded.set(balance.compareTo(getFeeAsCoin()) >= 0);
} }

View file

@ -24,7 +24,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.registration.RegistrationViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.registration.RegistrationView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -17,42 +17,34 @@
package io.bitsquare.gui.main.account.content.registration; package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.AddressTextField; import io.bitsquare.gui.components.AddressTextField;
import io.bitsquare.gui.components.BalanceTextField; import io.bitsquare.gui.components.BalanceTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*;
import org.controlsfx.control.action.AbstractAction; import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.slf4j.Logger; @FxmlView
import org.slf4j.LoggerFactory; public class RegistrationView extends InitializableView<GridPane, RegistrationViewModel> implements Wizard.Step {
public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(RegistrationViewCB.class);
private final OverlayManager overlayManager;
@FXML TextField feeTextField; @FXML TextField feeTextField;
@FXML AddressTextField addressTextField; @FXML AddressTextField addressTextField;
@ -61,40 +53,32 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
@FXML Label paymentSpinnerInfoLabel; @FXML Label paymentSpinnerInfoLabel;
@FXML ProgressIndicator paymentSpinner; @FXML ProgressIndicator paymentSpinner;
private Wizard parent;
/////////////////////////////////////////////////////////////////////////////////////////// private final OverlayManager overlayManager;
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RegistrationViewCB(RegistrationPM presentationModel, OverlayManager overlayManager) { private RegistrationView(RegistrationViewModel model, OverlayManager overlayManager) {
super(presentationModel); super(model);
this.overlayManager = overlayManager; this.overlayManager = overlayManager;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
super.initialize(url, rb); feeTextField.setText(model.getFeeAsString());
addressTextField.setAmountAsCoin(model.getFeeAsCoin());
feeTextField.setText(presentationModel.getFeeAsString()); addressTextField.setPaymentLabel(model.getPaymentLabel());
addressTextField.setAmountAsCoin(presentationModel.getFeeAsCoin()); addressTextField.setAddress(model.getAddressAsString());
addressTextField.setPaymentLabel(presentationModel.getPaymentLabel());
addressTextField.setAddress(presentationModel.getAddressAsString());
// TODO find better solution // TODO find better solution
addressTextField.setOverlayManager(overlayManager); addressTextField.setOverlayManager(overlayManager);
balanceTextField.setup(presentationModel.getWalletService(), presentationModel.address.get(), balanceTextField.setup(model.getWalletService(), model.address.get(),
presentationModel.getFormatter()); model.getFormatter());
payButton.disableProperty().bind(presentationModel.isPayButtonDisabled); payButton.disableProperty().bind(model.isPayButtonDisabled);
presentationModel.requestPlaceOfferErrorMessage.addListener((o, oldValue, newValue) -> { model.requestPlaceOfferErrorMessage.addListener((o, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
Popups.openErrorPopup(BSResources.get("shared.error"), Popups.openErrorPopup(BSResources.get("shared.error"),
BSResources.get("An error occurred when paying the registration fee"), BSResources.get("An error occurred when paying the registration fee"),
@ -102,14 +86,14 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
} }
}); });
paymentSpinnerInfoLabel.visibleProperty().bind(presentationModel.isPaymentSpinnerVisible); paymentSpinnerInfoLabel.visibleProperty().bind(model.isPaymentSpinnerVisible);
presentationModel.isPaymentSpinnerVisible.addListener((ov, oldValue, newValue) -> { model.isPaymentSpinnerVisible.addListener((ov, oldValue, newValue) -> {
paymentSpinner.setProgress(newValue ? -1 : 0); paymentSpinner.setProgress(newValue ? -1 : 0);
paymentSpinner.setVisible(newValue); paymentSpinner.setVisible(newValue);
}); });
presentationModel.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> { model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
if (newValue) { if (newValue) {
overlayManager.blurContent(); overlayManager.blurContent();
@ -126,8 +110,7 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
public void handle(ActionEvent actionEvent) { public void handle(ActionEvent actionEvent) {
getProperties().put("type", "CLOSE"); getProperties().put("type", "CLOSE");
try { try {
if (parent instanceof MultiStepNavigation) parent.nextStep(RegistrationView.this);
((MultiStepNavigation) parent).nextStep(RegistrationViewCB.this);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -144,55 +127,23 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
}); });
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void activate() { public void setParent(Wizard parent) {
super.activate(); this.parent = parent;
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void hideWizardNavigation() {
super.deactivate();
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void useSettingsContext(boolean useSettingsContext) {
if (useSettingsContext) {
// TODO not impl. yet
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML @FXML
private void onPayFee() { private void onPayFee() {
presentationModel.payFee(); model.payFee();
} }
@FXML @FXML
private void onOpenHelp() { private void onOpenHelp() {
Help.openWindow(HelpId.PAY_ACCOUNT_FEE); Help.openWindow(HelpId.PAY_ACCOUNT_FEE);
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
} }

View file

@ -18,7 +18,6 @@
package io.bitsquare.gui.main.account.content.registration; package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -27,6 +26,9 @@ import org.bitcoinj.core.Coin;
import com.google.inject.Inject; import com.google.inject.Inject;
import viewfx.model.ViewModel;
import viewfx.model.support.WithDelegate;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -34,12 +36,8 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class RegistrationViewModel extends WithDelegate<RegistrationDataModel> implements ViewModel {
class RegistrationPM extends PresentationModel<RegistrationModel> {
private static final Logger log = LoggerFactory.getLogger(RegistrationPM.class);
final BooleanProperty isPayButtonDisabled = new SimpleBooleanProperty(true); final BooleanProperty isPayButtonDisabled = new SimpleBooleanProperty(true);
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty(); final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
@ -51,42 +49,28 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
private final BSFormatter formatter; private final BSFormatter formatter;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RegistrationPM(RegistrationModel model, BSFormatter formatter) { public RegistrationViewModel(RegistrationDataModel delegate, BSFormatter formatter) {
super(model); super(delegate);
this.formatter = formatter; this.formatter = formatter;
}
if (delegate.getAddressEntry() != null) {
/////////////////////////////////////////////////////////////////////////////////////////// address.set(delegate.getAddressEntry().getAddress());
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
super.initialize();
if (model.getAddressEntry() != null) {
address.set(model.getAddressEntry().getAddress());
} }
model.isWalletFunded.addListener((ov, oldValue, newValue) -> { delegate.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue) if (newValue)
validateInput(); validateInput();
}); });
validateInput(); validateInput();
model.payFeeSuccess.addListener((ov, oldValue, newValue) -> { delegate.payFeeSuccess.addListener((ov, oldValue, newValue) -> {
isPayButtonDisabled.set(newValue); isPayButtonDisabled.set(newValue);
showTransactionPublishedScreen.set(newValue); showTransactionPublishedScreen.set(newValue);
isPaymentSpinnerVisible.set(false); isPaymentSpinnerVisible.set(false);
}); });
model.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> { delegate.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
requestPlaceOfferErrorMessage.set(newValue); requestPlaceOfferErrorMessage.set(newValue);
isPaymentSpinnerVisible.set(false); isPaymentSpinnerVisible.set(false);
@ -94,46 +78,19 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
}); });
} }
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI actions
///////////////////////////////////////////////////////////////////////////////////////////
void payFee() { void payFee() {
model.payFeeErrorMessage.set(null); delegate.payFeeErrorMessage.set(null);
model.payFeeSuccess.set(false); delegate.payFeeSuccess.set(false);
isPayButtonDisabled.set(true); isPayButtonDisabled.set(true);
isPaymentSpinnerVisible.set(true); isPaymentSpinnerVisible.set(true);
model.payFee(); delegate.payFee();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
WalletService getWalletService() { WalletService getWalletService() {
return model.getWalletService(); return delegate.getWalletService();
} }
BSFormatter getFormatter() { BSFormatter getFormatter() {
@ -141,11 +98,11 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
} }
Coin getFeeAsCoin() { Coin getFeeAsCoin() {
return model.getFeeAsCoin(); return delegate.getFeeAsCoin();
} }
String getAddressAsString() { String getAddressAsString() {
return model.getAddressEntry() != null ? model.getAddressEntry().getAddress().toString() : ""; return delegate.getAddressEntry() != null ? delegate.getAddressEntry().getAddress().toString() : "";
} }
String getPaymentLabel() { String getPaymentLabel() {
@ -153,20 +110,16 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
} }
String getFeeAsString() { String getFeeAsString() {
return formatter.formatCoinWithCode(model.getFeeAsCoin()); return formatter.formatCoinWithCode(delegate.getFeeAsCoin());
} }
String getTransactionId() { String getTransactionId() {
return model.getTransactionId(); return delegate.getTransactionId();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void validateInput() { private void validateInput() {
isPayButtonDisabled.set(!(model.isWalletFunded.get())); isPayButtonDisabled.set(!(delegate.isWalletFunded.get()));
} }

View file

@ -20,7 +20,6 @@ package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.account.AccountSettings; import io.bitsquare.account.AccountSettings;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.arbitrator.Reputation; import io.bitsquare.arbitrator.Reputation;
import io.bitsquare.gui.UIModel;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.LanguageUtil; import io.bitsquare.locale.LanguageUtil;
@ -40,14 +39,13 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import viewfx.model.Activatable;
import viewfx.model.DataModel;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import org.slf4j.Logger; class RestrictionsDataModel implements Activatable, DataModel {
import org.slf4j.LoggerFactory;
class RestrictionsModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(RestrictionsModel.class);
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
@ -62,27 +60,13 @@ class RestrictionsModel extends UIModel {
final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions()); final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RestrictionsModel(User user, AccountSettings accountSettings, Persistence persistence, public RestrictionsDataModel(User user, AccountSettings accountSettings, Persistence persistence,
MessageService messageService) { MessageService messageService) {
this.user = user; this.user = user;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.persistence = persistence; this.persistence = persistence;
this.messageService = messageService; this.messageService = messageService;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
super.initialize();
AccountSettings persistedAccountSettings = (AccountSettings) persistence.read(accountSettings); AccountSettings persistedAccountSettings = (AccountSettings) persistence.read(accountSettings);
if (persistedAccountSettings != null) { if (persistedAccountSettings != null) {
@ -103,30 +87,16 @@ class RestrictionsModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
languageList.setAll(accountSettings.getAcceptedLanguageLocales()); languageList.setAll(accountSettings.getAcceptedLanguageLocales());
countryList.setAll(accountSettings.getAcceptedCountries()); countryList.setAll(accountSettings.getAcceptedCountries());
arbitratorList.setAll(accountSettings.getAcceptedArbitrators()); arbitratorList.setAll(accountSettings.getAcceptedArbitrators());
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate(); // no-op
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getAllCountriesFor(Region selectedRegion) { ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion)); return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
} }
@ -178,10 +148,6 @@ class RestrictionsModel extends UIModel {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void saveSettings() { private void saveSettings() {
persistence.write(accountSettings); persistence.write(accountSettings);
} }

View file

@ -1,157 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.Region;
import com.google.inject.Inject;
import java.util.Locale;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class RestrictionsPM extends PresentationModel<RestrictionsModel> {
private static final Logger log = LoggerFactory.getLogger(RestrictionsPM.class);
final BooleanProperty doneButtonDisable = new SimpleBooleanProperty(true);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private RestrictionsPM(RestrictionsModel model) {
super(model);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@Override
public void activate() {
super.activate();
updateDoneButtonDisableState();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////
void addLanguage(Locale locale) {
model.addLanguage(locale);
updateDoneButtonDisableState();
}
void removeLanguage(Locale locale) {
model.removeLanguage(locale);
updateDoneButtonDisableState();
}
void addCountry(Country country) {
model.addCountry(country);
updateDoneButtonDisableState();
}
void removeCountry(Country country) {
model.removeCountry(country);
updateDoneButtonDisableState();
}
void removeArbitrator(Arbitrator arbitrator) {
model.removeArbitrator(arbitrator);
updateDoneButtonDisableState();
}
void updateArbitratorList() {
model.updateArbitratorList();
updateDoneButtonDisableState();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getListWithAllEuroCountries() {
return model.getListWithAllEuroCountries();
}
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return model.getAllCountriesFor(selectedRegion);
}
ObservableList<Locale> getLanguageList() {
return model.languageList;
}
ObservableList<Region> getAllRegions() {
return model.allRegions;
}
ObservableList<Locale> getAllLanguages() {
return model.allLanguages;
}
ObservableList<Country> getCountryList() {
return model.countryList;
}
ObservableList<Arbitrator> getArbitratorList() {
return model.arbitratorList;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
//TODO Revert size() > -1 to 0(2 later). For mock testing disabled arbitratorList test
private void updateDoneButtonDisableState() {
boolean isValid = model.languageList != null && model.languageList.size() > 0 &&
model.countryList != null && model.countryList.size() > 0 &&
model.arbitratorList != null && model.arbitratorList.size() > -1;
doneButtonDisable.set(!isValid);
}
}

View file

@ -22,7 +22,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.restrictions.RestrictionsViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.restrictions.RestrictionsView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -18,26 +18,25 @@
package io.bitsquare.gui.main.account.content.restrictions; package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.CachedViewCB; import io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserView;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.Region; import io.bitsquare.locale.Region;
import java.net.URL;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.Wizard;
import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.*; import javafx.scene.image.*;
@ -47,12 +46,8 @@ import javafx.stage.Stage;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.slf4j.Logger; @FxmlView
import org.slf4j.LoggerFactory; public class RestrictionsView extends ActivatableViewAndModel<GridPane, RestrictionsViewModel> implements Wizard.Step {
public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(RestrictionsViewCB.class);
@FXML ListView<Locale> languagesListView; @FXML ListView<Locale> languagesListView;
@FXML ListView<Country> countriesListView; @FXML ListView<Country> countriesListView;
@ -62,77 +57,47 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
@FXML ComboBox<Country> countryComboBox; @FXML ComboBox<Country> countryComboBox;
@FXML Button completedButton, addAllEuroCountriesButton; @FXML Button completedButton, addAllEuroCountriesButton;
private Wizard parent;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Stage primaryStage; private final Stage primaryStage;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RestrictionsViewCB(RestrictionsPM presentationModel, ViewLoader viewLoader, Stage primaryStage) { private RestrictionsView(RestrictionsViewModel model, CachingViewLoader viewLoader, Stage primaryStage) {
super(presentationModel); super(model);
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.primaryStage = primaryStage; this.primaryStage = primaryStage;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
super.initialize(url, rb);
initLanguage(); initLanguage();
initCountry(); initCountry();
initArbitrators(); initArbitrators();
completedButton.disableProperty().bind(presentationModel.doneButtonDisable); completedButton.disableProperty().bind(model.doneButtonDisable);
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate(); languagesListView.setItems(model.getLanguageList());
countriesListView.setItems(model.getCountryList());
languagesListView.setItems(presentationModel.getLanguageList()); arbitratorsListView.setItems(model.getArbitratorList());
countriesListView.setItems(presentationModel.getCountryList());
arbitratorsListView.setItems(presentationModel.getArbitratorList());
} }
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void useSettingsContext(boolean useSettingsContext) { public void setParent(Wizard parent) {
if (useSettingsContext) this.parent = parent;
((GridPane) root).getChildren().remove(completedButton);
} }
@Override
/////////////////////////////////////////////////////////////////////////////////////////// public void hideWizardNavigation() {
// UI handlers root.getChildren().remove(completedButton);
/////////////////////////////////////////////////////////////////////////////////////////// }
@FXML @FXML
private void onAddLanguage() { private void onAddLanguage() {
presentationModel.addLanguage(languageComboBox.getSelectionModel().getSelectedItem()); model.addLanguage(languageComboBox.getSelectionModel().getSelectedItem());
languageComboBox.getSelectionModel().clearSelection(); languageComboBox.getSelectionModel().clearSelection();
} }
@ -140,32 +105,33 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
private void onSelectRegion() { private void onSelectRegion() {
countryComboBox.setVisible(true); countryComboBox.setVisible(true);
Region region = regionComboBox.getSelectionModel().getSelectedItem(); Region region = regionComboBox.getSelectionModel().getSelectedItem();
countryComboBox.setItems(presentationModel.getAllCountriesFor(region)); countryComboBox.setItems(model.getAllCountriesFor(region));
addAllEuroCountriesButton.setVisible(region.getCode().equals("EU")); addAllEuroCountriesButton.setVisible(region.getCode().equals("EU"));
} }
@FXML @FXML
private void onAddCountry() { private void onAddCountry() {
presentationModel.addCountry(countryComboBox.getSelectionModel().getSelectedItem()); model.addCountry(countryComboBox.getSelectionModel().getSelectedItem());
countryComboBox.getSelectionModel().clearSelection(); countryComboBox.getSelectionModel().clearSelection();
} }
@FXML @FXML
private void onAddAllEuroCountries() { private void onAddAllEuroCountries() {
countriesListView.setItems(presentationModel.getListWithAllEuroCountries()); countriesListView.setItems(model.getListWithAllEuroCountries());
} }
@FXML @FXML
private void onOpenArbitratorScreen() { private void onOpenArbitratorScreen(){
loadView(Navigation.Item.ARBITRATOR_BROWSER); View view = viewLoader.load(ArbitratorBrowserView.class);
showStage(view);
} }
@FXML @FXML
private void onCompleted() { private void onCompleted() {
if (parent instanceof MultiStepNavigation) if (parent instanceof Wizard)
((MultiStepNavigation) parent).nextStep(this); ((Wizard) parent).nextStep(this);
} }
@FXML @FXML
@ -183,15 +149,7 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
Help.openWindow(HelpId.SETUP_RESTRICTION_ARBITRATORS); Help.openWindow(HelpId.SETUP_RESTRICTION_ARBITRATORS);
} }
private void showStage(View view) {
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false);
final Stage stage = new Stage(); final Stage stage = new Stage();
stage.setTitle("Arbitrator selection"); stage.setTitle("Arbitrator selection");
stage.setMinWidth(800); stage.setMinWidth(800);
@ -202,25 +160,18 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
stage.setY(primaryStage.getY() + 50); stage.setY(primaryStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL); stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage); stage.initOwner(primaryStage);
Scene scene = new Scene((Parent) loaded.view, 800, 600); Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
stage.setScene(scene); stage.setScene(scene);
stage.setOnHidden(windowEvent -> { stage.setOnHidden(windowEvent -> {
if (navigationItem == Navigation.Item.ARBITRATOR_BROWSER) if (view instanceof ArbitratorBrowserView)
updateArbitratorList(); updateArbitratorList();
}); });
stage.show(); stage.show();
return loaded.controller;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
void updateArbitratorList() { void updateArbitratorList() {
presentationModel.updateArbitratorList(); model.updateArbitratorList();
arbitratorsListView.setItems(presentationModel.getArbitratorList()); arbitratorsListView.setItems(model.getArbitratorList());
} }
private void initLanguage() { private void initLanguage() {
@ -255,7 +206,7 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
} }
}); });
languageComboBox.setItems(presentationModel.getAllLanguages()); languageComboBox.setItems(model.getAllLanguages());
languageComboBox.setConverter(new StringConverter<Locale>() { languageComboBox.setConverter(new StringConverter<Locale>() {
@Override @Override
public String toString(Locale locale) { public String toString(Locale locale) {
@ -270,7 +221,7 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
} }
private void initCountry() { private void initCountry() {
regionComboBox.setItems(presentationModel.getAllRegions()); regionComboBox.setItems(model.getAllRegions());
regionComboBox.setConverter(new StringConverter<io.bitsquare.locale.Region>() { regionComboBox.setConverter(new StringConverter<io.bitsquare.locale.Region>() {
@Override @Override
public String toString(io.bitsquare.locale.Region region) { public String toString(io.bitsquare.locale.Region region) {
@ -361,33 +312,15 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
} }
private void removeLanguage(Locale locale) { private void removeLanguage(Locale locale) {
presentationModel.removeLanguage(locale); model.removeLanguage(locale);
} }
private void removeCountry(Country country) { private void removeCountry(Country country) {
presentationModel.removeCountry(country); model.removeCountry(country);
} }
private void removeArbitrator(Arbitrator arbitrator) { private void removeArbitrator(Arbitrator arbitrator) {
presentationModel.removeArbitrator(arbitrator); model.removeArbitrator(arbitrator);
} }
/* private void addCountry(Country country) {
if (!countryList.contains(country) && country != null) {
countryList.add(country);
settings.addAcceptedCountry(country);
saveSettings();
}
}*/
/* private void addLanguage(Locale locale) {
if (locale != null && !languageList.contains(locale)) {
languageList.add(locale);
settings.addAcceptedLanguageLocale(locale);
}
}*/
} }

View file

@ -0,0 +1,119 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.Region;
import com.google.inject.Inject;
import java.util.Locale;
import viewfx.model.ViewModel;
import viewfx.model.support.ActivatableWithDelegate;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
class RestrictionsViewModel extends ActivatableWithDelegate<RestrictionsDataModel> implements ViewModel {
final BooleanProperty doneButtonDisable = new SimpleBooleanProperty(true);
@Inject
public RestrictionsViewModel(RestrictionsDataModel delegate) {
super(delegate);
}
@Override
public void doActivate() {
updateDoneButtonDisableState();
}
void addLanguage(Locale locale) {
delegate.addLanguage(locale);
updateDoneButtonDisableState();
}
void removeLanguage(Locale locale) {
delegate.removeLanguage(locale);
updateDoneButtonDisableState();
}
void addCountry(Country country) {
delegate.addCountry(country);
updateDoneButtonDisableState();
}
void removeCountry(Country country) {
delegate.removeCountry(country);
updateDoneButtonDisableState();
}
void removeArbitrator(Arbitrator arbitrator) {
delegate.removeArbitrator(arbitrator);
updateDoneButtonDisableState();
}
void updateArbitratorList() {
delegate.updateArbitratorList();
updateDoneButtonDisableState();
}
ObservableList<Country> getListWithAllEuroCountries() {
return delegate.getListWithAllEuroCountries();
}
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return delegate.getAllCountriesFor(selectedRegion);
}
ObservableList<Locale> getLanguageList() {
return delegate.languageList;
}
ObservableList<Region> getAllRegions() {
return delegate.allRegions;
}
ObservableList<Locale> getAllLanguages() {
return delegate.allLanguages;
}
ObservableList<Country> getCountryList() {
return delegate.countryList;
}
ObservableList<Arbitrator> getArbitratorList() {
return delegate.arbitratorList;
}
//TODO Revert size() > -1 to 0(2 later). For mock testing disabled arbitratorList test
private void updateDoneButtonDisableState() {
boolean isValid = delegate.languageList != null && delegate.languageList.size() > 0 &&
delegate.countryList != null && delegate.countryList.size() > 0 &&
delegate.arbitratorList != null && delegate.arbitratorList.size() > -1;
doneButtonDisable.set(!isValid);
}
}

View file

@ -1,83 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class SeedWordsModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(SeedWordsModel.class);
private List<String> mnemonicCode;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private SeedWordsModel(WalletService walletService) {
if (walletService != null && walletService.getWallet() != null)
mnemonicCode = walletService.getWallet().getKeyChainSeed().getMnemonicCode();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getter
///////////////////////////////////////////////////////////////////////////////////////////
List<String> getMnemonicCode() {
return mnemonicCode;
}
}

View file

@ -1,80 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.BSFormatter;
import com.google.inject.Inject;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class SeedWordsPM extends PresentationModel<SeedWordsModel> {
private static final Logger log = LoggerFactory.getLogger(SeedWordsPM.class);
final StringProperty seedWords = new SimpleStringProperty();
private final BSFormatter formatter;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private SeedWordsPM(SeedWordsModel model, BSFormatter formatter) {
super(model);
this.formatter = formatter;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize() {
super.initialize();
if (model.getMnemonicCode() != null)
seedWords.set(formatter.mnemonicCodeToString(model.getMnemonicCode()));
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
}

View file

@ -23,7 +23,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?> <?import javafx.scene.text.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.seedwords.SeedWordsViewCB" hgap="5.0" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.seedwords.SeedWordsView" hgap="5.0"
vgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"

View file

@ -0,0 +1,71 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
@FxmlView
public class SeedWordsView extends InitializableView<GridPane, SeedWordsViewModel> implements Wizard.Step {
@FXML Button completedButton;
@FXML TextArea seedWordsTextArea;
private Wizard parent;
@Inject
private SeedWordsView(SeedWordsViewModel model) {
super(model);
}
@Override
public void initialize() {
seedWordsTextArea.setText(model.seedWords.get());
}
@Override
public void setParent(Wizard parent) {
this.parent = parent;
}
@Override
public void hideWizardNavigation() {
root.getChildren().remove(completedButton);
}
@FXML
private void onCompleted() {
parent.nextStep(this);
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_SEED_WORDS);
}
}

View file

@ -1,113 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SeedWordsViewCB extends CachedViewCB<SeedWordsPM> implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(SeedWordsViewCB.class);
@FXML Button completedButton;
@FXML TextArea seedWordsTextArea;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private SeedWordsViewCB(SeedWordsPM presentationModel) {
super(presentationModel);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
seedWordsTextArea.setText(presentationModel.seedWords.get());
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void useSettingsContext(boolean useSettingsContext) {
if (useSettingsContext)
((GridPane) root).getChildren().remove(completedButton);
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
private void onCompleted() {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
@FXML
private void onOpenHelp() {
Help.openWindow(HelpId.SETUP_SEED_WORDS);
}
}

View file

@ -0,0 +1,45 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.util.BSFormatter;
import com.google.inject.Inject;
import java.util.List;
import viewfx.model.ViewModel;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
class SeedWordsViewModel implements ViewModel {
final StringProperty seedWords = new SimpleStringProperty();
@Inject
public SeedWordsViewModel(WalletService walletService, BSFormatter formatter) {
if (walletService.getWallet() != null) {
List<String> mnemonicCode = walletService.getWallet().getKeyChainSeed().getMnemonicCode();
if (mnemonicCode != null) {
seedWords.set(formatter.mnemonicCodeToString(mnemonicCode));
}
}
}
}

View file

@ -19,7 +19,7 @@
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.settings.AccountSettingsViewCB" <AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.settings.AccountSettingsView"
prefHeight="660.0" prefWidth="1000.0" prefHeight="660.0" prefWidth="1000.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -0,0 +1,172 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.settings;
import io.bitsquare.BitsquareException;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.account.content.changepassword.ChangePasswordView;
import io.bitsquare.gui.main.account.content.irc.IrcAccountView;
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
import io.bitsquare.gui.util.Colors;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.ViewPath;
import viewfx.view.Wizard;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
@FxmlView
public class AccountSettingsView extends ActivatableViewAndModel {
private final ViewLoader viewLoader;
private final Navigation navigation;
private MenuItem seedWords, password, restrictions, ircAccount, registration;
private Navigation.Listener listener;
@FXML private VBox leftVBox;
@FXML private AnchorPane content;
@Inject
private AccountSettingsView(ViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader;
this.navigation = navigation;
}
@Override
public void initialize() {
listener = viewPath -> {
if (viewPath.size() != 4 || viewPath.indexOf(AccountSettingsView.class) != 2)
return;
loadView(viewPath.tip());
};
ToggleGroup toggleGroup = new ToggleGroup();
seedWords = new MenuItem(navigation, toggleGroup, "Wallet seed", SeedWordsView.class);
password = new MenuItem(navigation, toggleGroup, "Wallet password", ChangePasswordView.class);
restrictions = new MenuItem(navigation, toggleGroup, "Arbitrator selection", RestrictionsView.class);
ircAccount = new MenuItem(navigation, toggleGroup, "Payments account(s)", IrcAccountView.class);
registration = new MenuItem(navigation, toggleGroup, "Renew your account", RegistrationView.class);
seedWords.setDisable(true);
password.setDisable(true);
restrictions.setDisable(true);
registration.setDisable(true);
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
}
@Override
public void doActivate() {
navigation.addListener(listener);
ViewPath viewPath = navigation.getCurrentPath();
if (viewPath.size() == 3 && viewPath.indexOf(AccountSettingsView.class) == 2) {
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, IrcAccountView.class);
}
else if (viewPath.size() == 4 && viewPath.indexOf(AccountSettingsView.class) == 2) {
loadView(viewPath.get(3));
}
}
@Override
public void doDeactivate() {
navigation.removeListener(listener);
}
private void loadView(Class<? extends View> viewClass) {
View view = viewLoader.load(viewClass);
content.getChildren().setAll(view.getRoot());
if (view instanceof Wizard.Step)
((Wizard.Step) view).hideWizardNavigation();
if (view instanceof SeedWordsView) seedWords.setSelected(true);
else if (view instanceof ChangePasswordView) password.setSelected(true);
else if (view instanceof RestrictionsView) restrictions.setSelected(true);
else if (view instanceof IrcAccountView) ircAccount.setSelected(true);
else if (view instanceof RegistrationView) registration.setSelected(true);
else throw new BitsquareException("Selecting main menu button for view " + view + " is not supported");
}
}
class MenuItem extends ToggleButton {
MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class<? extends View> viewClass) {
setToggleGroup(toggleGroup);
setText(title);
setId("account-settings-item-background-active");
setPrefHeight(40);
setPrefWidth(200);
setAlignment(Pos.CENTER_LEFT);
Label icon = new Label();
icon.setTextFill(Paint.valueOf("#999"));
if (viewClass == SeedWordsView.class)
AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN);
else if (viewClass == RegistrationView.class)
AwesomeDude.setIcon(icon, AwesomeIcon.BRIEFCASE);
else
AwesomeDude.setIcon(icon, AwesomeIcon.EDIT_SIGN);
setGraphic(icon);
setOnAction((event) ->
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, viewClass));
selectedProperty().addListener((ov, oldValue, newValue) -> {
if (newValue) {
setId("account-settings-item-background-selected");
icon.setTextFill(Colors.BLUE);
}
else {
setId("account-settings-item-background-active");
icon.setTextFill(Paint.valueOf("#999"));
}
});
disableProperty().addListener((ov, oldValue, newValue) -> {
if (newValue) {
setId("account-settings-item-background-disabled");
icon.setTextFill(Paint.valueOf("#ccc"));
}
else {
setId("account-settings-item-background-active");
icon.setTextFill(Paint.valueOf("#999"));
}
});
}
}

View file

@ -1,238 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.settings;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.util.Colors;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AccountSettingsViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(AccountSettingsViewCB.class);
private final ViewLoader viewLoader;
private final Navigation navigation;
private MenuItem seedWords, password, restrictions, fiatAccount, registration;
private Navigation.Listener listener;
@FXML private VBox leftVBox;
@FXML private AnchorPane content;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountSettingsViewCB(ViewLoader viewLoader, Navigation navigation) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
listener = navigationItems -> {
if (navigationItems != null &&
navigationItems.length == 4 &&
navigationItems[2] == Navigation.Item.ACCOUNT_SETTINGS) {
loadView(navigationItems[3]);
selectMainMenuButton(navigationItems[3]);
}
};
ToggleGroup toggleGroup = new ToggleGroup();
seedWords = new MenuItem(navigation, "Wallet seed",
Navigation.Item.SEED_WORDS, toggleGroup);
password = new MenuItem(navigation, "Wallet password",
Navigation.Item.CHANGE_PASSWORD, toggleGroup);
restrictions = new MenuItem(navigation, "Arbitrator selection",
Navigation.Item.RESTRICTIONS, toggleGroup);
fiatAccount = new MenuItem(navigation, "Payments account(s)",
Navigation.Item.FIAT_ACCOUNT, toggleGroup);
registration = new MenuItem(navigation, "Renew your account",
Navigation.Item.REGISTRATION, toggleGroup);
seedWords.setDisable(true);
password.setDisable(true);
restrictions.setDisable(true);
registration.setDisable(true);
leftVBox.getChildren().addAll(seedWords, password,
restrictions, fiatAccount, registration);
super.initialize(url, rb);
}
@Override
public void activate() {
super.activate();
navigation.addListener(listener);
Navigation.Item[] items = navigation.getCurrentItems();
if (items.length == 3 &&
items[2] == Navigation.Item.ACCOUNT_SETTINGS) {
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETTINGS, Navigation.Item.FIAT_ACCOUNT);
}
else {
if (items.length == 4 &&
items[2] == Navigation.Item.ACCOUNT_SETTINGS) {
loadView(items[3]);
selectMainMenuButton(items[3]);
}
}
}
@Override
public void deactivate() {
super.deactivate();
navigation.removeListener(listener);
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
content.getChildren().setAll(loaded.view);
childController = loaded.controller;
((ViewCB<? extends PresentationModel>) childController).setParent(this);
((ContextAware) childController).useSettingsContext(true);
return childController;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void selectMainMenuButton(Navigation.Item item) {
switch (item) {
case SEED_WORDS:
seedWords.setSelected(true);
break;
case CHANGE_PASSWORD:
password.setSelected(true);
break;
case RESTRICTIONS:
restrictions.setSelected(true);
break;
case FIAT_ACCOUNT:
fiatAccount.setSelected(true);
break;
case REGISTRATION:
registration.setSelected(true);
break;
default:
log.error(item.getFxmlUrl() + " is invalid");
break;
}
}
}
class MenuItem extends ToggleButton {
private static final Logger log = LoggerFactory.getLogger(MenuItem.class);
MenuItem(Navigation navigation, String title, Navigation.Item navigationItem,
ToggleGroup toggleGroup) {
setToggleGroup(toggleGroup);
setText(title);
setId("account-settings-item-background-active");
setPrefHeight(40);
setPrefWidth(200);
setAlignment(Pos.CENTER_LEFT);
Label icon = new Label();
icon.setTextFill(Paint.valueOf("#999"));
if (navigationItem.equals(Navigation.Item.SEED_WORDS))
AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN);
else if (navigationItem.equals(Navigation.Item.REGISTRATION))
AwesomeDude.setIcon(icon, AwesomeIcon.BRIEFCASE);
else
AwesomeDude.setIcon(icon, AwesomeIcon.EDIT_SIGN);
setGraphic(icon);
setOnAction((event) -> navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETTINGS, navigationItem));
selectedProperty().addListener((ov, oldValue, newValue) -> {
if (newValue) {
setId("account-settings-item-background-selected");
icon.setTextFill(Colors.BLUE);
}
else {
setId("account-settings-item-background-active");
icon.setTextFill(Paint.valueOf("#999"));
}
});
disableProperty().addListener((ov, oldValue, newValue) -> {
if (newValue) {
setId("account-settings-item-background-disabled");
icon.setTextFill(Paint.valueOf("#ccc"));
}
else {
setId("account-settings-item-background-active");
icon.setTextFill(Paint.valueOf("#999"));
}
});
}
}

View file

@ -1,272 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.setup;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.account.content.irc.IrcAccountViewCB;
import io.bitsquare.gui.main.account.content.password.PasswordViewCB;
import io.bitsquare.gui.main.account.content.registration.RegistrationViewCB;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsViewCB;
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsViewCB;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This UI is not cached as it is normally only needed once.
*/
public class AccountSetupViewCB extends ViewCB implements MultiStepNavigation {
private static final Logger log = LoggerFactory.getLogger(AccountSetupViewCB.class);
private WizardItem seedWords, password, fiatAccount, restrictions, registration;
private Navigation.Listener listener;
@FXML VBox leftVBox;
@FXML AnchorPane content;
private final ViewLoader viewLoader;
private final Navigation navigation;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountSetupViewCB(ViewLoader viewLoader, Navigation navigation) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
listener = navigationItems -> {
if (navigationItems != null &&
navigationItems.length == 4 &&
navigationItems[2] == Navigation.Item.ACCOUNT_SETUP) {
switch (navigationItems[3]) {
case SEED_WORDS:
childController = seedWords.show();
break;
case ADD_PASSWORD:
seedWords.onCompleted();
childController = password.show();
break;
case RESTRICTIONS:
seedWords.onCompleted();
password.onCompleted();
childController = restrictions.show();
break;
case FIAT_ACCOUNT:
seedWords.onCompleted();
password.onCompleted();
restrictions.onCompleted();
childController = fiatAccount.show();
break;
case REGISTRATION:
seedWords.onCompleted();
password.onCompleted();
restrictions.onCompleted();
fiatAccount.onCompleted();
childController = registration.show();
break;
}
}
};
seedWords = new WizardItem(this, "Backup wallet seed", "Write down the seed word for your wallet",
Navigation.Item.SEED_WORDS);
password = new WizardItem(this, "Setup password", "Protect your wallet with a password",
Navigation.Item.ADD_PASSWORD);
restrictions = new WizardItem(this, "Select arbitrators",
"Select which arbitrators you want to use for trading",
Navigation.Item.RESTRICTIONS);
fiatAccount = new WizardItem(this, " Setup Payments account(s)",
"You need to setup at least one payment account",
Navigation.Item.FIAT_ACCOUNT);
registration = new WizardItem(this, "Register your account",
"The registration in the Blockchain requires a payment of 0.0002 BTC",
Navigation.Item.REGISTRATION);
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
seedWords.setDisable(true);
password.setDisable(true);
restrictions.setDisable(true);
registration.setDisable(true);
super.initialize(url, rb);
navigation.addListener(listener);
childController = fiatAccount.show();
}
@Override
public void terminate() {
super.terminate();
navigation.removeListener(listener);
}
///////////////////////////////////////////////////////////////////////////////////////////
// MultiStepNavigation implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void nextStep(ViewCB<? extends PresentationModel> childView) {
if (childView instanceof SeedWordsViewCB) {
seedWords.onCompleted();
childController = password.show();
}
else if (childView instanceof PasswordViewCB) {
password.onCompleted();
childController = restrictions.show();
}
else if (childView instanceof RestrictionsViewCB) {
restrictions.onCompleted();
childController = fiatAccount.show();
}
else if (childView instanceof IrcAccountViewCB) {
fiatAccount.onCompleted();
childController = registration.show();
}
else if (childView instanceof RegistrationViewCB) {
registration.onCompleted();
childController = null;
if (navigation.getItemsForReturning() != null)
navigation.navigationTo(navigation.getItemsForReturning());
else
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.BUY);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
content.getChildren().setAll(loaded.view);
childController = loaded.controller;
((ViewCB<? extends PresentationModel>) childController).setParent(this);
((ContextAware) childController).useSettingsContext(false);
return childController;
}
}
class WizardItem extends HBox {
private static final Logger log = LoggerFactory.getLogger(WizardItem.class);
private ViewCB<? extends PresentationModel> childController;
private final ImageView imageView;
private final Label titleLabel;
private final Label subTitleLabel;
private final AccountSetupViewCB host;
private final Navigation.Item navigationItem;
WizardItem(AccountSetupViewCB host, String title, String subTitle,
Navigation.Item navigationItem) {
this.host = host;
this.navigationItem = navigationItem;
setId("wizard-item-background-deactivated");
setSpacing(5);
setPrefWidth(200);
imageView = new ImageView();
imageView.setId("image-arrow-grey");
imageView.setFitHeight(15);
imageView.setFitWidth(20);
imageView.setPickOnBounds(true);
imageView.setMouseTransparent(true);
HBox.setMargin(imageView, new Insets(8, 0, 0, 8));
titleLabel = new Label(title);
titleLabel.setId("wizard-title-deactivated");
titleLabel.setLayoutX(7);
titleLabel.setMouseTransparent(true);
subTitleLabel = new Label(subTitle);
subTitleLabel.setId("wizard-sub-title-deactivated");
subTitleLabel.setLayoutX(40);
subTitleLabel.setLayoutY(33);
subTitleLabel.setMaxWidth(250);
subTitleLabel.setWrapText(true);
subTitleLabel.setMouseTransparent(true);
final VBox vBox = new VBox();
vBox.setSpacing(1);
HBox.setMargin(vBox, new Insets(5, 0, 8, 0));
vBox.setMouseTransparent(true);
vBox.getChildren().addAll(titleLabel, subTitleLabel);
getChildren().addAll(imageView, vBox);
}
ViewCB<? extends PresentationModel> show() {
host.loadView(navigationItem);
/* navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT, Navigation
.Item.ACCOUNT_SETUP,
navigationItem);*/
setId("wizard-item-background-active");
imageView.setId("image-arrow-blue");
titleLabel.setId("wizard-title-active");
subTitleLabel.setId("wizard-sub-title-active");
return childController;
}
void onCompleted() {
setId("wizard-item-background-completed");
imageView.setId("image-tick");
titleLabel.setId("wizard-title-completed");
subTitleLabel.setId("wizard-sub-title-completed");
}
}

View file

@ -19,7 +19,7 @@
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.setup.AccountSetupViewCB" <AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.setup.AccountSetupWizard"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
<VBox fx:id="leftVBox" spacing="5" prefWidth="300" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="15" <VBox fx:id="leftVBox" spacing="5" prefWidth="300" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="15"

View file

@ -0,0 +1,223 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.setup;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.content.irc.IrcAccountView;
import io.bitsquare.gui.main.account.content.password.PasswordView;
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
import io.bitsquare.gui.main.trade.BuyView;
import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.Wizard;
import viewfx.view.support.ActivatableView;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
@FxmlView
public class AccountSetupWizard extends ActivatableView implements Wizard {
@FXML VBox leftVBox;
@FXML AnchorPane content;
private WizardItem seedWords, password, ircAccount, restrictions, registration;
private Navigation.Listener listener;
private final ViewLoader viewLoader;
private final Navigation navigation;
@Inject
private AccountSetupWizard(ViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader;
this.navigation = navigation;
}
@Override
public void initialize() {
listener = viewPath -> {
if (viewPath.size() != 4 || !viewPath.contains(this.getClass()))
return;
Class<? extends View> viewClass = viewPath.tip();
if (viewClass == SeedWordsView.class) {
seedWords.show();
}
else if (viewClass == PasswordView.class) {
seedWords.onCompleted();
password.show();
}
else if (viewClass == RestrictionsView.class) {
seedWords.onCompleted();
password.onCompleted();
restrictions.show();
}
else if (viewClass == IrcAccountView.class) {
seedWords.onCompleted();
password.onCompleted();
restrictions.onCompleted();
ircAccount.show();
}
else if (viewClass == RegistrationView.class) {
seedWords.onCompleted();
password.onCompleted();
restrictions.onCompleted();
ircAccount.onCompleted();
registration.show();
}
};
seedWords = new WizardItem(SeedWordsView.class,
"Backup wallet seed", "Write down the seed word for your wallet");
password = new WizardItem(PasswordView.class,
"Setup password", "Protect your wallet with a password");
restrictions = new WizardItem(RestrictionsView.class,
"Select arbitrators", "Select which arbitrators you want to use for trading");
ircAccount = new WizardItem(IrcAccountView.class,
" Setup Payments account(s)", "You need to setup at least one payment account");
registration = new WizardItem(RegistrationView.class,
"Register your account", "The registration in the Blockchain requires a payment of 0.0002 BTC");
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
seedWords.setDisable(true);
password.setDisable(true);
restrictions.setDisable(true);
registration.setDisable(true);
}
@Override
public void activate() {
navigation.addListener(listener);
ircAccount.show();
}
@Override
public void deactivate() {
navigation.removeListener(listener);
}
@Override
public void nextStep(Step currentStep) {
if (currentStep instanceof SeedWordsView) {
seedWords.onCompleted();
password.show();
}
else if (currentStep instanceof PasswordView) {
password.onCompleted();
restrictions.show();
}
else if (currentStep instanceof RestrictionsView) {
restrictions.onCompleted();
ircAccount.show();
}
else if (currentStep instanceof IrcAccountView) {
ircAccount.onCompleted();
registration.show();
}
else if (currentStep instanceof RegistrationView) {
registration.onCompleted();
if (navigation.getReturnPath() != null)
navigation.navigateTo(navigation.getReturnPath());
else
navigation.navigateTo(MainView.class, BuyView.class);
}
}
protected void loadView(Class<? extends View> viewClass) {
View view = viewLoader.load(viewClass);
content.getChildren().setAll(view.getRoot());
if (view instanceof Wizard.Step)
((Step) view).setParent(this);
}
private class WizardItem extends HBox {
private final ImageView imageView;
private final Label titleLabel;
private final Label subTitleLabel;
private final Class<? extends View> viewClass;
WizardItem(Class<? extends View> viewClass, String title, String subTitle) {
this.viewClass = viewClass;
setId("wizard-item-background-deactivated");
setSpacing(5);
setPrefWidth(200);
imageView = new ImageView();
imageView.setId("image-arrow-grey");
imageView.setFitHeight(15);
imageView.setFitWidth(20);
imageView.setPickOnBounds(true);
imageView.setMouseTransparent(true);
HBox.setMargin(imageView, new Insets(8, 0, 0, 8));
titleLabel = new Label(title);
titleLabel.setId("wizard-title-deactivated");
titleLabel.setLayoutX(7);
titleLabel.setMouseTransparent(true);
subTitleLabel = new Label(subTitle);
subTitleLabel.setId("wizard-sub-title-deactivated");
subTitleLabel.setLayoutX(40);
subTitleLabel.setLayoutY(33);
subTitleLabel.setMaxWidth(250);
subTitleLabel.setWrapText(true);
subTitleLabel.setMouseTransparent(true);
final VBox vBox = new VBox();
vBox.setSpacing(1);
HBox.setMargin(vBox, new Insets(5, 0, 8, 0));
vBox.setMouseTransparent(true);
vBox.getChildren().addAll(titleLabel, subTitleLabel);
getChildren().addAll(imageView, vBox);
}
void show() {
loadView(viewClass);
setId("wizard-item-background-active");
imageView.setId("image-arrow-blue");
titleLabel.setId("wizard-title-active");
subTitleLabel.setId("wizard-sub-title-active");
}
void onCompleted() {
setId("wizard-item-background-completed");
imageView.setId("image-tick");
titleLabel.setId("wizard-title-completed");
subTitleLabel.setId("wizard-sub-title-completed");
}
}
}

View file

@ -18,7 +18,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.funds.FundsViewCB" <TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.funds.FundsView"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0" AnchorPane.topAnchor="0.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -0,0 +1,101 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
import javax.inject.Inject;
import viewfx.model.Activatable;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.*;
@FxmlView
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab withdrawalTab, transactionsTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
private Tab currentTab;
private final ViewLoader viewLoader;
private final Navigation navigation;
@Inject
public FundsView(ViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader;
this.navigation = navigation;
}
@Override
public void initialize() {
navigationListener = viewPath -> {
if (viewPath.size() == 3 && viewPath.indexOf(FundsView.class) == 1)
loadView(viewPath.tip());
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == withdrawalTab)
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (newValue == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
};
}
@Override
public void doActivate() {
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
else
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
}
@Override
public void doDeactivate() {
root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
navigation.removeListener(navigationListener);
}
private void loadView(Class<? extends View> viewClass) {
// we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null)
currentTab.setContent(null);
View view = viewLoader.load(viewClass);
if (view instanceof WithdrawalView) currentTab = withdrawalTab;
else if (view instanceof TransactionsView) currentTab = transactionsTab;
currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab);
}
}

View file

@ -1,135 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.scene.control.*;
public class FundsViewCB extends CachedViewCB {
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
private Tab currentTab;
@FXML Tab withdrawalTab, transactionsTab;
private final ViewLoader viewLoader;
private final Navigation navigation;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
FundsViewCB(ViewLoader viewLoader, Navigation navigation) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
navigationListener = navigationItems -> {
if (navigationItems != null && navigationItems.length == 3
&& navigationItems[1] == Navigation.Item.FUNDS)
loadView(navigationItems[2]);
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == withdrawalTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.FUNDS, Navigation.Item.WITHDRAWAL);
else if (newValue == transactionsTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.FUNDS, Navigation.Item.TRANSACTIONS);
};
super.initialize(url, rb);
}
@Override
public void activate() {
super.activate();
((TabPane) root).getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (((TabPane) root).getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.FUNDS, Navigation.Item.TRANSACTIONS);
else
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.FUNDS, Navigation.Item.WITHDRAWAL);
}
@Override
public void deactivate() {
super.deactivate();
((TabPane) root).getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
navigation.removeListener(navigationListener);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
super.loadView(navigationItem);
// we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null)
currentTab.setContent(null);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
switch (navigationItem) {
case WITHDRAWAL:
currentTab = withdrawalTab;
break;
case TRANSACTIONS:
currentTab = transactionsTab;
break;
}
currentTab.setContent(loaded.view);
((TabPane) root).getSelectionModel().select(currentTab);
Initializable childController = loaded.controller;
((ViewCB) childController).setParent(this);
return childController;
}
}

View file

@ -32,11 +32,8 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.scene.control.*; import javafx.scene.control.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransactionsListItem { public class TransactionsListItem {
private static final Logger log = LoggerFactory.getLogger(TransactionsListItem.class);
private final StringProperty date = new SimpleStringProperty(); private final StringProperty date = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty(); private final StringProperty amount = new SimpleStringProperty();
private final StringProperty type = new SimpleStringProperty(); private final StringProperty type = new SimpleStringProperty();

View file

@ -21,7 +21,7 @@
<?import javafx.scene.control.cell.*?> <?import javafx.scene.control.cell.*?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.transactions.TransactionsViewCB" <VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.transactions.TransactionsView"
spacing="10" xmlns:fx="http://javafx.com/fxml"> spacing="10" xmlns:fx="http://javafx.com/fxml">
<padding> <padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>

View file

@ -18,20 +18,19 @@
package io.bitsquare.gui.main.funds.transactions; package io.bitsquare.gui.main.funds.transactions;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import org.bitcoinj.core.Transaction; import org.bitcoinj.core.Transaction;
import java.net.URL;
import java.util.List; import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -39,40 +38,26 @@ import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.util.Callback; import javafx.util.Callback;
import org.slf4j.Logger; @FxmlView
import org.slf4j.LoggerFactory; public class TransactionsView extends ActivatableViewAndModel {
public class TransactionsViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(TransactionsViewCB.class);
private final WalletService walletService;
private final BSFormatter formatter;
private ObservableList<TransactionsListItem> transactionsListItems;
@FXML TableView<TransactionsListItem> table; @FXML TableView<TransactionsListItem> table;
@FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn, @FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,
confidenceColumn; confidenceColumn;
private ObservableList<TransactionsListItem> transactionsListItems;
/////////////////////////////////////////////////////////////////////////////////////////// private final WalletService walletService;
// Constructor private final BSFormatter formatter;
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private TransactionsViewCB(WalletService walletService, BSFormatter formatter) { private TransactionsView(WalletService walletService, BSFormatter formatter) {
this.walletService = walletService; this.walletService = walletService;
this.formatter = formatter; this.formatter = formatter;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
super.initialize(url, rb);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No transactions available")); table.setPlaceholder(new Label("No transactions available"));
@ -81,9 +66,7 @@ public class TransactionsViewCB extends CachedViewCB {
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate();
List<Transaction> transactions = walletService.getWallet().getRecentTransactions(10000, true); List<Transaction> transactions = walletService.getWallet().getRecentTransactions(10000, true);
transactionsListItems = FXCollections.observableArrayList(); transactionsListItems = FXCollections.observableArrayList();
transactionsListItems.addAll(transactions.stream().map(transaction -> transactionsListItems.addAll(transactions.stream().map(transaction ->
@ -93,23 +76,11 @@ public class TransactionsViewCB extends CachedViewCB {
} }
@Override @Override
public void deactivate() { public void doDeactivate() {
super.deactivate();
for (TransactionsListItem transactionsListItem : transactionsListItems) for (TransactionsListItem transactionsListItem : transactionsListItems)
transactionsListItem.cleanup(); transactionsListItem.cleanup();
} }
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void openTxDetails(TransactionsListItem item) { private void openTxDetails(TransactionsListItem item) {
// TODO Open popup with details view // TODO Open popup with details view
log.debug("openTxDetails " + item); log.debug("openTxDetails " + item);
@ -118,11 +89,6 @@ public class TransactionsViewCB extends CachedViewCB {
"This will open a details popup but that is not implemented yet."); "This will open a details popup but that is not implemented yet.");
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Cell factories
///////////////////////////////////////////////////////////////////////////////////////////
private void setAddressColumnCellFactory() { private void setAddressColumnCellFactory() {
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue())); addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
addressColumn.setCellFactory( addressColumn.setCellFactory(
@ -182,6 +148,5 @@ public class TransactionsViewCB extends CachedViewCB {
} }
}); });
} }
} }

View file

@ -21,7 +21,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?> <?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.withdrawal.WithdrawalViewCB" <VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.withdrawal.WithdrawalView"
spacing="10" xmlns:fx="http://javafx.com/fxml"> spacing="10" xmlns:fx="http://javafx.com/fxml">
<padding> <padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>

View file

@ -22,7 +22,6 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.Restrictions; import io.bitsquare.btc.Restrictions;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener; import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
@ -34,14 +33,14 @@ import org.bitcoinj.core.Transaction;
import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.FutureCallback;
import java.net.URL;
import java.util.List; import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -56,40 +55,28 @@ import org.controlsfx.control.action.Action;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; @FxmlView
import org.slf4j.LoggerFactory; public class WithdrawalView extends ActivatableViewAndModel {
public class WithdrawalViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(WithdrawalViewCB.class);
@FXML TableView<WithdrawalListItem> table;
@FXML Button addNewAddressButton;
@FXML TextField withdrawFromTextField, withdrawToTextField, amountTextField;
@FXML TableColumn<WithdrawalListItem, WithdrawalListItem> labelColumn, addressColumn, balanceColumn, copyColumn,
confidenceColumn;
private final WalletService walletService; private final WalletService walletService;
private final BSFormatter formatter; private final BSFormatter formatter;
private final ObservableList<WithdrawalListItem> addressList = FXCollections.observableArrayList(); private final ObservableList<WithdrawalListItem> addressList = FXCollections.observableArrayList();
@FXML TableView<WithdrawalListItem> table;
@FXML TableColumn<WithdrawalListItem, WithdrawalListItem> labelColumn, addressColumn, balanceColumn, copyColumn,
confidenceColumn;
@FXML Button addNewAddressButton;
@FXML TextField withdrawFromTextField, withdrawToTextField, amountTextField;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private WithdrawalViewCB(WalletService walletService, BSFormatter formatter) { private WithdrawalView(WalletService walletService, BSFormatter formatter) {
this.walletService = walletService; this.walletService = walletService;
this.formatter = formatter; this.formatter = formatter;
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize() {
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No funded wallets for withdrawal available")); table.setPlaceholder(new Label("No funded wallets for withdrawal available"));
@ -97,14 +84,10 @@ public class WithdrawalViewCB extends CachedViewCB {
setBalanceColumnCellFactory(); setBalanceColumnCellFactory();
setCopyColumnCellFactory(); setCopyColumnCellFactory();
setConfidenceColumnCellFactory(); setConfidenceColumnCellFactory();
super.initialize(url, rb);
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate();
table.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> { table.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
@ -133,24 +116,11 @@ public class WithdrawalViewCB extends CachedViewCB {
} }
@Override @Override
public void deactivate() { public void doDeactivate() {
super.deactivate();
for (WithdrawalListItem item : addressList) for (WithdrawalListItem item : addressList)
item.cleanup(); item.cleanup();
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
@FXML @FXML
public void onWithdraw() { public void onWithdraw() {
Coin amount = formatter.parseToCoin(amountTextField.getText()); Coin amount = formatter.parseToCoin(amountTextField.getText());
@ -207,11 +177,6 @@ public class WithdrawalViewCB extends CachedViewCB {
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void fillList() { private void fillList() {
addressList.clear(); addressList.clear();
List<AddressEntry> addressEntryList = walletService.getAddressEntryList(); List<AddressEntry> addressEntryList = walletService.getAddressEntryList();
@ -221,10 +186,6 @@ public class WithdrawalViewCB extends CachedViewCB {
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
///////////////////////////////////////////////////////////////////////////////////////////
// Cell factories
///////////////////////////////////////////////////////////////////////////////////////////
private void setLabelColumnCellFactory() { private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue())); labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<WithdrawalListItem, WithdrawalListItem>, labelColumn.setCellFactory(new Callback<TableColumn<WithdrawalListItem, WithdrawalListItem>,

View file

@ -20,7 +20,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.home.HomeViewCB" <TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.home.HomeView"
AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -0,0 +1,27 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.home;
import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView;
// home is just hosting the arbiters buttons yet, but that's just for dev, not clear yet what will be in home,
// probably overview, event history, news, charts,... -> low prio
@FxmlView
public class HomeView extends AbstractView {
}

View file

@ -1,64 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.home;
import io.bitsquare.gui.CachedViewCB;
import java.net.URL;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// home is just hosting the arbiters buttons yet, but that's just for dev, not clear yet what will be in home,
// probably overview, event history, news, charts,... -> low prio
public class HomeViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(HomeViewCB.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
}

View file

@ -20,7 +20,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.msg.MsgViewCB" <TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.msg.MsgView"
AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -15,15 +15,13 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>. * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/ */
package io.bitsquare.gui.main.trade; package io.bitsquare.gui.main.msg;
import io.bitsquare.offer.Offer; import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView;
import org.bitcoinj.core.Coin; // will be probably only used for arbitration communication, will be renamed and the icon changed
import org.bitcoinj.utils.Fiat; @FxmlView
public class MsgView extends AbstractView {
public interface TradeNavigator {
void createOffer(Coin amount, Fiat price);
void takeOffer(Coin amount, Fiat price, Offer offer);
} }

View file

@ -1,99 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.msg;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.fxml.Initializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// will be probably only used for arbitration communication, will be renamed and the icon changed
public class MsgViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(MsgViewCB.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private MsgViewCB() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
return super.loadView(navigationItem);
}
///////////////////////////////////////////////////////////////////////////////////////////
// GUI Event handlers
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
}

View file

@ -19,7 +19,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.PortfolioViewCB" <TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.PortfolioView"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" tabClosingPolicy="UNAVAILABLE"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -0,0 +1,109 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.portfolio.closed.ClosedTradesView;
import io.bitsquare.gui.main.portfolio.offer.OffersView;
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
import io.bitsquare.trade.TradeManager;
import javax.inject.Inject;
import viewfx.model.Activatable;
import viewfx.view.FxmlView;
import viewfx.view.View;
import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.*;
@FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab offersTab, openTradesTab, closedTradesTab;
private Tab currentTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
private final ViewLoader viewLoader;
private final Navigation navigation;
private final TradeManager tradeManager;
@Inject
public PortfolioView(ViewLoader viewLoader, Navigation navigation, TradeManager tradeManager) {
this.viewLoader = viewLoader;
this.navigation = navigation;
this.tradeManager = tradeManager;
}
@Override
public void initialize() {
navigationListener = viewPath -> {
if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
loadView(viewPath.tip());
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == offersTab)
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else if (newValue == openTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
else if (newValue == closedTradesTab)
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
};
}
@Override
public void doActivate() {
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (tradeManager.getPendingTrades().size() == 0)
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
}
@Override
public void doDeactivate() {
root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
navigation.removeListener(navigationListener);
currentTab = null;
}
private void loadView(Class<? extends View> viewClass) {
// we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null)
currentTab.setContent(null);
View view = viewLoader.load(viewClass);
if (view instanceof OffersView) currentTab = offersTab;
else if (view instanceof PendingTradesView) currentTab = openTradesTab;
else if (view instanceof ClosedTradesView) currentTab = closedTradesTab;
currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab);
}
}

View file

@ -1,150 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.trade.TradeManager;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.*;
import javafx.scene.control.*;
public class PortfolioViewCB extends CachedViewCB {
private Tab currentTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
@FXML Tab offersTab, openTradesTab, closedTradesTab;
private final ViewLoader viewLoader;
private final Navigation navigation;
private final TradeManager tradeManager;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
PortfolioViewCB(ViewLoader viewLoader, Navigation navigation, TradeManager tradeManager) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
this.tradeManager = tradeManager;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb) {
navigationListener = navigationItems -> {
if (navigationItems != null && navigationItems.length == 3
&& navigationItems[1] == Navigation.Item.PORTFOLIO)
loadView(navigationItems[2]);
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == offersTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.PORTFOLIO, Navigation.Item.OFFERS);
else if (newValue == openTradesTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.PORTFOLIO,
Navigation.Item.PENDING_TRADES);
else if (newValue == closedTradesTab)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.PORTFOLIO, Navigation.Item.CLOSED_TRADES);
};
super.initialize(url, rb);
}
@Override
public void activate() {
super.activate();
((TabPane) root).getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (tradeManager.getPendingTrades().size() == 0)
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.PORTFOLIO, Navigation.Item.OFFERS);
else
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.PORTFOLIO, Navigation.Item.PENDING_TRADES);
}
@Override
public void deactivate() {
super.deactivate();
((TabPane) root).getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
navigation.removeListener(navigationListener);
currentTab = null;
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected Initializable loadView(Navigation.Item navigationItem) {
super.loadView(navigationItem);
// we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null)
currentTab.setContent(null);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl());
switch (navigationItem) {
case OFFERS:
currentTab = offersTab;
break;
case PENDING_TRADES:
currentTab = openTradesTab;
break;
case CLOSED_TRADES:
currentTab = closedTradesTab;
break;
}
currentTab.setContent(loaded.view);
((TabPane) root).getSelectionModel().select(currentTab);
Initializable childController = loaded.controller;
((ViewCB) childController).setParent(this);
return childController;
}
}

View file

@ -17,7 +17,6 @@
package io.bitsquare.gui.main.portfolio.closed; package io.bitsquare.gui.main.portfolio.closed;
import io.bitsquare.gui.UIModel;
import io.bitsquare.offer.Direction; import io.bitsquare.offer.Direction;
import io.bitsquare.offer.Offer; import io.bitsquare.offer.Offer;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
@ -26,54 +25,37 @@ import io.bitsquare.user.User;
import com.google.inject.Inject; import com.google.inject.Inject;
import viewfx.model.Activatable;
import viewfx.model.DataModel;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener; import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import org.slf4j.Logger; class ClosedTradesDataModel implements Activatable, DataModel {
import org.slf4j.LoggerFactory;
class ClosedTradesModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(ClosedTradesModel.class);
private final TradeManager tradeManager; private final TradeManager tradeManager;
private final User user; private final User user;
private final ObservableList<ClosedTradesListItem> list = FXCollections.observableArrayList(); private final ObservableList<ClosedTradesListItem> list = FXCollections.observableArrayList();
private MapChangeListener<String, Trade> mapChangeListener; private final MapChangeListener<String, Trade> mapChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public ClosedTradesModel(TradeManager tradeManager, User user) { public ClosedTradesDataModel(TradeManager tradeManager, User user) {
this.tradeManager = tradeManager; this.tradeManager = tradeManager;
this.user = user; this.user = user;
}
this.mapChangeListener = change -> {
///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize() {
mapChangeListener = change -> {
if (change.wasAdded()) if (change.wasAdded())
list.add(new ClosedTradesListItem(change.getValueAdded())); list.add(new ClosedTradesListItem(change.getValueAdded()));
else if (change.wasRemoved()) else if (change.wasRemoved())
list.removeIf(e -> e.getTrade().getId().equals(change.getValueRemoved().getId())); list.removeIf(e -> e.getTrade().getId().equals(change.getValueRemoved().getId()));
}; };
super.initialize();
} }
@Override @Override
public void activate() { public void activate() {
super.activate();
list.clear(); list.clear();
tradeManager.getClosedTrades().values().stream() tradeManager.getClosedTrades().values().stream()
.forEach(e -> list.add(new ClosedTradesListItem(e))); .forEach(e -> list.add(new ClosedTradesListItem(e)));
@ -85,22 +67,9 @@ class ClosedTradesModel extends UIModel {
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate();
tradeManager.getClosedTrades().removeListener(mapChangeListener); tradeManager.getClosedTrades().removeListener(mapChangeListener);
} }
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public ObservableList<ClosedTradesListItem> getList() { public ObservableList<ClosedTradesListItem> getList() {
return list; return list;
} }

View file

@ -19,14 +19,10 @@ package io.bitsquare.gui.main.portfolio.closed;
import io.bitsquare.trade.Trade; import io.bitsquare.trade.Trade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* We could remove that wrapper if it is not needed for additional UI only fields. * We could remove that wrapper if it is not needed for additional UI only fields.
*/ */
class ClosedTradesListItem { class ClosedTradesListItem {
private static final Logger log = LoggerFactory.getLogger(ClosedTradesListItem.class);
private final Trade trade; private final Trade trade;

View file

@ -21,7 +21,7 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.closed.ClosedTradesViewCB" <GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.closed.ClosedTradesView"
hgap="5.0" vgap="5" hgap="5.0" vgap="5"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">
<padding> <padding>

Some files were not shown because too many files have changed in this diff Show more