Refactor trade UIs to new pattern

This commit is contained in:
Manfred Karrer 2014-09-11 12:40:35 +02:00
parent 52b04206e8
commit 81129b8203
20 changed files with 340 additions and 57 deletions

View file

@ -3,7 +3,7 @@ package io.bitsquare.gui;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class UIModel<T> { public class UIModel {
private static final Logger log = LoggerFactory.getLogger(UIModel.class); private static final Logger log = LoggerFactory.getLogger(UIModel.class);
public void initialize() { public void initialize() {

View file

@ -23,7 +23,7 @@ public class ViewCB<T extends PresentationModel> implements Initializable {
//TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated //TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated
protected Initializable childController; protected Initializable childController;
//TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated //TODO Initializable has to be changed to CodeBehind<? extends PresentationModel> when all UIs are updated
protected Initializable parentController; protected Initializable parent;
@FXML protected Parent root; @FXML protected Parent root;
@ -71,13 +71,13 @@ public class ViewCB<T extends PresentationModel> implements Initializable {
} }
/** /**
* @param parentController Controller who has created this.getClass().getSimpleName() instance (via * @param parent Controller who has created this.getClass().getSimpleName() instance (via
* navigateToView/FXMLLoader). * navigateToView/FXMLLoader).
*/ */
public void setParentController(Initializable parentController) { public void setParent(Initializable parent) {
log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " + log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " +
parentController); parent);
this.parentController = parentController; this.parent = parent;
} }
/** /**

View file

@ -185,7 +185,7 @@ public class MainViewCB extends ViewCB<MainPM> {
childController = loader.getController(); childController = loader.getController();
if (childController instanceof ViewCB) if (childController instanceof ViewCB)
((ViewCB) childController).setParentController(this); ((ViewCB) childController).setParent(this);
presentationModel.setSelectedNavigationItem(navigationItem); presentationModel.setSelectedNavigationItem(navigationItem);
return childController; return childController;

View file

@ -110,7 +110,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
Pane view = loader.load(); Pane view = loader.load();
tab.setContent(view); tab.setContent(view);
Initializable childController = loader.getController(); Initializable childController = loader.getController();
((ViewCB) childController).setParentController(this); ((ViewCB) childController).setParent(this);
if (childController instanceof AccountSetupViewCB) if (childController instanceof AccountSetupViewCB)
((AccountSetupViewCB) childController).setRemoveCallBack(() -> { ((AccountSetupViewCB) childController).setRemoveCallBack(() -> {

View file

@ -107,8 +107,8 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
private void onSaved() { private void onSaved() {
boolean result = presentationModel.requestSavePassword(); boolean result = presentationModel.requestSavePassword();
if (result) { if (result) {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
else { else {
log.debug(presentationModel.getErrorMessage()); // TODO use validating TF log.debug(presentationModel.getErrorMessage()); // TODO use validating TF
@ -122,8 +122,8 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
@FXML @FXML
private void onSkipped() { private void onSkipped() {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
} }

View file

@ -176,8 +176,8 @@ public class FiatAccountViewCB extends CachedViewCB<FiatAccountPm> implements Co
@FXML @FXML
private void onCompleted() { private void onCompleted() {
if (parentController != null) if (parent != null)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML

View file

@ -107,8 +107,8 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
private void onSaved() { private void onSaved() {
boolean result = presentationModel.requestSavePassword(); boolean result = presentationModel.requestSavePassword();
if (result) { if (result) {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
else { else {
// TODO use validating passwordTF // TODO use validating passwordTF
@ -118,8 +118,8 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
@FXML @FXML
private void onSkipped() { private void onSkipped() {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML

View file

@ -117,8 +117,8 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
@Override @Override
public void handle(ActionEvent actionEvent) { public void handle(ActionEvent actionEvent) {
try { try {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(RegistrationViewCB.this); ((MultiStepNavigation) parent).nextStep(RegistrationViewCB.this);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -160,8 +160,8 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
@FXML @FXML
private void onCompleted() { private void onCompleted() {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML

View file

@ -101,8 +101,8 @@ public class SeedWordsViewCB extends CachedViewCB<SeedWordsPM> implements Contex
@FXML @FXML
private void onCompleted() { private void onCompleted() {
if (parentController instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parentController).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
@FXML @FXML

View file

@ -160,7 +160,7 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
final Pane view = loader.load(); final Pane view = loader.load();
content.getChildren().setAll(view); content.getChildren().setAll(view);
childController = loader.getController(); childController = loader.getController();
((ViewCB<? extends PresentationModel>) childController).setParentController(this); ((ViewCB<? extends PresentationModel>) childController).setParent(this);
((ContextAware) childController).useSettingsContext(true); ((ContextAware) childController).useSettingsContext(true);
return childController; return childController;
} catch (IOException e) { } catch (IOException e) {

View file

@ -170,7 +170,7 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
final Pane view = loader.load(); final Pane view = loader.load();
content.getChildren().setAll(view); content.getChildren().setAll(view);
childController = loader.getController(); childController = loader.getController();
((ViewCB<? extends PresentationModel>) childController).setParentController(this); ((ViewCB<? extends PresentationModel>) childController).setParent(this);
((ContextAware) childController).useSettingsContext(false); ((ContextAware) childController).useSettingsContext(false);
return childController; return childController;
} catch (IOException e) { } catch (IOException e) {

View file

@ -19,7 +19,15 @@ package io.bitsquare.gui.main.trade;
import io.bitsquare.trade.Direction; import io.bitsquare.trade.Direction;
import javax.inject.Inject;
public class BuyController extends TradeController { public class BuyController extends TradeController {
@Inject
public BuyController(TradePM presentationModel) {
super(presentationModel);
}
@Override @Override
protected void applyDirection() { protected void applyDirection() {
//tabPane.getSelectionModel().select(0); //tabPane.getSelectionModel().select(0);

View file

@ -19,7 +19,15 @@ package io.bitsquare.gui.main.trade;
import io.bitsquare.trade.Direction; import io.bitsquare.trade.Direction;
import javax.inject.Inject;
public class SellController extends TradeController { public class SellController extends TradeController {
@Inject
public SellController(TradePM presentationModel) {
super(presentationModel);
}
@Override @Override
protected void applyDirection() { protected void applyDirection() {
orderBookController.applyDirection(Direction.SELL); orderBookController.applyDirection(Direction.SELL);

View file

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.trade; package io.bitsquare.gui.main.trade;
import io.bitsquare.gui.CachedViewController; import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.NavigationItem; import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.main.trade.createoffer.CreateOfferViewCB; import io.bitsquare.gui.main.trade.createoffer.CreateOfferViewCB;
@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
public class TradeController extends CachedViewController { public class TradeController extends CachedViewCB<TradePM> {
private static final Logger log = LoggerFactory.getLogger(TradeController.class); private static final Logger log = LoggerFactory.getLogger(TradeController.class);
protected OrderBookController orderBookController; protected OrderBookController orderBookController;
@ -53,20 +53,25 @@ public class TradeController extends CachedViewController {
private Node createOfferView; private Node createOfferView;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
protected TradeController(TradePM presentationModel) {
super(presentationModel);
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Lifecycle // Lifecycle
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("EmptyMethod")
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
loadViewAndGetChildController(NavigationItem.ORDER_BOOK); loadView(NavigationItem.ORDER_BOOK);
}
@Override
public void deactivate() {
super.deactivate();
} }
@Override @Override
@ -99,13 +104,27 @@ public class TradeController extends CachedViewController {
}); });
} }
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Navigation // Navigation
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override // @Override
public Initializable loadViewAndGetChildController(NavigationItem navigationItem) { public Initializable loadView(NavigationItem navigationItem) {
super.loadView(navigationItem);
TabPane tabPane = (TabPane) root; TabPane tabPane = (TabPane) root;
if (navigationItem == NavigationItem.ORDER_BOOK) { if (navigationItem == NavigationItem.ORDER_BOOK) {
checkArgument(orderBookLoader == null); checkArgument(orderBookLoader == null);
@ -122,7 +141,7 @@ public class TradeController extends CachedViewController {
log.error(e.getMessage()); log.error(e.getMessage());
} }
orderBookController = orderBookLoader.getController(); orderBookController = orderBookLoader.getController();
orderBookController.setParentController(this); orderBookController.setParent(this);
return orderBookController; return orderBookController;
} }
else if (navigationItem == NavigationItem.CREATE_OFFER) { else if (navigationItem == NavigationItem.CREATE_OFFER) {
@ -134,7 +153,7 @@ public class TradeController extends CachedViewController {
try { try {
createOfferView = loader.load(); createOfferView = loader.load();
createOfferCodeBehind = loader.getController(); createOfferCodeBehind = loader.getController();
createOfferCodeBehind.setParentController(this); createOfferCodeBehind.setParent(this);
createOfferCodeBehind.setOnClose(() -> { createOfferCodeBehind.setOnClose(() -> {
orderBookController.onCreateOfferViewRemoved(); orderBookController.onCreateOfferViewRemoved();
return null; return null;
@ -159,7 +178,8 @@ public class TradeController extends CachedViewController {
try { try {
final Parent view = loader.load(); final Parent view = loader.load();
takeOfferController = loader.getController(); takeOfferController = loader.getController();
takeOfferController.setParentController(this); //TODO
//takeOfferController.setParentController(this);
final Tab tab = new Tab("Take offer"); final Tab tab = new Tab("Take offer");
tab.setContent(view); tab.setContent(view);
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);

View file

@ -0,0 +1,59 @@
/*
* 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.trade;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradeModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(TradeModel.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradeModel() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
}

View file

@ -0,0 +1,65 @@
/*
* 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.trade;
import io.bitsquare.gui.PresentationModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradePM extends PresentationModel<TradeModel> {
private static final Logger log = LoggerFactory.getLogger(TradePM.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradePM(TradeModel model) {
super(model);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Initializable
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
}

View file

@ -19,7 +19,7 @@ package io.bitsquare.gui.main.trade.orderbook;
import io.bitsquare.bank.BankAccountType; import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.WalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.CachedViewController; import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.NavigationController; import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.NavigationItem; import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.OverlayController; import io.bitsquare.gui.OverlayController;
@ -82,7 +82,7 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class OrderBookController extends CachedViewController { public class OrderBookController extends CachedViewCB<OrderBookPM> {
private static final Logger log = LoggerFactory.getLogger(OrderBookController.class); private static final Logger log = LoggerFactory.getLogger(OrderBookController.class);
private NavigationController navigationController; private NavigationController navigationController;
@ -114,11 +114,14 @@ public class OrderBookController extends CachedViewController {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private OrderBookController(NavigationController navigationController, private OrderBookController(OrderBookPM presentationModel,
NavigationController navigationController,
OverlayController overlayController, OverlayController overlayController,
OrderBook orderBook, User user, OrderBook orderBook, User user,
MessageFacade messageFacade, MessageFacade messageFacade,
WalletFacade walletFacade, Settings settings, Persistence persistence) { WalletFacade walletFacade, Settings settings, Persistence persistence) {
super(presentationModel);
this.navigationController = navigationController; this.navigationController = navigationController;
this.overlayController = overlayController; this.overlayController = overlayController;
this.orderBook = orderBook; this.orderBook = orderBook;
@ -173,13 +176,13 @@ public class OrderBookController extends CachedViewController {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void setParentController(ViewController parentController) { public void setParent(Initializable parent) {
super.setParentController(parentController); super.setParent(parent);
} }
@Override @Override
public Initializable loadViewAndGetChildController(NavigationItem navigationItem) { public Initializable loadView(NavigationItem navigationItem) {
return null; return super.loadView(navigationItem);
} }
@ -242,12 +245,12 @@ public class OrderBookController extends CachedViewController {
//TODO Remove that when all UIs are converted to CodeBehind //TODO Remove that when all UIs are converted to CodeBehind
Initializable nextController = null; Initializable nextController = null;
if (parentController != null) { if (parent != null) {
if (parentController instanceof ViewController) if (parent instanceof ViewController)
nextController = ((ViewController) parentController).loadViewAndGetChildController(NavigationItem nextController = ((ViewController) parent).loadViewAndGetChildController(NavigationItem
.CREATE_OFFER); .CREATE_OFFER);
else if (parentController instanceof ViewCB) else if (parent instanceof ViewCB)
nextController = ((ViewCB) parentController).loadView(NavigationItem nextController = ((ViewCB) parent).loadView(NavigationItem
.CREATE_OFFER); .CREATE_OFFER);
} }
@ -322,13 +325,13 @@ public class OrderBookController extends CachedViewController {
//TODO Remove that when all UIs are converted to CodeBehind //TODO Remove that when all UIs are converted to CodeBehind
TakeOfferController takeOfferController = null; TakeOfferController takeOfferController = null;
if (parentController != null) { if (parent != null) {
if (parentController instanceof ViewController) if (parent instanceof ViewController)
takeOfferController = (TakeOfferController) ((ViewController) parentController) takeOfferController = (TakeOfferController) ((ViewController) parent)
.loadViewAndGetChildController(NavigationItem .loadViewAndGetChildController(NavigationItem
.TAKE_OFFER); .TAKE_OFFER);
else if (parentController instanceof ViewCB) else if (parent instanceof ViewCB)
takeOfferController = (TakeOfferController) ((ViewCB) parentController) takeOfferController = (TakeOfferController) ((ViewCB) parent)
.loadView(NavigationItem .loadView(NavigationItem
.TAKE_OFFER); .TAKE_OFFER);
} }

View file

@ -0,0 +1,60 @@
/*
* 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.trade.orderbook;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderBookModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(OrderBookModel.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public OrderBookModel() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
}

View file

@ -0,0 +1,60 @@
/*
* 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.trade.orderbook;
import io.bitsquare.gui.PresentationModel;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderBookPM extends PresentationModel<OrderBookModel> {
private static final Logger log = LoggerFactory.getLogger(OrderBookPM.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public OrderBookPM(OrderBookModel model) {
super(model);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
}