mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 23:06:39 +01:00
Merge pull request #2566 from ripcurlx/ui-dao-improvements
DAO UI improvements
This commit is contained in:
commit
2a46133292
23 changed files with 878 additions and 472 deletions
|
@ -1681,6 +1681,7 @@ dao.proposal.active.remove.confirm=Are you sure you want to remove that proposal
|
||||||
The already paid proposal fee will be lost.
|
The already paid proposal fee will be lost.
|
||||||
dao.proposal.active.remove.doRemove=Yes, remove my proposal
|
dao.proposal.active.remove.doRemove=Yes, remove my proposal
|
||||||
dao.proposal.active.remove.failed=Could not remove proposal.
|
dao.proposal.active.remove.failed=Could not remove proposal.
|
||||||
|
dao.proposal.myVote.title=Voting
|
||||||
dao.proposal.myVote.accept=Accept proposal
|
dao.proposal.myVote.accept=Accept proposal
|
||||||
dao.proposal.myVote.reject=Reject proposal
|
dao.proposal.myVote.reject=Reject proposal
|
||||||
dao.proposal.myVote.removeMyVote=Ignore proposal
|
dao.proposal.myVote.removeMyVote=Ignore proposal
|
||||||
|
@ -1688,10 +1689,12 @@ dao.proposal.myVote.merit=Vote weight from earned BSQ
|
||||||
dao.proposal.myVote.stake=Vote weight from stake
|
dao.proposal.myVote.stake=Vote weight from stake
|
||||||
dao.proposal.myVote.blindVoteTxId=Blind vote transaction ID
|
dao.proposal.myVote.blindVoteTxId=Blind vote transaction ID
|
||||||
dao.proposal.myVote.revealTxId=Vote reveal transaction ID
|
dao.proposal.myVote.revealTxId=Vote reveal transaction ID
|
||||||
dao.proposal.myVote.stake.prompt=Max. available balance for voting: {0}
|
dao.proposal.myVote.stake.prompt=Max. available stake for voting: {0}
|
||||||
dao.proposal.votes.header=Vote on all proposals
|
dao.proposal.votes.header=Set stake for voting and publish your votes
|
||||||
dao.proposal.votes.header.voted=My vote
|
dao.proposal.myVote.button=Publish votes
|
||||||
dao.proposal.myVote.button=Vote on all proposals
|
dao.proposal.myVote.setStake.description=After voting on all proposals you have to set your stake for voting by locking up \
|
||||||
|
BSQ. The more BSQ you lock up, the more weight your vote will have. \n\n\
|
||||||
|
BSQ locked up for voting will be unlocked again during the vote reveal phase.
|
||||||
dao.proposal.create.selectProposalType=Select proposal type
|
dao.proposal.create.selectProposalType=Select proposal type
|
||||||
dao.proposal.create.phase.inactive=Please wait until the next proposal phase
|
dao.proposal.create.phase.inactive=Please wait until the next proposal phase
|
||||||
dao.proposal.create.proposalType=Proposal type
|
dao.proposal.create.proposalType=Proposal type
|
||||||
|
|
|
@ -320,6 +320,20 @@ bg color of non edit textFields: fafafa
|
||||||
-fx-padding: 0 10 0 10;
|
-fx-padding: 0 10 0 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-button {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-underline: true;
|
||||||
|
-fx-padding: 0 10 0 10;
|
||||||
|
-fx-pref-height: 28;
|
||||||
|
-fx-min-height: -fx-pref-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-button:hover {
|
||||||
|
-fx-text-fill: -bs-rd-black;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-underline: false;
|
||||||
|
}
|
||||||
|
|
||||||
.jfx-checkbox {
|
.jfx-checkbox {
|
||||||
-jfx-checked-color: -bs-rd-green;
|
-jfx-checked-color: -bs-rd-green;
|
||||||
-fx-font-size: 0.692em;
|
-fx-font-size: 0.692em;
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class BondsView extends ActivatableView<GridPane, Void> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.allBonds.header"));
|
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.allBonds.header"), "last");
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
addColumns();
|
addColumns();
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class BondingDashboardView extends ActivatableView<GridPane, Void> {
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
gridRow = bsqBalanceUtil.addGroup(root, gridRow);
|
gridRow = bsqBalanceUtil.addGroup(root, gridRow);
|
||||||
gridRow = bsqBalanceUtil.addBondBalanceGroup(root, gridRow);
|
gridRow = bsqBalanceUtil.addBondBalanceGroup(root, gridRow, "last");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -144,7 +144,7 @@ public class MyReputationView extends ActivatableView<GridPane, Void> implements
|
||||||
|
|
||||||
lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bond.reputation.lockupButton"));
|
lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bond.reputation.lockupButton"));
|
||||||
|
|
||||||
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.reputation.table.header"), 20);
|
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.reputation.table.header"), 20, "last");
|
||||||
createColumns();
|
createColumns();
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class RolesView extends ActivatableView<GridPane, Void> {
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
int gridRow = 0;
|
int gridRow = 0;
|
||||||
tableView = FormBuilder.addTableViewWithHeader(root, gridRow, Res.get("dao.bond.bondedRoles"));
|
tableView = FormBuilder.addTableViewWithHeader(root, gridRow, Res.get("dao.bond.bondedRoles"), "last");
|
||||||
createColumns();
|
createColumns();
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class AssetFeeView extends ActivatableView<GridPane, Void> implements Bsq
|
||||||
|
|
||||||
payFeeButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.burnBsq.payFee"));
|
payFeeButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.burnBsq.payFee"));
|
||||||
|
|
||||||
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.burnBsq.allAssets"), 20);
|
tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.burnBsq.allAssets"), 20, "last");
|
||||||
createColumns();
|
createColumns();
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class ProofOfBurnView extends ActivatableView<GridPane, Void> implements
|
||||||
createColumnsForMyItems();
|
createColumnsForMyItems();
|
||||||
myItemsTableView.setItems(myItemsSortedList);
|
myItemsTableView.setItems(myItemsSortedList);
|
||||||
|
|
||||||
allTxsTableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.proofOfBurn.allTxs"), 30);
|
allTxsTableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.proofOfBurn.allTxs"), 30, "last");
|
||||||
createColumnsForAllTxs();
|
createColumnsForAllTxs();
|
||||||
allTxsTableView.setItems(allItemsSortedList);
|
allTxsTableView.setItems(allItemsSortedList);
|
||||||
|
|
||||||
|
|
|
@ -140,9 +140,10 @@ public class ProposalDisplay {
|
||||||
private final ChangeListener<Object> inputListener;
|
private final ChangeListener<Object> inputListener;
|
||||||
private ChangeListener<Param> paramChangeListener;
|
private ChangeListener<Param> paramChangeListener;
|
||||||
private ChangeListener<BondedRoleType> requiredBondForRoleListener;
|
private ChangeListener<BondedRoleType> requiredBondForRoleListener;
|
||||||
private TitledGroupBg titledGroupBg;
|
private TitledGroupBg myVoteTitledGroup;
|
||||||
private int titledGroupBgRowSpan;
|
private int titledGroupBgRowSpan;
|
||||||
private VBox linkWithIconContainer, comboBoxValueContainer, myVoteBox, voteResultBox;
|
private VBox linkWithIconContainer, comboBoxValueContainer, myVoteBox, voteResultBox;
|
||||||
|
private int votingBoxRowSpan;
|
||||||
|
|
||||||
public ProposalDisplay(GridPane gridPane,
|
public ProposalDisplay(GridPane gridPane,
|
||||||
BsqFormatter bsqFormatter,
|
BsqFormatter bsqFormatter,
|
||||||
|
@ -176,6 +177,11 @@ public class ProposalDisplay {
|
||||||
|
|
||||||
public void createAllFields(String title, int gridRowStartIndex, double top, ProposalType proposalType,
|
public void createAllFields(String title, int gridRowStartIndex, double top, ProposalType proposalType,
|
||||||
boolean isMakeProposalScreen) {
|
boolean isMakeProposalScreen) {
|
||||||
|
createAllFields(title, gridRowStartIndex, top, proposalType, isMakeProposalScreen, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createAllFields(String title, int gridRowStartIndex, double top, ProposalType proposalType,
|
||||||
|
boolean isMakeProposalScreen, String titledGroupStyle) {
|
||||||
removeAllFields();
|
removeAllFields();
|
||||||
this.gridRowStartIndex = gridRowStartIndex;
|
this.gridRowStartIndex = gridRowStartIndex;
|
||||||
this.gridRow = gridRowStartIndex;
|
this.gridRow = gridRowStartIndex;
|
||||||
|
@ -200,12 +206,26 @@ public class ProposalDisplay {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
titledGroupBg = addTitledGroupBg(gridPane, gridRow, titledGroupBgRowSpan, title, top);
|
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, gridRow, titledGroupBgRowSpan, title, top);
|
||||||
double proposalTypeTop = top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE;
|
|
||||||
|
if (titledGroupStyle != null) titledGroupBg.getStyleClass().add(titledGroupStyle);
|
||||||
|
|
||||||
|
double proposalTypeTop;
|
||||||
|
|
||||||
|
if (top == Layout.GROUP_DISTANCE_WITHOUT_SEPARATOR) {
|
||||||
|
proposalTypeTop = Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE_WITHOUT_SEPARATOR;
|
||||||
|
} else if (top == Layout.GROUP_DISTANCE) {
|
||||||
|
proposalTypeTop = Layout.FIRST_ROW_AND_GROUP_DISTANCE;
|
||||||
|
} else if (top == 0) {
|
||||||
|
proposalTypeTop = Layout.FIRST_ROW_DISTANCE;
|
||||||
|
} else {
|
||||||
|
proposalTypeTop = Layout.FIRST_ROW_DISTANCE + top;
|
||||||
|
}
|
||||||
|
|
||||||
proposalTypeTextField = addTopLabelTextField(gridPane, gridRow,
|
proposalTypeTextField = addTopLabelTextField(gridPane, gridRow,
|
||||||
Res.get("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second;
|
Res.get("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second;
|
||||||
|
|
||||||
nameTextField = addInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name"), Layout.FIRST_ROW_DISTANCE);
|
nameTextField = addInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name"));
|
||||||
if (isMakeProposalScreen)
|
if (isMakeProposalScreen)
|
||||||
nameTextField.setValidator(new InputValidator());
|
nameTextField.setValidator(new InputValidator());
|
||||||
inputControls.add(nameTextField);
|
inputControls.add(nameTextField);
|
||||||
|
@ -317,7 +337,7 @@ public class ProposalDisplay {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
comboBoxes.add(bondedRoleTypeComboBox);
|
comboBoxes.add(bondedRoleTypeComboBox);
|
||||||
requiredBondForRoleTextField = addTopLabelTextField(gridPane, ++gridRow,
|
requiredBondForRoleTextField = addTopLabelReadOnlyTextField(gridPane, ++gridRow,
|
||||||
Res.get("dao.proposal.display.requiredBondForRole.label")).second;
|
Res.get("dao.proposal.display.requiredBondForRole.label")).second;
|
||||||
|
|
||||||
requiredBondForRoleListener = (observable, oldValue, newValue) -> {
|
requiredBondForRoleListener = (observable, oldValue, newValue) -> {
|
||||||
|
@ -398,15 +418,18 @@ public class ProposalDisplay {
|
||||||
proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight())));
|
proposalFeeTextField.setText(bsqFormatter.formatCoinWithCode(daoFacade.getProposalFee(daoFacade.getChainHeight())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple3<Label, TextField, VBox> tuple3 = addTopLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.myVote"));
|
votingBoxRowSpan = 4;
|
||||||
|
|
||||||
|
myVoteTitledGroup = addTitledGroupBg(gridPane, ++gridRow, 4, Res.get("dao.proposal.myVote.title"), Layout.COMPACT_FIRST_ROW_DISTANCE);
|
||||||
|
|
||||||
|
Tuple3<Label, TextField, VBox> tuple3 = addTopLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.myVote"), Layout.COMPACT_FIRST_ROW_DISTANCE);
|
||||||
|
|
||||||
myVoteBox = tuple3.third;
|
myVoteBox = tuple3.third;
|
||||||
myVoteBox.setVisible(false);
|
setMyVoteBoxVisibility(false);
|
||||||
myVoteBox.setManaged(false);
|
|
||||||
|
|
||||||
myVoteTextField = tuple3.second;
|
myVoteTextField = tuple3.second;
|
||||||
|
|
||||||
tuple3 = addTopLabelTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.voteResult"));
|
tuple3 = addTopLabelReadOnlyTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.voteResult"));
|
||||||
|
|
||||||
voteResultBox = tuple3.third;
|
voteResultBox = tuple3.third;
|
||||||
voteResultBox.setVisible(false);
|
voteResultBox.setVisible(false);
|
||||||
|
@ -427,12 +450,10 @@ public class ProposalDisplay {
|
||||||
}
|
}
|
||||||
myVoteTextField.setText(myVote);
|
myVoteTextField.setText(myVote);
|
||||||
|
|
||||||
myVoteBox.setVisible(isNotNull);
|
setMyVoteBoxVisibility(isNotNull);
|
||||||
myVoteBox.setManaged(isNotNull);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyEvaluatedProposal(@Nullable EvaluatedProposal evaluatedProposal) {
|
public void applyEvaluatedProposal(@Nullable EvaluatedProposal evaluatedProposal) {
|
||||||
GridPane.setRowSpan(titledGroupBg, titledGroupBgRowSpan + 1);
|
|
||||||
|
|
||||||
boolean isEvaluatedProposalNotNull = evaluatedProposal != null;
|
boolean isEvaluatedProposalNotNull = evaluatedProposal != null;
|
||||||
if (isEvaluatedProposalNotNull) {
|
if (isEvaluatedProposalNotNull) {
|
||||||
|
@ -468,11 +489,12 @@ public class ProposalDisplay {
|
||||||
String myVoteSummary = Res.get("dao.proposal.myVote.summary", myVote,
|
String myVoteSummary = Res.get("dao.proposal.myVote.summary", myVote,
|
||||||
weight, meritString, stakeString);
|
weight, meritString, stakeString);
|
||||||
myVoteTextField.setText(myVoteSummary);
|
myVoteTextField.setText(myVoteSummary);
|
||||||
|
|
||||||
|
GridPane.setRowSpan(myVoteTitledGroup, votingBoxRowSpan - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean show = ballotIsNotNull && hasVoted;
|
boolean show = ballotIsNotNull && hasVoted;
|
||||||
myVoteBox.setVisible(show);
|
setMyVoteBoxVisibility(show);
|
||||||
myVoteBox.setManaged(show);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsVoteIncludedInResult(boolean isVoteIncludedInResult) {
|
public void setIsVoteIncludedInResult(boolean isVoteIncludedInResult) {
|
||||||
|
@ -658,4 +680,11 @@ public class ProposalDisplay {
|
||||||
|
|
||||||
return scrollPane;
|
return scrollPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setMyVoteBoxVisibility(boolean visibility) {
|
||||||
|
myVoteTitledGroup.setVisible(visibility);
|
||||||
|
myVoteTitledGroup.setManaged(visibility);
|
||||||
|
myVoteBox.setVisible(visibility);
|
||||||
|
myVoteBox.setManaged(visibility);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package bisq.desktop.main.dao.governance.dashboard;
|
||||||
|
|
||||||
import bisq.desktop.common.view.ActivatableView;
|
import bisq.desktop.common.view.ActivatableView;
|
||||||
import bisq.desktop.common.view.FxmlView;
|
import bisq.desktop.common.view.FxmlView;
|
||||||
|
import bisq.desktop.components.TitledGroupBg;
|
||||||
import bisq.desktop.main.dao.governance.PhasesView;
|
import bisq.desktop.main.dao.governance.PhasesView;
|
||||||
import bisq.desktop.util.Layout;
|
import bisq.desktop.util.Layout;
|
||||||
|
|
||||||
|
@ -69,7 +70,8 @@ public class GovernanceDashboardView extends ActivatableView<GridPane, Void> imp
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
gridRow = phasesView.addGroup(root, gridRow);
|
gridRow = phasesView.addGroup(root, gridRow);
|
||||||
|
|
||||||
addTitledGroupBg(root, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE);
|
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 6, Res.get("dao.cycle.overview.headline"), Layout.GROUP_DISTANCE);
|
||||||
|
titledGroupBg.getStyleClass().add("last");
|
||||||
currentBlockHeightTextField = addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.cycle.currentBlockHeight"),
|
currentBlockHeightTextField = addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.cycle.currentBlockHeight"),
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
currentPhaseTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.cycle.currentPhase")).second;
|
currentPhaseTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.cycle.currentPhase")).second;
|
||||||
|
|
|
@ -161,6 +161,7 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
|
||||||
gridRow = phasesView.addGroup(root, gridRow);
|
gridRow = phasesView.addGroup(root, gridRow);
|
||||||
|
|
||||||
proposalTitledGroup = addTitledGroupBg(root, ++gridRow, 2, proposalGroupTitle.get(), Layout.GROUP_DISTANCE);
|
proposalTitledGroup = addTitledGroupBg(root, ++gridRow, 2, proposalGroupTitle.get(), Layout.GROUP_DISTANCE);
|
||||||
|
proposalTitledGroup.getStyleClass().add("last");
|
||||||
final Tuple3<Label, TextField, VBox> nextProposalPhaseTuple = addTopLabelReadOnlyTextField(root, gridRow,
|
final Tuple3<Label, TextField, VBox> nextProposalPhaseTuple = addTopLabelReadOnlyTextField(root, gridRow,
|
||||||
Res.get("dao.cycle.proposal.next"),
|
Res.get("dao.cycle.proposal.next"),
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||||
|
@ -444,7 +445,7 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
|
||||||
if (selectedProposalType != null) {
|
if (selectedProposalType != null) {
|
||||||
proposalDisplay = new ProposalDisplay(root, bsqFormatter, daoFacade, changeParamValidator, navigation, null);
|
proposalDisplay = new ProposalDisplay(root, bsqFormatter, daoFacade, changeParamValidator, navigation, null);
|
||||||
|
|
||||||
proposalDisplay.createAllFields(Res.get("dao.proposal.create.new"), alwaysVisibleGridRowIndex, Layout.GROUP_DISTANCE,
|
proposalDisplay.createAllFields(Res.get("dao.proposal.create.new"), alwaysVisibleGridRowIndex, Layout.GROUP_DISTANCE_WITHOUT_SEPARATOR,
|
||||||
selectedProposalType, true);
|
selectedProposalType, true);
|
||||||
|
|
||||||
final Tuple4<Button, BusyAnimation, Label, HBox> makeProposalTuple = addButtonBusyAnimationLabelAfterGroup(root,
|
final Tuple4<Button, BusyAnimation, Label, HBox> makeProposalTuple = addButtonBusyAnimationLabelAfterGroup(root,
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.desktop.main.dao.governance.proposals;
|
package bisq.desktop.main.dao.governance.proposals;
|
||||||
|
|
||||||
import bisq.desktop.Navigation;
|
|
||||||
import bisq.desktop.common.view.ActivatableView;
|
import bisq.desktop.common.view.ActivatableView;
|
||||||
import bisq.desktop.common.view.FxmlView;
|
import bisq.desktop.common.view.FxmlView;
|
||||||
import bisq.desktop.components.AutoTooltipLabel;
|
import bisq.desktop.components.AutoTooltipLabel;
|
||||||
|
@ -29,8 +28,8 @@ import bisq.desktop.components.TableGroupHeadline;
|
||||||
import bisq.desktop.components.TitledGroupBg;
|
import bisq.desktop.components.TitledGroupBg;
|
||||||
import bisq.desktop.components.TxIdTextField;
|
import bisq.desktop.components.TxIdTextField;
|
||||||
import bisq.desktop.main.dao.governance.PhasesView;
|
import bisq.desktop.main.dao.governance.PhasesView;
|
||||||
import bisq.desktop.main.dao.governance.ProposalDisplay;
|
|
||||||
import bisq.desktop.main.overlays.popups.Popup;
|
import bisq.desktop.main.overlays.popups.Popup;
|
||||||
|
import bisq.desktop.main.overlays.windows.SelectProposalWindow;
|
||||||
import bisq.desktop.util.GUIUtil;
|
import bisq.desktop.util.GUIUtil;
|
||||||
import bisq.desktop.util.Layout;
|
import bisq.desktop.util.Layout;
|
||||||
import bisq.desktop.util.validation.BsqValidator;
|
import bisq.desktop.util.validation.BsqValidator;
|
||||||
|
@ -42,7 +41,6 @@ import bisq.core.btc.wallet.BsqWalletService;
|
||||||
import bisq.core.dao.DaoFacade;
|
import bisq.core.dao.DaoFacade;
|
||||||
import bisq.core.dao.governance.blindvote.BlindVoteConsensus;
|
import bisq.core.dao.governance.blindvote.BlindVoteConsensus;
|
||||||
import bisq.core.dao.governance.myvote.MyVote;
|
import bisq.core.dao.governance.myvote.MyVote;
|
||||||
import bisq.core.dao.governance.proposal.param.ChangeParamValidator;
|
|
||||||
import bisq.core.dao.state.DaoStateListener;
|
import bisq.core.dao.state.DaoStateListener;
|
||||||
import bisq.core.dao.state.DaoStateService;
|
import bisq.core.dao.state.DaoStateService;
|
||||||
import bisq.core.dao.state.model.blockchain.Block;
|
import bisq.core.dao.state.model.blockchain.Block;
|
||||||
|
@ -71,7 +69,6 @@ import com.jfoenix.controls.JFXButton;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.control.TableCell;
|
import javafx.scene.control.TableCell;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
|
@ -101,11 +98,13 @@ import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static bisq.desktop.util.FormBuilder.*;
|
import static bisq.desktop.util.FormBuilder.*;
|
||||||
|
import static bisq.desktop.util.Layout.INITIAL_WINDOW_HEIGHT;
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class ProposalsView extends ActivatableView<GridPane, Void> implements BsqBalanceListener, DaoStateListener {
|
public class ProposalsView extends ActivatableView<GridPane, Void> implements BsqBalanceListener, DaoStateListener {
|
||||||
|
@ -113,11 +112,10 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
private final BsqWalletService bsqWalletService;
|
private final BsqWalletService bsqWalletService;
|
||||||
private final PhasesView phasesView;
|
private final PhasesView phasesView;
|
||||||
private final DaoStateService daoStateService;
|
private final DaoStateService daoStateService;
|
||||||
private final ChangeParamValidator changeParamValidator;
|
|
||||||
private final Preferences preferences;
|
private final Preferences preferences;
|
||||||
private final BsqFormatter bsqFormatter;
|
private final BsqFormatter bsqFormatter;
|
||||||
private final BSFormatter btcFormatter;
|
private final BSFormatter btcFormatter;
|
||||||
private final Navigation navigation;
|
private final SelectProposalWindow selectProposalWindow;
|
||||||
|
|
||||||
private final ObservableList<ProposalsListItem> listItems = FXCollections.observableArrayList();
|
private final ObservableList<ProposalsListItem> listItems = FXCollections.observableArrayList();
|
||||||
private final SortedList<ProposalsListItem> sortedList = new SortedList<>(listItems);
|
private final SortedList<ProposalsListItem> sortedList = new SortedList<>(listItems);
|
||||||
|
@ -125,20 +123,15 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
private final List<Node> voteFields = new ArrayList<>();
|
private final List<Node> voteFields = new ArrayList<>();
|
||||||
|
|
||||||
private TableView<ProposalsListItem> tableView;
|
private TableView<ProposalsListItem> tableView;
|
||||||
private TitledGroupBg voteTitledGroupBg;
|
|
||||||
private Label voteButtonInfoLabel;
|
private Label voteButtonInfoLabel;
|
||||||
private TxIdTextField revealTxIdTextField, blindVoteTxIdTextField;
|
private TxIdTextField revealTxIdTextField, blindVoteTxIdTextField;
|
||||||
private TextField meritTextField;
|
private TextField meritTextField;
|
||||||
private VBox blindVoteTxIdContainer, revealTxIdContainer;
|
private VBox blindVoteTxIdContainer, revealTxIdContainer;
|
||||||
private Button removeProposalButton, acceptButton, rejectButton, ignoreButton, voteButton;
|
private Button voteButton;
|
||||||
private InputTextField stakeInputTextField;
|
private InputTextField stakeInputTextField;
|
||||||
private ScrollPane proposalDisplayView;
|
|
||||||
private GridPane proposalDisplayGridPane;
|
|
||||||
private BusyAnimation voteButtonBusyAnimation;
|
private BusyAnimation voteButtonBusyAnimation;
|
||||||
private ProposalDisplay proposalDisplay;
|
|
||||||
|
|
||||||
private int gridRow = 0;
|
private int gridRow = 0;
|
||||||
private boolean proposalDisplayInitialized;
|
|
||||||
private ProposalsListItem selectedItem;
|
private ProposalsListItem selectedItem;
|
||||||
private DaoPhase.Phase currentPhase;
|
private DaoPhase.Phase currentPhase;
|
||||||
private ListChangeListener<Proposal> proposalListChangeListener;
|
private ListChangeListener<Proposal> proposalListChangeListener;
|
||||||
|
@ -147,6 +140,16 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
private Subscription selectedProposalSubscription, phaseSubscription;
|
private Subscription selectedProposalSubscription, phaseSubscription;
|
||||||
private boolean areVoteButtonsVisible;
|
private boolean areVoteButtonsVisible;
|
||||||
private TableColumn<ProposalsListItem, ProposalsListItem> lastColumn;
|
private TableColumn<ProposalsListItem, ProposalsListItem> lastColumn;
|
||||||
|
private String shownVoteOnProposalWindowForTxId = "";
|
||||||
|
|
||||||
|
private final double initialProposalTableViewHeight = 180;
|
||||||
|
private final double pixelsPerProposalTableRow = (initialProposalTableViewHeight - 28) / 4.0;
|
||||||
|
private final Function<Double, Double> proposalTableViewHeight = (screenSize) -> {
|
||||||
|
int extraRows = screenSize <= INITIAL_WINDOW_HEIGHT ? 0 : (int) ((screenSize - INITIAL_WINDOW_HEIGHT) / pixelsPerProposalTableRow);
|
||||||
|
return extraRows == 0 ? initialProposalTableViewHeight : Math.ceil(initialProposalTableViewHeight + (extraRows * pixelsPerProposalTableRow));
|
||||||
|
};
|
||||||
|
private ChangeListener<Number> bisqWindowVerticalSizeListener;
|
||||||
|
private TableGroupHeadline proposalsHeadline;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -158,20 +161,18 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
BsqWalletService bsqWalletService,
|
BsqWalletService bsqWalletService,
|
||||||
PhasesView phasesView,
|
PhasesView phasesView,
|
||||||
DaoStateService daoStateService,
|
DaoStateService daoStateService,
|
||||||
ChangeParamValidator changeParamValidator,
|
|
||||||
Preferences preferences,
|
Preferences preferences,
|
||||||
BsqFormatter bsqFormatter,
|
BsqFormatter bsqFormatter,
|
||||||
BSFormatter btcFormatter,
|
BSFormatter btcFormatter,
|
||||||
Navigation navigation) {
|
SelectProposalWindow selectProposalWindow) {
|
||||||
this.daoFacade = daoFacade;
|
this.daoFacade = daoFacade;
|
||||||
this.bsqWalletService = bsqWalletService;
|
this.bsqWalletService = bsqWalletService;
|
||||||
this.phasesView = phasesView;
|
this.phasesView = phasesView;
|
||||||
this.daoStateService = daoStateService;
|
this.daoStateService = daoStateService;
|
||||||
this.changeParamValidator = changeParamValidator;
|
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.bsqFormatter = bsqFormatter;
|
this.bsqFormatter = bsqFormatter;
|
||||||
this.btcFormatter = btcFormatter;
|
this.btcFormatter = btcFormatter;
|
||||||
this.navigation = navigation;
|
this.selectProposalWindow = selectProposalWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,15 +181,21 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
|
|
||||||
gridRow = phasesView.addGroup(root, gridRow);
|
gridRow = phasesView.addGroup(root, gridRow);
|
||||||
|
|
||||||
proposalDisplayGridPane = new GridPane();
|
|
||||||
|
|
||||||
createProposalsTableView();
|
createProposalsTableView();
|
||||||
createEmptyProposalDisplay();
|
|
||||||
createVoteView();
|
createVoteView();
|
||||||
|
|
||||||
ballotListChangeListener = c -> updateListItems();
|
ballotListChangeListener = c -> updateListItems();
|
||||||
proposalListChangeListener = c -> updateListItems();
|
proposalListChangeListener = c -> updateListItems();
|
||||||
|
|
||||||
|
bisqWindowVerticalSizeListener = (observable, oldValue, newValue) -> {
|
||||||
|
double newTableViewHeight = proposalTableViewHeight.apply(newValue.doubleValue());
|
||||||
|
if (tableView.getHeight() != newTableViewHeight) {
|
||||||
|
tableView.setMinHeight(newTableViewHeight);
|
||||||
|
double diff = newTableViewHeight - tableView.getHeight();
|
||||||
|
proposalsHeadline.setMaxHeight(proposalsHeadline.getHeight() + diff);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
stakeListener = (observable, oldValue, newValue) -> updateViews();
|
stakeListener = (observable, oldValue, newValue) -> updateViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,8 +225,10 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
bsqWalletService.getUnlockingBondsBalance());
|
bsqWalletService.getUnlockingBondsBalance());
|
||||||
|
|
||||||
updateListItems();
|
updateListItems();
|
||||||
GUIUtil.setFitToRowsForTableView(tableView, 38, 28, 2, 6);
|
GUIUtil.setFitToRowsForTableView(tableView, 38, 28, 4, 4);
|
||||||
updateViews();
|
updateViews();
|
||||||
|
|
||||||
|
root.getScene().heightProperty().addListener(bisqWindowVerticalSizeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -242,8 +251,6 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
}
|
}
|
||||||
if (voteButton != null)
|
if (voteButton != null)
|
||||||
voteButton.setOnAction(null);
|
voteButton.setOnAction(null);
|
||||||
if (removeProposalButton != null)
|
|
||||||
removeProposalButton.setOnAction(null);
|
|
||||||
|
|
||||||
listItems.forEach(ProposalsListItem::cleanup);
|
listItems.forEach(ProposalsListItem::cleanup);
|
||||||
tableView.getSelectionModel().clearSelection();
|
tableView.getSelectionModel().clearSelection();
|
||||||
|
@ -316,89 +323,39 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
listItems.clear();
|
listItems.clear();
|
||||||
|
|
||||||
fillListItems();
|
fillListItems();
|
||||||
|
|
||||||
if (listItems.isEmpty())
|
|
||||||
hideProposalDisplay();
|
|
||||||
|
|
||||||
|
|
||||||
if (!tableView.getItems().isEmpty()) {
|
|
||||||
onSelectProposal(tableView.getItems().get(0));
|
|
||||||
onSelectProposal(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
GUIUtil.setFitToRowsForTableView(tableView, 38, 28, 2, 6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAllFieldsOnProposalDisplay(Proposal proposal, @Nullable Ballot ballot,
|
private void showVoteOnProposalWindow(Proposal proposal, @Nullable Ballot ballot,
|
||||||
@Nullable EvaluatedProposal evaluatedProposal) {
|
@Nullable EvaluatedProposal evaluatedProposal) {
|
||||||
proposalDisplayView.setVisible(true);
|
|
||||||
proposalDisplayView.setManaged(true);
|
|
||||||
|
|
||||||
proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0, proposal.getType(),
|
if (!shownVoteOnProposalWindowForTxId.equals(proposal.getTxId())) {
|
||||||
false);
|
shownVoteOnProposalWindowForTxId = proposal.getTxId();
|
||||||
proposalDisplay.setEditable(false);
|
|
||||||
|
|
||||||
proposalDisplay.applyProposalPayload(proposal);
|
selectProposalWindow.show(proposal, evaluatedProposal, ballot);
|
||||||
|
selectProposalWindow.onAccept(() -> {
|
||||||
|
shownVoteOnProposalWindowForTxId = "";
|
||||||
|
onAccept();
|
||||||
|
});
|
||||||
|
selectProposalWindow.onReject(() -> {
|
||||||
|
shownVoteOnProposalWindowForTxId = "";
|
||||||
|
onReject();
|
||||||
|
});
|
||||||
|
selectProposalWindow.onIgnore(() -> {
|
||||||
|
shownVoteOnProposalWindowForTxId = "";
|
||||||
|
onIgnore();
|
||||||
|
});
|
||||||
|
selectProposalWindow.onRemove(() -> {
|
||||||
|
shownVoteOnProposalWindowForTxId = "";
|
||||||
|
onRemoveProposal();
|
||||||
|
});
|
||||||
|
|
||||||
proposalDisplay.applyEvaluatedProposal(evaluatedProposal);
|
selectProposalWindow.onClose(() -> {
|
||||||
|
shownVoteOnProposalWindowForTxId = "";
|
||||||
Tuple2<Long, Long> meritAndStakeTuple = daoFacade.getMeritAndStakeForProposal(proposal.getTxId());
|
tableView.getSelectionModel().clearSelection();
|
||||||
long merit = meritAndStakeTuple.first;
|
});
|
||||||
long stake = meritAndStakeTuple.second;
|
|
||||||
proposalDisplay.applyBallotAndVoteWeight(ballot, merit, stake);
|
|
||||||
|
|
||||||
proposalDisplayInitialized = true;
|
|
||||||
|
|
||||||
removeProposalButton = addButtonAfterGroup(proposalDisplayGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("shared.remove"));
|
|
||||||
removeProposalButton.setOnAction(event -> onRemoveProposal());
|
|
||||||
onPhaseChanged(daoFacade.phaseProperty().get());
|
|
||||||
|
|
||||||
Tuple3<Button, Button, Button> tuple = add3ButtonsAfterGroup(proposalDisplayGridPane,
|
|
||||||
proposalDisplay.incrementAndGetGridRow(),
|
|
||||||
Res.get("dao.proposal.myVote.accept"),
|
|
||||||
Res.get("dao.proposal.myVote.reject"),
|
|
||||||
Res.get("dao.proposal.myVote.removeMyVote"));
|
|
||||||
acceptButton = tuple.first;
|
|
||||||
acceptButton.setDefaultButton(false);
|
|
||||||
rejectButton = tuple.second;
|
|
||||||
ignoreButton = tuple.third;
|
|
||||||
acceptButton.setOnAction(event -> onAccept());
|
|
||||||
rejectButton.setOnAction(event -> onReject());
|
|
||||||
ignoreButton.setOnAction(event -> onIgnore());
|
|
||||||
|
|
||||||
voteButtons.clear();
|
|
||||||
voteButtons.add(voteButton);
|
|
||||||
voteButtons.add(acceptButton);
|
|
||||||
voteButtons.add(rejectButton);
|
|
||||||
voteButtons.add(ignoreButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideProposalDisplay() {
|
|
||||||
if (proposalDisplayInitialized) {
|
|
||||||
proposalDisplay.removeAllFields();
|
|
||||||
proposalDisplayView.setVisible(false);
|
|
||||||
proposalDisplayView.setManaged(false);
|
|
||||||
}
|
|
||||||
if (removeProposalButton != null) {
|
|
||||||
removeProposalButton.setManaged(false);
|
|
||||||
removeProposalButton.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (acceptButton != null) {
|
|
||||||
acceptButton.setManaged(false);
|
|
||||||
acceptButton.setVisible(false);
|
|
||||||
}
|
|
||||||
if (rejectButton != null) {
|
|
||||||
rejectButton.setManaged(false);
|
|
||||||
rejectButton.setVisible(false);
|
|
||||||
}
|
|
||||||
if (ignoreButton != null) {
|
|
||||||
ignoreButton.setManaged(false);
|
|
||||||
ignoreButton.setVisible(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Handlers
|
// Handlers
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -407,15 +364,6 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
if (phase != null && !phase.equals(currentPhase)) {
|
if (phase != null && !phase.equals(currentPhase)) {
|
||||||
currentPhase = phase;
|
currentPhase = phase;
|
||||||
stakeInputTextField.clear();
|
stakeInputTextField.clear();
|
||||||
onSelectProposal(selectedItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeProposalButton != null) {
|
|
||||||
boolean doShowRemoveButton = phase == DaoPhase.Phase.PROPOSAL &&
|
|
||||||
selectedItem != null &&
|
|
||||||
daoFacade.isMyProposal(selectedItem.getProposal());
|
|
||||||
removeProposalButton.setVisible(doShowRemoveButton);
|
|
||||||
removeProposalButton.setManaged(doShowRemoveButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateViews();
|
updateViews();
|
||||||
|
@ -427,9 +375,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
new Popup<>().warning(Res.get("dao.proposal.active.remove.confirm"))
|
new Popup<>().warning(Res.get("dao.proposal.active.remove.confirm"))
|
||||||
.actionButtonText(Res.get("dao.proposal.active.remove.doRemove"))
|
.actionButtonText(Res.get("dao.proposal.active.remove.doRemove"))
|
||||||
.onAction(() -> {
|
.onAction(() -> {
|
||||||
if (daoFacade.removeMyProposal(proposal)) {
|
if (!daoFacade.removeMyProposal(proposal)) {
|
||||||
hideProposalDisplay();
|
|
||||||
} else {
|
|
||||||
new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show();
|
new Popup<>().warning(Res.get("dao.proposal.active.remove.failed")).show();
|
||||||
}
|
}
|
||||||
tableView.getSelectionModel().clearSelection();
|
tableView.getSelectionModel().clearSelection();
|
||||||
|
@ -448,14 +394,11 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
.findAny()
|
.findAny()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
createAllFieldsOnProposalDisplay(selectedItem.getProposal(), selectedItem.getBallot(), evaluatedProposal);
|
|
||||||
applyMerit();
|
applyMerit();
|
||||||
} else {
|
showVoteOnProposalWindow(selectedItem.getProposal(), selectedItem.getBallot(), evaluatedProposal);
|
||||||
hideProposalDisplay();
|
|
||||||
}
|
}
|
||||||
onPhaseChanged(daoFacade.phaseProperty().get());
|
|
||||||
|
|
||||||
updateViews();
|
onPhaseChanged(daoFacade.phaseProperty().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyMerit() {
|
private void applyMerit() {
|
||||||
|
@ -479,20 +422,31 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
|
|
||||||
private void onAccept() {
|
private void onAccept() {
|
||||||
daoFacade.setVote(getBallotListItem().getBallot(), new Vote(true));
|
daoFacade.setVote(getBallotListItem().getBallot(), new Vote(true));
|
||||||
proposalDisplay.applyBallot(getBallotListItem().getBallot());
|
|
||||||
updateStateAfterVote();
|
updateStateAfterVote();
|
||||||
|
tableView.getSelectionModel().clearSelection();
|
||||||
|
|
||||||
|
showHowToSetStakeForVotingPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showHowToSetStakeForVotingPopup() {
|
||||||
|
String id = "explainHowToSetStakeForVoting";
|
||||||
|
if (preferences.showAgain(id))
|
||||||
|
new Popup<>().information(Res.get("dao.proposal.myVote.setStake.description"))
|
||||||
|
.dontShowAgainId(id).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onReject() {
|
private void onReject() {
|
||||||
daoFacade.setVote(getBallotListItem().getBallot(), new Vote(false));
|
daoFacade.setVote(getBallotListItem().getBallot(), new Vote(false));
|
||||||
proposalDisplay.applyBallot(getBallotListItem().getBallot());
|
|
||||||
updateStateAfterVote();
|
updateStateAfterVote();
|
||||||
|
tableView.getSelectionModel().clearSelection();
|
||||||
|
showHowToSetStakeForVotingPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onIgnore() {
|
private void onIgnore() {
|
||||||
daoFacade.setVote(getBallotListItem().getBallot(), null);
|
daoFacade.setVote(getBallotListItem().getBallot(), null);
|
||||||
proposalDisplay.applyBallot(getBallotListItem().getBallot());
|
|
||||||
updateStateAfterVote();
|
updateStateAfterVote();
|
||||||
|
tableView.getSelectionModel().clearSelection();
|
||||||
|
showHowToSetStakeForVotingPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onVote() {
|
private void onVote() {
|
||||||
|
@ -545,13 +499,6 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
return selectedItem;
|
return selectedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Vote> getVote(@Nullable Ballot ballot) {
|
|
||||||
if (ballot == null)
|
|
||||||
return Optional.empty();
|
|
||||||
else
|
|
||||||
return ballot.getVoteAsOptional();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateViews() {
|
private void updateViews() {
|
||||||
boolean isBlindVotePhaseButNotLastBlock = isBlindVotePhaseButNotLastBlock();
|
boolean isBlindVotePhaseButNotLastBlock = isBlindVotePhaseButNotLastBlock();
|
||||||
boolean hasVotedOnProposal = hasVotedOnProposal();
|
boolean hasVotedOnProposal = hasVotedOnProposal();
|
||||||
|
@ -560,17 +507,8 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
|
|
||||||
List<MyVote> myVoteListForCycle = daoFacade.getMyVoteListForCycle();
|
List<MyVote> myVoteListForCycle = daoFacade.getMyVoteListForCycle();
|
||||||
boolean hasAlreadyVoted = !myVoteListForCycle.isEmpty();
|
boolean hasAlreadyVoted = !myVoteListForCycle.isEmpty();
|
||||||
if (selectedItem != null && acceptButton != null) {
|
if (selectedItem != null) {
|
||||||
Optional<Vote> optionalVote = getVote(selectedItem.getBallot());
|
|
||||||
boolean isPresent = optionalVote.isPresent();
|
|
||||||
boolean isAccepted = isPresent && optionalVote.get().isAccepted();
|
|
||||||
acceptButton.setDisable((isPresent && isAccepted));
|
|
||||||
rejectButton.setDisable((isPresent && !isAccepted));
|
|
||||||
ignoreButton.setDisable(!isPresent);
|
|
||||||
|
|
||||||
stakeInputTextField.setMouseTransparent(hasAlreadyVoted || !isBlindVotePhaseButNotLastBlock);
|
stakeInputTextField.setMouseTransparent(hasAlreadyVoted || !isBlindVotePhaseButNotLastBlock);
|
||||||
} else {
|
|
||||||
stakeInputTextField.setMouseTransparent(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasProposals = !daoFacade.getActiveOrMyUnconfirmedProposals().isEmpty();
|
boolean hasProposals = !daoFacade.getActiveOrMyUnconfirmedProposals().isEmpty();
|
||||||
|
@ -595,7 +533,6 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
revealTxIdContainer.setManaged(false);
|
revealTxIdContainer.setManaged(false);
|
||||||
|
|
||||||
if (hasAlreadyVoted) {
|
if (hasAlreadyVoted) {
|
||||||
voteTitledGroupBg.setText(Res.get("dao.proposal.votes.header.voted"));
|
|
||||||
if (myVoteListForCycle.size() == 1) {
|
if (myVoteListForCycle.size() == 1) {
|
||||||
Optional<MyVote> optionalMyVote = myVoteListForCycle.stream()
|
Optional<MyVote> optionalMyVote = myVoteListForCycle.stream()
|
||||||
.filter(myVote -> daoFacade.isTxInCorrectCycle(myVote.getHeight(), daoFacade.getChainHeight()))
|
.filter(myVote -> daoFacade.isTxInCorrectCycle(myVote.getHeight(), daoFacade.getChainHeight()))
|
||||||
|
@ -660,7 +597,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void createProposalsTableView() {
|
private void createProposalsTableView() {
|
||||||
TableGroupHeadline proposalsHeadline = new TableGroupHeadline(Res.get("dao.proposal.active.header"));
|
proposalsHeadline = new TableGroupHeadline(Res.get("dao.proposal.active.header"));
|
||||||
GridPane.setRowIndex(proposalsHeadline, ++gridRow);
|
GridPane.setRowIndex(proposalsHeadline, ++gridRow);
|
||||||
GridPane.setMargin(proposalsHeadline, new Insets(Layout.GROUP_DISTANCE, -10, -10, -10));
|
GridPane.setMargin(proposalsHeadline, new Insets(Layout.GROUP_DISTANCE, -10, -10, -10));
|
||||||
root.getChildren().add(proposalsHeadline);
|
root.getChildren().add(proposalsHeadline);
|
||||||
|
@ -672,25 +609,17 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
createProposalColumns();
|
createProposalColumns();
|
||||||
GridPane.setRowIndex(tableView, gridRow);
|
GridPane.setRowIndex(tableView, gridRow);
|
||||||
GridPane.setHgrow(tableView, Priority.ALWAYS);
|
GridPane.setHgrow(tableView, Priority.ALWAYS);
|
||||||
|
GridPane.setVgrow(tableView, Priority.SOMETIMES);
|
||||||
GridPane.setMargin(tableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, 5, -10));
|
GridPane.setMargin(tableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, 5, -10));
|
||||||
root.getChildren().add(tableView);
|
root.getChildren().add(tableView);
|
||||||
|
|
||||||
tableView.setItems(sortedList);
|
tableView.setItems(sortedList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createEmptyProposalDisplay() {
|
|
||||||
proposalDisplay = new ProposalDisplay(proposalDisplayGridPane, bsqFormatter, daoFacade,
|
|
||||||
changeParamValidator, navigation, preferences);
|
|
||||||
proposalDisplayView = proposalDisplay.getView();
|
|
||||||
GridPane.setMargin(proposalDisplayView, new Insets(0, -10, 0, -10));
|
|
||||||
GridPane.setRowIndex(proposalDisplayView, ++gridRow);
|
|
||||||
GridPane.setHgrow(proposalDisplayView, Priority.ALWAYS);
|
|
||||||
root.getChildren().add(proposalDisplayView);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createVoteView() {
|
private void createVoteView() {
|
||||||
voteTitledGroupBg = addTitledGroupBg(root, ++gridRow, 4,
|
TitledGroupBg voteTitledGroupBg = addTitledGroupBg(root, ++gridRow, 4,
|
||||||
Res.get("dao.proposal.votes.header"), 20);
|
Res.get("dao.proposal.votes.header"), 20);
|
||||||
|
voteTitledGroupBg.getStyleClass().add("last");
|
||||||
voteFields.add(voteTitledGroupBg);
|
voteFields.add(voteTitledGroupBg);
|
||||||
|
|
||||||
Tuple3<Label, TextField, VBox> meritTuple = addTopLabelTextField(root, gridRow,
|
Tuple3<Label, TextField, VBox> meritTuple = addTopLabelTextField(root, gridRow,
|
||||||
|
@ -866,7 +795,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||||
JFXButton iconButton = item.getIconButton();
|
JFXButton iconButton = item.getIconButton();
|
||||||
if (iconButton != null) {
|
if (iconButton != null) {
|
||||||
iconButton.setOnAction(e -> {
|
iconButton.setOnAction(e -> {
|
||||||
onSelectProposal(item);
|
selectedItem = item;
|
||||||
if (areVoteButtonsVisible) {
|
if (areVoteButtonsVisible) {
|
||||||
if (iconButton.getUserData() == ProposalsListItem.IconButtonTypes.ACCEPT)
|
if (iconButton.getUserData() == ProposalsListItem.IconButtonTypes.ACCEPT)
|
||||||
onReject();
|
onReject();
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.desktop.main.dao.governance.result;
|
package bisq.desktop.main.dao.governance.result;
|
||||||
|
|
||||||
import bisq.desktop.Navigation;
|
|
||||||
import bisq.desktop.common.view.ActivatableView;
|
import bisq.desktop.common.view.ActivatableView;
|
||||||
import bisq.desktop.common.view.FxmlView;
|
import bisq.desktop.common.view.FxmlView;
|
||||||
import bisq.desktop.components.AutoTooltipLabel;
|
import bisq.desktop.components.AutoTooltipLabel;
|
||||||
|
@ -25,9 +24,9 @@ import bisq.desktop.components.AutoTooltipTableColumn;
|
||||||
import bisq.desktop.components.HyperlinkWithIcon;
|
import bisq.desktop.components.HyperlinkWithIcon;
|
||||||
import bisq.desktop.components.TableGroupHeadline;
|
import bisq.desktop.components.TableGroupHeadline;
|
||||||
import bisq.desktop.main.dao.governance.PhasesView;
|
import bisq.desktop.main.dao.governance.PhasesView;
|
||||||
import bisq.desktop.main.dao.governance.ProposalDisplay;
|
|
||||||
import bisq.desktop.main.overlays.popups.Popup;
|
import bisq.desktop.main.overlays.popups.Popup;
|
||||||
import bisq.desktop.main.overlays.windows.DaoTestingFeedbackWindow;
|
import bisq.desktop.main.overlays.windows.DaoTestingFeedbackWindow;
|
||||||
|
import bisq.desktop.main.overlays.windows.ProposalResultsWindow;
|
||||||
import bisq.desktop.util.FormBuilder;
|
import bisq.desktop.util.FormBuilder;
|
||||||
import bisq.desktop.util.GUIUtil;
|
import bisq.desktop.util.GUIUtil;
|
||||||
import bisq.desktop.util.Layout;
|
import bisq.desktop.util.Layout;
|
||||||
|
@ -63,11 +62,9 @@ import bisq.core.dao.state.model.governance.RoleProposal;
|
||||||
import bisq.core.dao.state.model.governance.Vote;
|
import bisq.core.dao.state.model.governance.Vote;
|
||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
import bisq.core.user.DontShowAgainLookup;
|
import bisq.core.user.DontShowAgainLookup;
|
||||||
import bisq.core.user.Preferences;
|
|
||||||
import bisq.core.util.BsqFormatter;
|
import bisq.core.util.BsqFormatter;
|
||||||
|
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
import bisq.common.util.Tuple2;
|
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
@ -79,21 +76,18 @@ import com.google.gson.JsonObject;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
|
||||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||||
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.control.TableCell;
|
import javafx.scene.control.TableCell;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
import javafx.scene.control.TextArea;
|
import javafx.scene.control.TextArea;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
|
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -118,6 +112,8 @@ import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static bisq.desktop.util.FormBuilder.addButton;
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class VoteResultView extends ActivatableView<GridPane, Void> implements DaoStateListener {
|
public class VoteResultView extends ActivatableView<GridPane, Void> implements DaoStateListener {
|
||||||
private final DaoFacade daoFacade;
|
private final DaoFacade daoFacade;
|
||||||
|
@ -128,11 +124,10 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
private final ProposalService proposalService;
|
private final ProposalService proposalService;
|
||||||
private final PeriodService periodService;
|
private final PeriodService periodService;
|
||||||
private final BsqWalletService bsqWalletService;
|
private final BsqWalletService bsqWalletService;
|
||||||
private final Preferences preferences;
|
|
||||||
private final BsqFormatter bsqFormatter;
|
private final BsqFormatter bsqFormatter;
|
||||||
private final Navigation navigation;
|
|
||||||
private final MyProposalListService myProposalListService;
|
private final MyProposalListService myProposalListService;
|
||||||
private final MyBlindVoteListService myBlindVoteListService;
|
private final MyBlindVoteListService myBlindVoteListService;
|
||||||
|
private ProposalResultsWindow proposalResultsWindow;
|
||||||
private Button exportButton;
|
private Button exportButton;
|
||||||
|
|
||||||
private int gridRow = 0;
|
private int gridRow = 0;
|
||||||
|
@ -152,7 +147,6 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
private ChangeListener<CycleListItem> selectedVoteResultListItemListener;
|
private ChangeListener<CycleListItem> selectedVoteResultListItemListener;
|
||||||
private ResultsOfCycle resultsOfCycle;
|
private ResultsOfCycle resultsOfCycle;
|
||||||
private ProposalListItem selectedProposalListItem;
|
private ProposalListItem selectedProposalListItem;
|
||||||
private TableView<VoteListItem> votesTableView;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -168,11 +162,10 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
ProposalService proposalService,
|
ProposalService proposalService,
|
||||||
PeriodService periodService,
|
PeriodService periodService,
|
||||||
BsqWalletService bsqWalletService,
|
BsqWalletService bsqWalletService,
|
||||||
Preferences preferences,
|
|
||||||
BsqFormatter bsqFormatter,
|
BsqFormatter bsqFormatter,
|
||||||
Navigation navigation,
|
|
||||||
MyProposalListService myProposalListService,
|
MyProposalListService myProposalListService,
|
||||||
MyBlindVoteListService myBlindVoteListService) {
|
MyBlindVoteListService myBlindVoteListService,
|
||||||
|
ProposalResultsWindow proposalResultsWindow) {
|
||||||
this.daoFacade = daoFacade;
|
this.daoFacade = daoFacade;
|
||||||
this.phasesView = phasesView;
|
this.phasesView = phasesView;
|
||||||
this.daoStateService = daoStateService;
|
this.daoStateService = daoStateService;
|
||||||
|
@ -181,11 +174,10 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
this.proposalService = proposalService;
|
this.proposalService = proposalService;
|
||||||
this.periodService = periodService;
|
this.periodService = periodService;
|
||||||
this.bsqWalletService = bsqWalletService;
|
this.bsqWalletService = bsqWalletService;
|
||||||
this.preferences = preferences;
|
|
||||||
this.bsqFormatter = bsqFormatter;
|
this.bsqFormatter = bsqFormatter;
|
||||||
this.navigation = navigation;
|
|
||||||
this.myProposalListService = myProposalListService;
|
this.myProposalListService = myProposalListService;
|
||||||
this.myBlindVoteListService = myBlindVoteListService;
|
this.myBlindVoteListService = myBlindVoteListService;
|
||||||
|
this.proposalResultsWindow = proposalResultsWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -195,8 +187,9 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
selectedVoteResultListItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue);
|
selectedVoteResultListItemListener = (observable, oldValue, newValue) -> onResultsListItemSelected(newValue);
|
||||||
|
|
||||||
createCyclesTable();
|
createCyclesTable();
|
||||||
exportButton = FormBuilder.addButton(root, ++gridRow, Res.get("shared.exportJSON"));
|
exportButton = addButton(root, ++gridRow, Res.get("shared.exportJSON"));
|
||||||
GridPane.setMargin(exportButton, new Insets(20, -10, -40, 0));
|
exportButton.getStyleClass().add("text-button");
|
||||||
|
GridPane.setMargin(exportButton, new Insets(10, -10, -50, 0));
|
||||||
GridPane.setColumnSpan(exportButton, 2);
|
GridPane.setColumnSpan(exportButton, 2);
|
||||||
GridPane.setHalignment(exportButton, HPos.RIGHT);
|
GridPane.setHalignment(exportButton, HPos.RIGHT);
|
||||||
}
|
}
|
||||||
|
@ -216,12 +209,9 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
GUIUtil.exportJSON("voteResultsHistory.json", cyclesJsonArray, (Stage) root.getScene().getWindow());
|
GUIUtil.exportJSON("voteResultsHistory.json", cyclesJsonArray, (Stage) root.getScene().getWindow());
|
||||||
});
|
});
|
||||||
if (proposalsTableView != null) {
|
if (proposalsTableView != null) {
|
||||||
GUIUtil.setFitToRowsForTableView(proposalsTableView, 25, 28, 2, 4);
|
GUIUtil.setFitToRowsForTableView(proposalsTableView, 25, 28, 6, 6);
|
||||||
}
|
}
|
||||||
if (votesTableView != null) {
|
GUIUtil.setFitToRowsForTableView(cyclesTableView, 25, 28, 6, 6);
|
||||||
GUIUtil.setFitToRowsForTableView(votesTableView, 25, 28, 2, 4);
|
|
||||||
}
|
|
||||||
GUIUtil.setFitToRowsForTableView(cyclesTableView, 25, 28, 2, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -336,17 +326,30 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
Optional<Ballot> optionalBallot = daoFacade.getAllValidBallots().stream()
|
Optional<Ballot> optionalBallot = daoFacade.getAllValidBallots().stream()
|
||||||
.filter(ballot -> ballot.getTxId().equals(evaluatedProposal.getProposalTxId()))
|
.filter(ballot -> ballot.getTxId().equals(evaluatedProposal.getProposalTxId()))
|
||||||
.findAny();
|
.findAny();
|
||||||
Ballot ballot = optionalBallot.orElse(null);
|
|
||||||
ProposalDisplay proposalDisplay = createProposalDisplay(evaluatedProposal, ballot);
|
|
||||||
createVotesTable();
|
|
||||||
|
|
||||||
|
Ballot ballot = optionalBallot.orElse(null);
|
||||||
// Check if my vote is included in result
|
// Check if my vote is included in result
|
||||||
boolean isVoteIncludedInResult = voteListItemList.stream()
|
boolean isVoteIncludedInResult = voteListItemList.stream()
|
||||||
.anyMatch(voteListItem -> bsqWalletService.getTransaction(voteListItem.getBlindVoteTxId()) != null);
|
.anyMatch(voteListItem -> bsqWalletService.getTransaction(voteListItem.getBlindVoteTxId()) != null);
|
||||||
proposalDisplay.setIsVoteIncludedInResult(isVoteIncludedInResult);
|
|
||||||
|
voteListItemList.clear();
|
||||||
|
resultsOfCycle.getEvaluatedProposals().stream()
|
||||||
|
.filter(evProposal -> evProposal.getProposal().equals(selectedProposalListItem.getEvaluatedProposal().getProposal()))
|
||||||
|
.forEach(evProposal -> resultsOfCycle.getDecryptedVotesForCycle().forEach(decryptedBallotsWithMerits ->
|
||||||
|
voteListItemList.add(new VoteListItem(evProposal.getProposal(), decryptedBallotsWithMerits,
|
||||||
|
daoStateService, bsqFormatter))));
|
||||||
|
|
||||||
|
voteListItemList.sort(Comparator.comparing(VoteListItem::getBlindVoteTxId));
|
||||||
|
|
||||||
|
showProposalResultWindow(evaluatedProposal, ballot, isVoteIncludedInResult, sortedVoteListItemList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showProposalResultWindow(EvaluatedProposal evaluatedProposal, Ballot ballot,
|
||||||
|
boolean isVoteIncludedInResult, SortedList<VoteListItem> sortedVoteListItemList) {
|
||||||
|
proposalResultsWindow.show(evaluatedProposal, ballot, isVoteIncludedInResult, sortedVoteListItemList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Fill lists: Cycle
|
// Fill lists: Cycle
|
||||||
|
@ -386,7 +389,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
|
|
||||||
maybeShowDaoTestingFeedbackWindow();
|
maybeShowDaoTestingFeedbackWindow();
|
||||||
|
|
||||||
GUIUtil.setFitToRowsForTableView(cyclesTableView, 25, 28, 2, 4);
|
GUIUtil.setFitToRowsForTableView(cyclesTableView, 25, 28, 6, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeShowDaoTestingFeedbackWindow() {
|
private void maybeShowDaoTestingFeedbackWindow() {
|
||||||
|
@ -450,7 +453,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
createProposalsColumns(proposalsTableView);
|
createProposalsColumns(proposalsTableView);
|
||||||
|
|
||||||
GridPane.setRowIndex(proposalsTableView, gridRow);
|
GridPane.setRowIndex(proposalsTableView, gridRow);
|
||||||
GridPane.setMargin(proposalsTableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, 5, -10));
|
GridPane.setMargin(proposalsTableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, 0, -10));
|
||||||
GridPane.setColumnSpan(proposalsTableView, 2);
|
GridPane.setColumnSpan(proposalsTableView, 2);
|
||||||
root.getChildren().add(proposalsTableView);
|
root.getChildren().add(proposalsTableView);
|
||||||
|
|
||||||
|
@ -477,81 +480,9 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
ballotByProposalTxIdMap.get(evaluatedProposal.getProposalTxId()),
|
ballotByProposalTxIdMap.get(evaluatedProposal.getProposalTxId()),
|
||||||
bsqFormatter))
|
bsqFormatter))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
GUIUtil.setFitToRowsForTableView(proposalsTableView, 25, 28, 2, 4);
|
GUIUtil.setFitToRowsForTableView(proposalsTableView, 25, 28, 6, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Create views: proposalDisplay
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private ProposalDisplay createProposalDisplay(EvaluatedProposal evaluatedProposal, Ballot ballot) {
|
|
||||||
Proposal proposal = evaluatedProposal.getProposal();
|
|
||||||
ProposalDisplay proposalDisplay = new ProposalDisplay(new GridPane(), bsqFormatter,
|
|
||||||
daoFacade, null, navigation, preferences);
|
|
||||||
|
|
||||||
ScrollPane proposalDisplayView = proposalDisplay.getView();
|
|
||||||
GridPane.setMargin(proposalDisplayView, new Insets(0, -10, -15, -10));
|
|
||||||
GridPane.setRowIndex(proposalDisplayView, ++gridRow);
|
|
||||||
GridPane.setColumnSpan(proposalDisplayView, 2);
|
|
||||||
GridPane.setHgrow(proposalDisplayView, Priority.ALWAYS);
|
|
||||||
root.getChildren().add(proposalDisplayView);
|
|
||||||
|
|
||||||
proposalDisplay.createAllFields(Res.get("dao.proposal.selectedProposal"), 0, 0,
|
|
||||||
proposal.getType(), false);
|
|
||||||
proposalDisplay.setEditable(false);
|
|
||||||
|
|
||||||
proposalDisplay.applyProposalPayload(proposal);
|
|
||||||
|
|
||||||
proposalDisplay.applyEvaluatedProposal(evaluatedProposal);
|
|
||||||
|
|
||||||
Tuple2<Long, Long> meritAndStakeTuple = daoFacade.getMeritAndStakeForProposal(proposal.getTxId());
|
|
||||||
long merit = meritAndStakeTuple.first;
|
|
||||||
long stake = meritAndStakeTuple.second;
|
|
||||||
proposalDisplay.applyBallotAndVoteWeight(ballot, merit, stake);
|
|
||||||
return proposalDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Create views: votesTableView
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void createVotesTable() {
|
|
||||||
TableGroupHeadline votesTableHeader = new TableGroupHeadline(Res.get("dao.results.proposals.voting.detail.header"));
|
|
||||||
GridPane.setRowIndex(votesTableHeader, ++gridRow);
|
|
||||||
GridPane.setMargin(votesTableHeader, new Insets(Layout.GROUP_DISTANCE, -10, -10, -10));
|
|
||||||
GridPane.setColumnSpan(votesTableHeader, 2);
|
|
||||||
root.getChildren().add(votesTableHeader);
|
|
||||||
|
|
||||||
votesTableView = new TableView<>();
|
|
||||||
votesTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData")));
|
|
||||||
votesTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
|
||||||
|
|
||||||
createColumns(votesTableView);
|
|
||||||
GridPane.setRowIndex(votesTableView, gridRow);
|
|
||||||
GridPane.setMargin(votesTableView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, -10, -15, -10));
|
|
||||||
GridPane.setColumnSpan(votesTableView, 2);
|
|
||||||
root.getChildren().add(votesTableView);
|
|
||||||
|
|
||||||
votesTableView.setItems(sortedVoteListItemList);
|
|
||||||
sortedVoteListItemList.comparatorProperty().bind(votesTableView.comparatorProperty());
|
|
||||||
|
|
||||||
voteListItemList.clear();
|
|
||||||
resultsOfCycle.getEvaluatedProposals().stream()
|
|
||||||
.filter(evaluatedProposal -> evaluatedProposal.getProposal().equals(selectedProposalListItem.getEvaluatedProposal().getProposal()))
|
|
||||||
.forEach(evaluatedProposal -> {
|
|
||||||
resultsOfCycle.getDecryptedVotesForCycle().forEach(decryptedBallotsWithMerits -> {
|
|
||||||
voteListItemList.add(new VoteListItem(evaluatedProposal.getProposal(), decryptedBallotsWithMerits,
|
|
||||||
daoStateService, bsqFormatter));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
voteListItemList.sort(Comparator.comparing(VoteListItem::getBlindVoteTxId));
|
|
||||||
GUIUtil.setFitToRowsForTableView(votesTableView, 25, 28, 2, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// TableColumns: CycleListItem
|
// TableColumns: CycleListItem
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -879,117 +810,6 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||||
votesTableView.getColumns().add(column);
|
votesTableView.getColumns().add(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// TableColumns: VoteListItem
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void createColumns(TableView<VoteListItem> votesTableView) {
|
|
||||||
TableColumn<VoteListItem, VoteListItem> column;
|
|
||||||
|
|
||||||
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.vote"));
|
|
||||||
column.setSortable(false);
|
|
||||||
column.setMinWidth(50);
|
|
||||||
column.setMaxWidth(column.getMinWidth());
|
|
||||||
column.getStyleClass().add("first-column");
|
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
|
||||||
column.setCellFactory(
|
|
||||||
new Callback<>() {
|
|
||||||
@Override
|
|
||||||
public TableCell<VoteListItem, VoteListItem> call(
|
|
||||||
TableColumn<VoteListItem, VoteListItem> column) {
|
|
||||||
return new TableCell<>() {
|
|
||||||
private Label icon;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateItem(final VoteListItem item, boolean empty) {
|
|
||||||
super.updateItem(item, empty);
|
|
||||||
|
|
||||||
if (item != null && !empty) {
|
|
||||||
Tuple2<AwesomeIcon, String> iconStyleTuple = item.getIconStyleTuple();
|
|
||||||
icon = new Label();
|
|
||||||
AwesomeDude.setIcon(icon, iconStyleTuple.first);
|
|
||||||
icon.getStyleClass().add(iconStyleTuple.second);
|
|
||||||
setGraphic(icon);
|
|
||||||
} else {
|
|
||||||
setGraphic(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
votesTableView.getColumns().add(column);
|
|
||||||
|
|
||||||
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit"));
|
|
||||||
column.setSortable(false);
|
|
||||||
column.setMinWidth(100);
|
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
|
||||||
column.setCellFactory(
|
|
||||||
new Callback<>() {
|
|
||||||
@Override
|
|
||||||
public TableCell<VoteListItem, VoteListItem> call(
|
|
||||||
TableColumn<VoteListItem, VoteListItem> column) {
|
|
||||||
return new TableCell<>() {
|
|
||||||
@Override
|
|
||||||
public void updateItem(final VoteListItem item, boolean empty) {
|
|
||||||
super.updateItem(item, empty);
|
|
||||||
if (item != null)
|
|
||||||
setText(item.getMeritAndStake());
|
|
||||||
else
|
|
||||||
setText("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
votesTableView.getColumns().add(column);
|
|
||||||
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit"));
|
|
||||||
column.setSortable(false);
|
|
||||||
column.setMinWidth(100);
|
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
|
||||||
column.setCellFactory(
|
|
||||||
new Callback<>() {
|
|
||||||
@Override
|
|
||||||
public TableCell<VoteListItem, VoteListItem> call(
|
|
||||||
TableColumn<VoteListItem, VoteListItem> column) {
|
|
||||||
return new TableCell<>() {
|
|
||||||
@Override
|
|
||||||
public void updateItem(final VoteListItem item, boolean empty) {
|
|
||||||
super.updateItem(item, empty);
|
|
||||||
if (item != null)
|
|
||||||
setText(item.getMerit());
|
|
||||||
else
|
|
||||||
setText("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
votesTableView.getColumns().add(column);
|
|
||||||
|
|
||||||
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake"));
|
|
||||||
column.setSortable(false);
|
|
||||||
column.setMinWidth(100);
|
|
||||||
column.getStyleClass().add("last-column");
|
|
||||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
|
||||||
column.setCellFactory(
|
|
||||||
new Callback<>() {
|
|
||||||
@Override
|
|
||||||
public TableCell<VoteListItem, VoteListItem> call(
|
|
||||||
TableColumn<VoteListItem, VoteListItem> column) {
|
|
||||||
return new TableCell<>() {
|
|
||||||
@Override
|
|
||||||
public void updateItem(final VoteListItem item, boolean empty) {
|
|
||||||
super.updateItem(item, empty);
|
|
||||||
if (item != null)
|
|
||||||
setText(item.getStake());
|
|
||||||
else
|
|
||||||
setText("");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
votesTableView.getColumns().add(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonElement getVotingHistoryJson() {
|
private JsonElement getVotingHistoryJson() {
|
||||||
JsonArray cyclesArray = new JsonArray();
|
JsonArray cyclesArray = new JsonArray();
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package bisq.desktop.main.dao.wallet;
|
package bisq.desktop.main.dao.wallet;
|
||||||
|
|
||||||
|
import bisq.desktop.components.TitledGroupBg;
|
||||||
import bisq.desktop.util.FormBuilder;
|
import bisq.desktop.util.FormBuilder;
|
||||||
import bisq.desktop.util.Layout;
|
import bisq.desktop.util.Layout;
|
||||||
|
|
||||||
|
@ -176,10 +177,12 @@ public class BsqBalanceUtil implements BsqBalanceListener, DaoStateListener {
|
||||||
return gridRow;
|
return gridRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int addBondBalanceGroup(GridPane gridPane, int gridRow) {
|
public int addBondBalanceGroup(GridPane gridPane, int gridRow, String groupStyle) {
|
||||||
addTitledGroupBg(gridPane, ++gridRow, 2,
|
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 2,
|
||||||
Res.get("dao.bond.dashboard.bondsHeadline"), Layout.GROUP_DISTANCE);
|
Res.get("dao.bond.dashboard.bondsHeadline"), Layout.GROUP_DISTANCE);
|
||||||
|
|
||||||
|
if (groupStyle != null) titledGroupBg.getStyleClass().add(groupStyle);
|
||||||
|
|
||||||
lockupAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(gridPane, gridRow,
|
lockupAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(gridPane, gridRow,
|
||||||
Res.get("dao.bond.dashboard.lockupAmount"),
|
Res.get("dao.bond.dashboard.lockupAmount"),
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
|
|
|
@ -20,6 +20,7 @@ package bisq.desktop.main.dao.wallet.dashboard;
|
||||||
import bisq.desktop.common.view.ActivatableView;
|
import bisq.desktop.common.view.ActivatableView;
|
||||||
import bisq.desktop.common.view.FxmlView;
|
import bisq.desktop.common.view.FxmlView;
|
||||||
import bisq.desktop.components.HyperlinkWithIcon;
|
import bisq.desktop.components.HyperlinkWithIcon;
|
||||||
|
import bisq.desktop.components.TitledGroupBg;
|
||||||
import bisq.desktop.main.dao.wallet.BsqBalanceUtil;
|
import bisq.desktop.main.dao.wallet.BsqBalanceUtil;
|
||||||
import bisq.desktop.util.FormBuilder;
|
import bisq.desktop.util.FormBuilder;
|
||||||
import bisq.desktop.util.Layout;
|
import bisq.desktop.util.Layout;
|
||||||
|
@ -96,24 +97,24 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||||
|
|
||||||
int startRow = gridRow;
|
int startRow = gridRow;
|
||||||
addTitledGroupBg(root, ++gridRow, 5, Res.get("dao.wallet.dashboard.distribution"), Layout.GROUP_DISTANCE);
|
addTitledGroupBg(root, ++gridRow, 5, Res.get("dao.wallet.dashboard.distribution"), Layout.GROUP_DISTANCE);
|
||||||
genesisIssueAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisIssueAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
genesisIssueAmountTextField = addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisIssueAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
compRequestIssueAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second;
|
compRequestIssueAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second;
|
||||||
reimbursementAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.reimbursementAmount")).second;
|
reimbursementAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.reimbursementAmount")).second;
|
||||||
burntAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second;
|
burntAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second;
|
||||||
availableAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second;
|
availableAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second;
|
||||||
|
|
||||||
gridRow = startRow;
|
gridRow = startRow;
|
||||||
addTitledGroupBg(root, ++gridRow, columnIndex, 5, Res.get("dao.wallet.dashboard.locked"), Layout.GROUP_DISTANCE);
|
addTitledGroupBg(root, ++gridRow, columnIndex, 5, Res.get("dao.wallet.dashboard.locked"), Layout.GROUP_DISTANCE);
|
||||||
totalLockedUpAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalLockedUpAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
totalLockedUpAmountTextField = addTopLabelReadOnlyTextField(root, gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalLockedUpAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
totalUnlockingAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalUnlockingAmount")).second;
|
totalUnlockingAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalUnlockingAmount")).second;
|
||||||
totalUnlockedAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalUnlockedAmount")).second;
|
totalUnlockedAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalUnlockedAmount")).second;
|
||||||
totalConfiscatedAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalConfiscatedAmount")).second;
|
totalConfiscatedAmountTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, Res.get("dao.wallet.dashboard.totalConfiscatedAmount")).second;
|
||||||
gridRow++;
|
gridRow++;
|
||||||
|
|
||||||
startRow = gridRow;
|
startRow = gridRow;
|
||||||
addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.wallet.dashboard.market"), Layout.GROUP_DISTANCE);
|
addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.wallet.dashboard.market"), Layout.GROUP_DISTANCE);
|
||||||
priceTextField = FormBuilder.addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.price"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
priceTextField = addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.price"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
marketCapTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.marketCap")).second;
|
marketCapTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.marketCap")).second;
|
||||||
|
|
||||||
gridRow = startRow;
|
gridRow = startRow;
|
||||||
addTitledGroupBg(root, ++gridRow, columnIndex, 2, Res.get("dao.wallet.dashboard.genesis"), Layout.GROUP_DISTANCE);
|
addTitledGroupBg(root, ++gridRow, columnIndex, 2, Res.get("dao.wallet.dashboard.genesis"), Layout.GROUP_DISTANCE);
|
||||||
|
@ -130,19 +131,21 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||||
hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", genesisTxId)));
|
hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", genesisTxId)));
|
||||||
|
|
||||||
startRow = gridRow;
|
startRow = gridRow;
|
||||||
addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.wallet.dashboard.txDetails"), Layout.GROUP_DISTANCE);
|
TitledGroupBg titledGroupBgTxDetails = addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.wallet.dashboard.txDetails"), Layout.GROUP_DISTANCE);
|
||||||
allTxTextField = FormBuilder.addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.allTx"),
|
titledGroupBgTxDetails.getStyleClass().add("last");
|
||||||
|
allTxTextField = addTopLabelReadOnlyTextField(root, gridRow, Res.get("dao.wallet.dashboard.allTx"),
|
||||||
genTxHeight, Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
genTxHeight, Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
utxoTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second;
|
utxoTextField = addTopLabelReadOnlyTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second;
|
||||||
compensationIssuanceTxTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow,
|
compensationIssuanceTxTextField = addTopLabelReadOnlyTextField(root, ++gridRow,
|
||||||
Res.get("dao.wallet.dashboard.compensationIssuanceTx")).second;
|
Res.get("dao.wallet.dashboard.compensationIssuanceTx")).second;
|
||||||
|
|
||||||
gridRow = startRow;
|
gridRow = startRow;
|
||||||
addTitledGroupBg(root, ++gridRow, columnIndex, 3, "", Layout.GROUP_DISTANCE);
|
TitledGroupBg titledGroupBgReImbursement = addTitledGroupBg(root, ++gridRow, columnIndex, 3, "", Layout.GROUP_DISTANCE);
|
||||||
reimbursementIssuanceTxTextField = FormBuilder.addTopLabelReadOnlyTextField(root, gridRow, columnIndex,
|
titledGroupBgReImbursement.getStyleClass().add("last");
|
||||||
|
reimbursementIssuanceTxTextField = addTopLabelReadOnlyTextField(root, gridRow, columnIndex,
|
||||||
Res.get("dao.wallet.dashboard.reimbursementIssuanceTx"),
|
Res.get("dao.wallet.dashboard.reimbursementIssuanceTx"),
|
||||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||||
burntTxTextField = FormBuilder.addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex,
|
burntTxTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex,
|
||||||
Res.get("dao.wallet.dashboard.burntTx")).second;
|
Res.get("dao.wallet.dashboard.burntTx")).second;
|
||||||
++gridRow;
|
++gridRow;
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class BsqReceiveView extends ActivatableView<GridPane, Void> {
|
||||||
|
|
||||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1,
|
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 1,
|
||||||
Res.get("dao.wallet.receive.fundYourWallet"), Layout.GROUP_DISTANCE);
|
Res.get("dao.wallet.receive.fundYourWallet"), Layout.GROUP_DISTANCE);
|
||||||
|
titledGroupBg.getStyleClass().add("last");
|
||||||
GridPane.setColumnSpan(titledGroupBg, 3);
|
GridPane.setColumnSpan(titledGroupBg, 3);
|
||||||
Tuple3<Label, BsqAddressTextField, VBox> tuple = addLabelBsqAddressTextField(root, gridRow,
|
Tuple3<Label, BsqAddressTextField, VBox> tuple = addLabelBsqAddressTextField(root, gridRow,
|
||||||
Res.get("dao.wallet.receive.bsqAddress"),
|
Res.get("dao.wallet.receive.bsqAddress"),
|
||||||
|
|
|
@ -125,6 +125,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
int extraRows = screenSize <= INITIAL_WINDOW_HEIGHT ? 0 : (int) ((screenSize - INITIAL_WINDOW_HEIGHT) / pixelsPerOfferTableRow);
|
int extraRows = screenSize <= INITIAL_WINDOW_HEIGHT ? 0 : (int) ((screenSize - INITIAL_WINDOW_HEIGHT) / pixelsPerOfferTableRow);
|
||||||
return extraRows == 0 ? initialOfferTableViewHeight : Math.ceil(initialOfferTableViewHeight + ((extraRows + 1) * pixelsPerOfferTableRow));
|
return extraRows == 0 ? initialOfferTableViewHeight : Math.ceil(initialOfferTableViewHeight + ((extraRows + 1) * pixelsPerOfferTableRow));
|
||||||
};
|
};
|
||||||
|
private ChangeListener<Number> bisqWindowVerticalSizeListener;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, lifecycle
|
// Constructor, lifecycle
|
||||||
|
@ -141,12 +142,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
changeListener = c -> updateChartData();
|
createListener();
|
||||||
|
|
||||||
currencyListItemsListener = c -> {
|
|
||||||
if (model.getSelectedCurrencyListItem().isPresent())
|
|
||||||
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());
|
|
||||||
};
|
|
||||||
|
|
||||||
final Tuple3<VBox, Label, ComboBox<CurrencyListItem>> currencyComboBoxTuple = addTopLabelComboBox(Res.get("shared.currency"),
|
final Tuple3<VBox, Label, ComboBox<CurrencyListItem>> currencyComboBoxTuple = addTopLabelComboBox(Res.get("shared.currency"),
|
||||||
Res.get("list.currency.select"), 0);
|
Res.get("list.currency.select"), 0);
|
||||||
|
@ -268,6 +264,23 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
|
|
||||||
buyOfferTableView.setItems(model.getTopBuyOfferList());
|
buyOfferTableView.setItems(model.getTopBuyOfferList());
|
||||||
sellOfferTableView.setItems(model.getTopSellOfferList());
|
sellOfferTableView.setItems(model.getTopSellOfferList());
|
||||||
|
|
||||||
|
buyOfferTableView.getSelectionModel().selectedItemProperty().addListener(buyTableRowSelectionListener);
|
||||||
|
sellOfferTableView.getSelectionModel().selectedItemProperty().addListener(sellTableRowSelectionListener);
|
||||||
|
|
||||||
|
root.getScene().heightProperty().addListener(bisqWindowVerticalSizeListener);
|
||||||
|
|
||||||
|
updateChartData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createListener() {
|
||||||
|
changeListener = c -> updateChartData();
|
||||||
|
|
||||||
|
currencyListItemsListener = c -> {
|
||||||
|
if (model.getSelectedCurrencyListItem().isPresent())
|
||||||
|
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());
|
||||||
|
};
|
||||||
|
|
||||||
buyTableRowSelectionListener = (observable, oldValue, newValue) -> {
|
buyTableRowSelectionListener = (observable, oldValue, newValue) -> {
|
||||||
model.preferences.setSellScreenCurrencyCode(model.getCurrencyCode());
|
model.preferences.setSellScreenCurrencyCode(model.getCurrencyCode());
|
||||||
navigation.navigateTo(MainView.class, SellOfferView.class);
|
navigation.navigateTo(MainView.class, SellOfferView.class);
|
||||||
|
@ -276,19 +289,14 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
model.preferences.setBuyScreenCurrencyCode(model.getCurrencyCode());
|
model.preferences.setBuyScreenCurrencyCode(model.getCurrencyCode());
|
||||||
navigation.navigateTo(MainView.class, BuyOfferView.class);
|
navigation.navigateTo(MainView.class, BuyOfferView.class);
|
||||||
};
|
};
|
||||||
buyOfferTableView.getSelectionModel().selectedItemProperty().addListener(buyTableRowSelectionListener);
|
|
||||||
sellOfferTableView.getSelectionModel().selectedItemProperty().addListener(sellTableRowSelectionListener);
|
|
||||||
|
|
||||||
ChangeListener<Number> bisqWindowVerticalSizeListener = (observable, oldValue, newValue) -> {
|
bisqWindowVerticalSizeListener = (observable, oldValue, newValue) -> {
|
||||||
double newTableViewHeight = offerTableViewHeight.apply(newValue.doubleValue());
|
double newTableViewHeight = offerTableViewHeight.apply(newValue.doubleValue());
|
||||||
if (buyOfferTableView.getHeight() != newTableViewHeight) {
|
if (buyOfferTableView.getHeight() != newTableViewHeight) {
|
||||||
buyOfferTableView.setMinHeight(newTableViewHeight);
|
buyOfferTableView.setMinHeight(newTableViewHeight);
|
||||||
sellOfferTableView.setMinHeight(newTableViewHeight);
|
sellOfferTableView.setMinHeight(newTableViewHeight);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
root.getScene().heightProperty().addListener(bisqWindowVerticalSizeListener);
|
|
||||||
|
|
||||||
updateChartData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -60,6 +60,7 @@ import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.transform.Rotate;
|
import javafx.scene.transform.Rotate;
|
||||||
|
|
||||||
|
@ -499,7 +500,7 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
Scene rootScene = owner.getScene();
|
Scene rootScene = owner.getScene();
|
||||||
if (rootScene != null) {
|
if (rootScene != null) {
|
||||||
Scene scene = new Scene(gridPane);
|
Scene scene = new Scene(getRootContainer());
|
||||||
scene.getStylesheets().setAll(rootScene.getStylesheets());
|
scene.getStylesheets().setAll(rootScene.getStylesheets());
|
||||||
scene.setFill(Color.TRANSPARENT);
|
scene.setFill(Color.TRANSPARENT);
|
||||||
|
|
||||||
|
@ -544,6 +545,11 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Region getRootContainer() {
|
||||||
|
return gridPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setupKeyHandler(Scene scene) {
|
protected void setupKeyHandler(Scene scene) {
|
||||||
if (!hideCloseButton) {
|
if (!hideCloseButton) {
|
||||||
scene.setOnKeyPressed(e -> {
|
scene.setOnKeyPressed(e -> {
|
||||||
|
@ -556,66 +562,68 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void animateDisplay() {
|
protected void animateDisplay() {
|
||||||
gridPane.setOpacity(0);
|
Region rootContainer = this.getRootContainer();
|
||||||
|
|
||||||
|
rootContainer.setOpacity(0);
|
||||||
Interpolator interpolator = Interpolator.SPLINE(0.25, 0.1, 0.25, 1);
|
Interpolator interpolator = Interpolator.SPLINE(0.25, 0.1, 0.25, 1);
|
||||||
double duration = getDuration(400);
|
double duration = getDuration(400);
|
||||||
Timeline timeline = new Timeline();
|
Timeline timeline = new Timeline();
|
||||||
ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
|
ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
|
||||||
|
|
||||||
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
||||||
double startY = -gridPane.getHeight();
|
double startY = -rootContainer.getHeight();
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.translateYProperty(), startY, interpolator)
|
new KeyValue(rootContainer.translateYProperty(), startY, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.translateYProperty(), -50, interpolator)
|
new KeyValue(rootContainer.translateYProperty(), -50, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.ScaleFromCenter) {
|
} else if (type.animationType == AnimationType.ScaleFromCenter) {
|
||||||
double startScale = 0.25;
|
double startScale = 0.25;
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), startScale, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), startScale, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), startScale, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), startScale, interpolator)
|
||||||
|
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), 1, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), 1, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.ScaleYFromCenter) {
|
} else if (type.animationType == AnimationType.ScaleYFromCenter) {
|
||||||
double startYScale = 0.25;
|
double startYScale = 0.25;
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), startYScale, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), startYScale, interpolator)
|
||||||
|
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), 1, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.ScaleDownToCenter) {
|
} else if (type.animationType == AnimationType.ScaleDownToCenter) {
|
||||||
double startScale = 1.1;
|
double startScale = 1.1;
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), startScale, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), startScale, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), startScale, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), startScale, interpolator)
|
||||||
|
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), 1, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), 1, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.FadeInAtCenter) {
|
} else if (type.animationType == AnimationType.FadeInAtCenter) {
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator)
|
||||||
|
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,15 +636,16 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
Timeline timeline = new Timeline();
|
Timeline timeline = new Timeline();
|
||||||
ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
|
ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
|
||||||
|
|
||||||
|
Region rootContainer = getRootContainer();
|
||||||
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
||||||
double endY = -gridPane.getHeight();
|
double endY = -rootContainer.getHeight();
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.translateYProperty(), -10, interpolator)
|
new KeyValue(rootContainer.translateYProperty(), -10, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.translateYProperty(), endY, interpolator)
|
new KeyValue(rootContainer.translateYProperty(), endY, interpolator)
|
||||||
));
|
));
|
||||||
|
|
||||||
timeline.setOnFinished(e -> onFinishedHandler.run());
|
timeline.setOnFinished(e -> onFinishedHandler.run());
|
||||||
|
@ -644,44 +653,44 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
} else if (type.animationType == AnimationType.ScaleFromCenter) {
|
} else if (type.animationType == AnimationType.ScaleFromCenter) {
|
||||||
double endScale = 0.25;
|
double endScale = 0.25;
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), 1, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), 1, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), endScale, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), endScale, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), endScale, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), endScale, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.ScaleYFromCenter) {
|
} else if (type.animationType == AnimationType.ScaleYFromCenter) {
|
||||||
gridPane.setRotationAxis(Rotate.X_AXIS);
|
rootContainer.setRotationAxis(Rotate.X_AXIS);
|
||||||
gridPane.getScene().setCamera(new PerspectiveCamera());
|
rootContainer.getScene().setCamera(new PerspectiveCamera());
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.rotateProperty(), 0, interpolator),
|
new KeyValue(rootContainer.rotateProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.rotateProperty(), -90, interpolator),
|
new KeyValue(rootContainer.rotateProperty(), -90, interpolator),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.ScaleDownToCenter) {
|
} else if (type.animationType == AnimationType.ScaleDownToCenter) {
|
||||||
double endScale = 0.1;
|
double endScale = 0.1;
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), 1, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), 1, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), 1, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator),
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator),
|
||||||
new KeyValue(gridPane.scaleXProperty(), endScale, interpolator),
|
new KeyValue(rootContainer.scaleXProperty(), endScale, interpolator),
|
||||||
new KeyValue(gridPane.scaleYProperty(), endScale, interpolator)
|
new KeyValue(rootContainer.scaleYProperty(), endScale, interpolator)
|
||||||
));
|
));
|
||||||
} else if (type.animationType == AnimationType.FadeInAtCenter) {
|
} else if (type.animationType == AnimationType.FadeInAtCenter) {
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(0),
|
keyFrames.add(new KeyFrame(Duration.millis(0),
|
||||||
new KeyValue(gridPane.opacityProperty(), 1, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 1, interpolator)
|
||||||
));
|
));
|
||||||
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
keyFrames.add(new KeyFrame(Duration.millis(duration),
|
||||||
new KeyValue(gridPane.opacityProperty(), 0, interpolator)
|
new KeyValue(rootContainer.opacityProperty(), 0, interpolator)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,10 +727,11 @@ public abstract class Overlay<T extends Overlay> {
|
||||||
|
|
||||||
|
|
||||||
protected void applyStyles() {
|
protected void applyStyles() {
|
||||||
|
Region rootContainer = getRootContainer();
|
||||||
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
if (type.animationType == AnimationType.SlideDownFromCenterTop) {
|
||||||
gridPane.getStyleClass().add("popup-bg-top");
|
rootContainer.getStyleClass().add("popup-bg-top");
|
||||||
} else {
|
} else {
|
||||||
gridPane.getStyleClass().add("popup-bg");
|
rootContainer.getStyleClass().add("popup-bg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package bisq.desktop.main.overlays;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXTabPane;
|
||||||
|
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
|
public abstract class TabbedOverlay<T extends TabbedOverlay> extends Overlay {
|
||||||
|
|
||||||
|
protected JFXTabPane tabPane;
|
||||||
|
|
||||||
|
protected void createTabPane() {
|
||||||
|
this.tabPane = new JFXTabPane();
|
||||||
|
tabPane.setMinWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Region getRootContainer() {
|
||||||
|
return tabPane;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,326 @@
|
||||||
|
package bisq.desktop.main.overlays.windows;
|
||||||
|
|
||||||
|
import bisq.desktop.Navigation;
|
||||||
|
import bisq.desktop.components.AutoTooltipLabel;
|
||||||
|
import bisq.desktop.components.AutoTooltipTableColumn;
|
||||||
|
import bisq.desktop.components.TableGroupHeadline;
|
||||||
|
import bisq.desktop.main.dao.governance.ProposalDisplay;
|
||||||
|
import bisq.desktop.main.dao.governance.result.VoteListItem;
|
||||||
|
import bisq.desktop.main.overlays.TabbedOverlay;
|
||||||
|
import bisq.desktop.util.Layout;
|
||||||
|
|
||||||
|
import bisq.core.dao.DaoFacade;
|
||||||
|
import bisq.core.dao.governance.proposal.param.ChangeParamValidator;
|
||||||
|
import bisq.core.dao.state.model.governance.Ballot;
|
||||||
|
import bisq.core.dao.state.model.governance.EvaluatedProposal;
|
||||||
|
import bisq.core.dao.state.model.governance.Proposal;
|
||||||
|
import bisq.core.locale.Res;
|
||||||
|
import bisq.core.user.Preferences;
|
||||||
|
import bisq.core.util.BsqFormatter;
|
||||||
|
|
||||||
|
import bisq.common.util.Tuple2;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||||
|
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||||
|
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Tab;
|
||||||
|
import javafx.scene.control.TableCell;
|
||||||
|
import javafx.scene.control.TableColumn;
|
||||||
|
import javafx.scene.control.TableView;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.layout.ColumnConstraints;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
|
import javafx.geometry.HPos;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
|
||||||
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
|
|
||||||
|
import javafx.collections.transformation.SortedList;
|
||||||
|
|
||||||
|
import javafx.util.Callback;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import static bisq.desktop.util.FormBuilder.addButtonAfterGroup;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ProposalResultsWindow extends TabbedOverlay<ProposalResultsWindow> {
|
||||||
|
|
||||||
|
private final BsqFormatter bsqFormatter;
|
||||||
|
private final DaoFacade daoFacade;
|
||||||
|
private final ChangeParamValidator changeParamValidator;
|
||||||
|
private final Navigation navigation;
|
||||||
|
private final Preferences preferences;
|
||||||
|
private Optional<Runnable> acceptHandlerOptional;
|
||||||
|
private Optional<Runnable> rejectHandlerOptional;
|
||||||
|
private Optional<Runnable> ignoreHandlerOptional;
|
||||||
|
private Optional<Runnable> removeHandlerOptional;
|
||||||
|
private EvaluatedProposal evaluatedProposal;
|
||||||
|
private Ballot ballot;
|
||||||
|
private boolean isVoteIncludedInResult;
|
||||||
|
private SortedList<VoteListItem> sortedVotes;
|
||||||
|
private Tab proposalTab, votesTab;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public API
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProposalResultsWindow(BsqFormatter bsqFormatter, DaoFacade daoFacade,
|
||||||
|
ChangeParamValidator changeParamValidator, Navigation navigation,
|
||||||
|
Preferences preferences) {
|
||||||
|
this.bsqFormatter = bsqFormatter;
|
||||||
|
this.daoFacade = daoFacade;
|
||||||
|
this.changeParamValidator = changeParamValidator;
|
||||||
|
this.navigation = navigation;
|
||||||
|
this.preferences = preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(EvaluatedProposal evaluatedProposal, Ballot ballot,
|
||||||
|
boolean isVoteIncludedInResult, SortedList<VoteListItem> sortedVotes) {
|
||||||
|
|
||||||
|
this.evaluatedProposal = evaluatedProposal;
|
||||||
|
this.ballot = ballot;
|
||||||
|
this.isVoteIncludedInResult = isVoteIncludedInResult;
|
||||||
|
this.sortedVotes = sortedVotes;
|
||||||
|
|
||||||
|
rowIndex = 0;
|
||||||
|
width = 1000;
|
||||||
|
createTabPane();
|
||||||
|
createGridPane();
|
||||||
|
addContent(evaluatedProposal, ballot);
|
||||||
|
|
||||||
|
display();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTabs() {
|
||||||
|
proposalTab = new Tab("PROPOSAL");
|
||||||
|
votesTab = new Tab("VOTES");
|
||||||
|
|
||||||
|
tabPane.getTabs().addAll(proposalTab, votesTab);
|
||||||
|
|
||||||
|
tabPane.getSelectionModel().selectedItemProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
|
if (newValue != oldValue) {
|
||||||
|
stage.sizeToScene();
|
||||||
|
layout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onShow() {
|
||||||
|
super.onShow();
|
||||||
|
|
||||||
|
setupCloseKeyHandler(stage.getScene());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createGridPane() {
|
||||||
|
super.createGridPane();
|
||||||
|
gridPane.getColumnConstraints().remove(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addContent(EvaluatedProposal evaluatedProposal, Ballot ballot) {
|
||||||
|
Proposal proposal = evaluatedProposal.getProposal();
|
||||||
|
ProposalDisplay proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, daoFacade, null,
|
||||||
|
navigation, preferences);
|
||||||
|
proposalDisplay.createAllFields("", rowIndex, -Layout.FIRST_ROW_DISTANCE, proposal.getType(),
|
||||||
|
false, "last");
|
||||||
|
proposalDisplay.setEditable(false);
|
||||||
|
|
||||||
|
proposalDisplay.applyProposalPayload(proposal);
|
||||||
|
proposalDisplay.applyEvaluatedProposal(evaluatedProposal);
|
||||||
|
proposalDisplay.setIsVoteIncludedInResult(isVoteIncludedInResult);
|
||||||
|
|
||||||
|
Tuple2<Long, Long> meritAndStakeTuple = daoFacade.getMeritAndStakeForProposal(proposal.getTxId());
|
||||||
|
long merit = meritAndStakeTuple.first;
|
||||||
|
long stake = meritAndStakeTuple.second;
|
||||||
|
proposalDisplay.applyBallotAndVoteWeight(ballot, merit, stake);
|
||||||
|
|
||||||
|
Region spacer = new Region();
|
||||||
|
GridPane.setVgrow(spacer, Priority.ALWAYS);
|
||||||
|
GridPane.setRowIndex(spacer, proposalDisplay.incrementAndGetGridRow());
|
||||||
|
gridPane.getChildren().add(spacer);
|
||||||
|
|
||||||
|
addCloseButton(gridPane, proposalDisplay.incrementAndGetGridRow());
|
||||||
|
|
||||||
|
createTabs();
|
||||||
|
|
||||||
|
gridPane.setPadding(new Insets(0, 15, 15, 15));
|
||||||
|
proposalTab.setContent(gridPane);
|
||||||
|
votesTab.setContent(createVotesTable());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button addCloseButton(GridPane gridPane, int rowIndex) {
|
||||||
|
Button closeButton = addButtonAfterGroup(gridPane, rowIndex, Res.get("shared.close"));
|
||||||
|
closeButton.setOnAction(event -> doClose());
|
||||||
|
return closeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridPane createVotesTable() {
|
||||||
|
GridPane votesGridPane = new GridPane();
|
||||||
|
votesGridPane.setHgap(5);
|
||||||
|
votesGridPane.setVgap(5);
|
||||||
|
votesGridPane.setPadding(new Insets(15));
|
||||||
|
|
||||||
|
ColumnConstraints columnConstraints1 = new ColumnConstraints();
|
||||||
|
columnConstraints1.setHalignment(HPos.RIGHT);
|
||||||
|
columnConstraints1.setHgrow(Priority.ALWAYS);
|
||||||
|
votesGridPane.getColumnConstraints().addAll(columnConstraints1);
|
||||||
|
|
||||||
|
int gridRow = 0;
|
||||||
|
|
||||||
|
TableGroupHeadline votesTableHeader = new TableGroupHeadline(Res.get("dao.results.proposals.voting.detail.header"));
|
||||||
|
GridPane.setRowIndex(votesTableHeader, gridRow);
|
||||||
|
GridPane.setMargin(votesTableHeader, new Insets(8, 0, 0, 0));
|
||||||
|
GridPane.setColumnSpan(votesTableHeader, 2);
|
||||||
|
votesGridPane.getChildren().add(votesTableHeader);
|
||||||
|
|
||||||
|
TableView votesTableView = new TableView<>();
|
||||||
|
votesTableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData")));
|
||||||
|
votesTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
|
|
||||||
|
createColumns(votesTableView);
|
||||||
|
GridPane.setRowIndex(votesTableView, gridRow);
|
||||||
|
GridPane.setMargin(votesTableView, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 0));
|
||||||
|
GridPane.setColumnSpan(votesTableView, 2);
|
||||||
|
GridPane.setVgrow(votesTableView, Priority.ALWAYS);
|
||||||
|
votesGridPane.getChildren().add(votesTableView);
|
||||||
|
|
||||||
|
votesTableView.setItems(sortedVotes);
|
||||||
|
|
||||||
|
addCloseButton(votesGridPane, ++gridRow);
|
||||||
|
|
||||||
|
return votesGridPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createColumns(TableView<VoteListItem> votesTableView) {
|
||||||
|
TableColumn<VoteListItem, VoteListItem> column;
|
||||||
|
|
||||||
|
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.vote"));
|
||||||
|
column.setSortable(false);
|
||||||
|
column.setMinWidth(50);
|
||||||
|
column.setMaxWidth(column.getMinWidth());
|
||||||
|
column.getStyleClass().add("first-column");
|
||||||
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
|
column.setCellFactory(
|
||||||
|
new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public TableCell<VoteListItem, VoteListItem> call(
|
||||||
|
TableColumn<VoteListItem, VoteListItem> column) {
|
||||||
|
return new TableCell<>() {
|
||||||
|
private Label icon;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(final VoteListItem item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
|
if (item != null && !empty) {
|
||||||
|
Tuple2<AwesomeIcon, String> iconStyleTuple = item.getIconStyleTuple();
|
||||||
|
icon = new Label();
|
||||||
|
AwesomeDude.setIcon(icon, iconStyleTuple.first);
|
||||||
|
icon.getStyleClass().add(iconStyleTuple.second);
|
||||||
|
setGraphic(icon);
|
||||||
|
} else {
|
||||||
|
setGraphic(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
votesTableView.getColumns().add(column);
|
||||||
|
|
||||||
|
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stakeAndMerit"));
|
||||||
|
column.setSortable(false);
|
||||||
|
column.setMinWidth(100);
|
||||||
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
|
column.setCellFactory(
|
||||||
|
new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public TableCell<VoteListItem, VoteListItem> call(
|
||||||
|
TableColumn<VoteListItem, VoteListItem> column) {
|
||||||
|
return new TableCell<>() {
|
||||||
|
@Override
|
||||||
|
public void updateItem(final VoteListItem item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (item != null)
|
||||||
|
setText(item.getMeritAndStake());
|
||||||
|
else
|
||||||
|
setText("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
votesTableView.getColumns().add(column);
|
||||||
|
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.merit"));
|
||||||
|
column.setSortable(false);
|
||||||
|
column.setMinWidth(100);
|
||||||
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
|
column.setCellFactory(
|
||||||
|
new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public TableCell<VoteListItem, VoteListItem> call(
|
||||||
|
TableColumn<VoteListItem, VoteListItem> column) {
|
||||||
|
return new TableCell<>() {
|
||||||
|
@Override
|
||||||
|
public void updateItem(final VoteListItem item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (item != null)
|
||||||
|
setText(item.getMerit());
|
||||||
|
else
|
||||||
|
setText("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
votesTableView.getColumns().add(column);
|
||||||
|
|
||||||
|
column = new AutoTooltipTableColumn<>(Res.get("dao.results.votes.table.header.stake"));
|
||||||
|
column.setSortable(false);
|
||||||
|
column.setMinWidth(100);
|
||||||
|
column.getStyleClass().add("last-column");
|
||||||
|
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||||
|
column.setCellFactory(
|
||||||
|
new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public TableCell<VoteListItem, VoteListItem> call(
|
||||||
|
TableColumn<VoteListItem, VoteListItem> column) {
|
||||||
|
return new TableCell<>() {
|
||||||
|
@Override
|
||||||
|
public void updateItem(final VoteListItem item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (item != null)
|
||||||
|
setText(item.getStake());
|
||||||
|
else
|
||||||
|
setText("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
votesTableView.getColumns().add(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupCloseKeyHandler(Scene scene) {
|
||||||
|
scene.setOnKeyPressed(e -> {
|
||||||
|
if (e.getCode() == KeyCode.ESCAPE || e.getCode() == KeyCode.ENTER) {
|
||||||
|
e.consume();
|
||||||
|
doClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
package bisq.desktop.main.overlays.windows;
|
||||||
|
|
||||||
|
import bisq.desktop.Navigation;
|
||||||
|
import bisq.desktop.main.dao.governance.ProposalDisplay;
|
||||||
|
import bisq.desktop.main.overlays.Overlay;
|
||||||
|
import bisq.desktop.util.Layout;
|
||||||
|
|
||||||
|
import bisq.core.dao.DaoFacade;
|
||||||
|
import bisq.core.dao.governance.myvote.MyVote;
|
||||||
|
import bisq.core.dao.governance.proposal.param.ChangeParamValidator;
|
||||||
|
import bisq.core.dao.state.model.governance.Ballot;
|
||||||
|
import bisq.core.dao.state.model.governance.DaoPhase;
|
||||||
|
import bisq.core.dao.state.model.governance.EvaluatedProposal;
|
||||||
|
import bisq.core.dao.state.model.governance.Proposal;
|
||||||
|
import bisq.core.dao.state.model.governance.Vote;
|
||||||
|
import bisq.core.locale.Res;
|
||||||
|
import bisq.core.user.Preferences;
|
||||||
|
import bisq.core.util.BsqFormatter;
|
||||||
|
|
||||||
|
import bisq.common.util.Tuple2;
|
||||||
|
import bisq.common.util.Tuple3;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static bisq.desktop.util.FormBuilder.add2ButtonsAfterGroup;
|
||||||
|
import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup;
|
||||||
|
import static bisq.desktop.util.FormBuilder.addButtonAfterGroup;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SelectProposalWindow extends Overlay<SelectProposalWindow> {
|
||||||
|
|
||||||
|
private final BsqFormatter bsqFormatter;
|
||||||
|
private final DaoFacade daoFacade;
|
||||||
|
private final ChangeParamValidator changeParamValidator;
|
||||||
|
private final Navigation navigation;
|
||||||
|
private final Preferences preferences;
|
||||||
|
private Optional<Runnable> acceptHandlerOptional;
|
||||||
|
private Optional<Runnable> rejectHandlerOptional;
|
||||||
|
private Optional<Runnable> ignoreHandlerOptional;
|
||||||
|
private Optional<Runnable> removeHandlerOptional;
|
||||||
|
private Proposal proposal;
|
||||||
|
private EvaluatedProposal evaluatedProposal;
|
||||||
|
private Ballot ballot;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public API
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SelectProposalWindow(BsqFormatter bsqFormatter, DaoFacade daoFacade,
|
||||||
|
ChangeParamValidator changeParamValidator, Navigation navigation,
|
||||||
|
Preferences preferences) {
|
||||||
|
this.bsqFormatter = bsqFormatter;
|
||||||
|
this.daoFacade = daoFacade;
|
||||||
|
this.changeParamValidator = changeParamValidator;
|
||||||
|
this.navigation = navigation;
|
||||||
|
this.preferences = preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(Proposal proposal, EvaluatedProposal evaluatedProposal, Ballot ballot) {
|
||||||
|
|
||||||
|
this.proposal = proposal;
|
||||||
|
this.evaluatedProposal = evaluatedProposal;
|
||||||
|
this.ballot = ballot;
|
||||||
|
|
||||||
|
rowIndex = 0;
|
||||||
|
width = 1000;
|
||||||
|
createGridPane();
|
||||||
|
headLine(Res.get("dao.proposal.selectedProposal"));
|
||||||
|
message("");
|
||||||
|
hideCloseButton();
|
||||||
|
super.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onAccept(Runnable acceptHandler) {
|
||||||
|
this.acceptHandlerOptional = Optional.of(acceptHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onReject(Runnable rejectHandler) {
|
||||||
|
this.rejectHandlerOptional = Optional.of(rejectHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onIgnore(Runnable ignoreHandler) {
|
||||||
|
this.ignoreHandlerOptional = Optional.of(ignoreHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRemove(Runnable removeHandler) {
|
||||||
|
this.removeHandlerOptional = Optional.of(removeHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createGridPane() {
|
||||||
|
super.createGridPane();
|
||||||
|
gridPane.getColumnConstraints().remove(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onShow() {
|
||||||
|
|
||||||
|
display();
|
||||||
|
|
||||||
|
setupCloseKeyHandler(stage.getScene());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addMessage() {
|
||||||
|
super.addMessage();
|
||||||
|
|
||||||
|
addContent(proposal, evaluatedProposal, ballot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addContent(Proposal proposal, EvaluatedProposal evaluatedProposal, Ballot ballot) {
|
||||||
|
ProposalDisplay proposalDisplay = new ProposalDisplay(gridPane, bsqFormatter, daoFacade, changeParamValidator,
|
||||||
|
navigation, preferences);
|
||||||
|
proposalDisplay.createAllFields("", rowIndex, -Layout.FIRST_ROW_DISTANCE, proposal.getType(),
|
||||||
|
false, "last");
|
||||||
|
proposalDisplay.setEditable(false);
|
||||||
|
proposalDisplay.applyProposalPayload(proposal);
|
||||||
|
proposalDisplay.applyEvaluatedProposal(evaluatedProposal);
|
||||||
|
|
||||||
|
Tuple2<Long, Long> meritAndStakeTuple = daoFacade.getMeritAndStakeForProposal(proposal.getTxId());
|
||||||
|
long merit = meritAndStakeTuple.first;
|
||||||
|
long stake = meritAndStakeTuple.second;
|
||||||
|
proposalDisplay.applyBallotAndVoteWeight(ballot, merit, stake);
|
||||||
|
|
||||||
|
|
||||||
|
List<MyVote> myVoteListForCycle = daoFacade.getMyVoteListForCycle();
|
||||||
|
boolean hasAlreadyVoted = !myVoteListForCycle.isEmpty();
|
||||||
|
|
||||||
|
DaoPhase.Phase currentPhase = daoFacade.phaseProperty().get();
|
||||||
|
|
||||||
|
if (currentPhase == DaoPhase.Phase.PROPOSAL) {
|
||||||
|
|
||||||
|
Tuple2<Button, Button> proposalPhaseButtonsTuple = add2ButtonsAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("shared.remove"), Res.get("shared.close"));
|
||||||
|
Button removeProposalButton = proposalPhaseButtonsTuple.first;
|
||||||
|
|
||||||
|
boolean doShowRemoveButton = daoFacade.isMyProposal(proposal);
|
||||||
|
|
||||||
|
removeProposalButton.setOnAction(event -> {
|
||||||
|
removeHandlerOptional.ifPresent(Runnable::run);
|
||||||
|
doClose();
|
||||||
|
});
|
||||||
|
removeProposalButton.setVisible(doShowRemoveButton);
|
||||||
|
removeProposalButton.setManaged(doShowRemoveButton);
|
||||||
|
|
||||||
|
proposalPhaseButtonsTuple.second.setOnAction(event -> doClose());
|
||||||
|
|
||||||
|
} else if (currentPhase == DaoPhase.Phase.BLIND_VOTE &&
|
||||||
|
!hasAlreadyVoted &&
|
||||||
|
daoFacade.isInPhaseButNotLastBlock(currentPhase)) {
|
||||||
|
int rowIndexForVoting = proposalDisplay.incrementAndGetGridRow();
|
||||||
|
Tuple3<Button, Button, Button> tuple = add3ButtonsAfterGroup(gridPane,
|
||||||
|
rowIndexForVoting,
|
||||||
|
Res.get("dao.proposal.myVote.accept"),
|
||||||
|
Res.get("dao.proposal.myVote.reject"),
|
||||||
|
Res.get("dao.proposal.myVote.removeMyVote"));
|
||||||
|
Button acceptButton = tuple.first;
|
||||||
|
acceptButton.setDefaultButton(false);
|
||||||
|
Button rejectButton = tuple.second;
|
||||||
|
Button ignoreButton = tuple.third;
|
||||||
|
|
||||||
|
// show if already voted
|
||||||
|
proposalDisplay.applyBallot(ballot);
|
||||||
|
|
||||||
|
Optional<Vote> optionalVote = getVote(ballot);
|
||||||
|
boolean isPresent = optionalVote.isPresent();
|
||||||
|
boolean isAccepted = isPresent && optionalVote.get().isAccepted();
|
||||||
|
acceptButton.setDisable((isPresent && isAccepted));
|
||||||
|
rejectButton.setDisable((isPresent && !isAccepted));
|
||||||
|
ignoreButton.setDisable(!isPresent);
|
||||||
|
|
||||||
|
acceptButton.setOnAction(event -> {
|
||||||
|
acceptHandlerOptional.ifPresent(Runnable::run);
|
||||||
|
doClose();
|
||||||
|
});
|
||||||
|
rejectButton.setOnAction(event -> {
|
||||||
|
rejectHandlerOptional.ifPresent(Runnable::run);
|
||||||
|
doClose();
|
||||||
|
});
|
||||||
|
ignoreButton.setOnAction(event -> {
|
||||||
|
ignoreHandlerOptional.ifPresent(Runnable::run);
|
||||||
|
doClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
Button closeButton = addButtonAfterGroup(gridPane, ++rowIndexForVoting, Res.get("shared.close"));
|
||||||
|
closeButton.setOnAction(event -> doClose());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Button closeButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("shared.close"));
|
||||||
|
closeButton.setOnAction(event -> doClose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupCloseKeyHandler(Scene scene) {
|
||||||
|
scene.setOnKeyPressed(e -> {
|
||||||
|
if (e.getCode() == KeyCode.ESCAPE || e.getCode() == KeyCode.ENTER) {
|
||||||
|
e.consume();
|
||||||
|
doClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Vote> getVote(@Nullable Ballot ballot) {
|
||||||
|
if (ballot == null)
|
||||||
|
return Optional.empty();
|
||||||
|
else
|
||||||
|
return ballot.getVoteAsOptional();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1743,11 +1743,21 @@ public class FormBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText) {
|
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText) {
|
||||||
return addTableViewWithHeader(gridPane, rowIndex, headerText, 0);
|
return addTableViewWithHeader(gridPane, rowIndex, headerText, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText, String groupStyle) {
|
||||||
|
return addTableViewWithHeader(gridPane, rowIndex, headerText, 0, groupStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText, int top) {
|
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText, int top) {
|
||||||
addTitledGroupBg(gridPane, rowIndex, 1, headerText, top);
|
return addTableViewWithHeader(gridPane, rowIndex, headerText, top, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> TableView<T> addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText, int top, String groupStyle) {
|
||||||
|
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, rowIndex, 1, headerText, top);
|
||||||
|
|
||||||
|
if (groupStyle != null) titledGroupBg.getStyleClass().add(groupStyle);
|
||||||
|
|
||||||
TableView<T> tableView = new TableView<>();
|
TableView<T> tableView = new TableView<>();
|
||||||
GridPane.setRowIndex(tableView, rowIndex);
|
GridPane.setRowIndex(tableView, rowIndex);
|
||||||
|
|
|
@ -28,9 +28,11 @@ public class Layout {
|
||||||
public static final double FLOATING_LABEL_DISTANCE = 20d;
|
public static final double FLOATING_LABEL_DISTANCE = 20d;
|
||||||
public static final double GROUP_DISTANCE = 40d;
|
public static final double GROUP_DISTANCE = 40d;
|
||||||
public static final double COMPACT_GROUP_DISTANCE = 30d;
|
public static final double COMPACT_GROUP_DISTANCE = 30d;
|
||||||
|
public static final double GROUP_DISTANCE_WITHOUT_SEPARATOR = 20d;
|
||||||
public static final double FIRST_ROW_AND_GROUP_DISTANCE = GROUP_DISTANCE + FIRST_ROW_DISTANCE;
|
public static final double FIRST_ROW_AND_GROUP_DISTANCE = GROUP_DISTANCE + FIRST_ROW_DISTANCE;
|
||||||
public static final double COMPACT_FIRST_ROW_AND_GROUP_DISTANCE = COMPACT_GROUP_DISTANCE + FIRST_ROW_DISTANCE;
|
public static final double COMPACT_FIRST_ROW_AND_GROUP_DISTANCE = COMPACT_GROUP_DISTANCE + FIRST_ROW_DISTANCE;
|
||||||
public static final double COMPACT_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE = COMPACT_GROUP_DISTANCE + COMPACT_FIRST_ROW_DISTANCE;
|
public static final double COMPACT_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE = COMPACT_GROUP_DISTANCE + COMPACT_FIRST_ROW_DISTANCE;
|
||||||
|
public static final double COMPACT_FIRST_ROW_AND_GROUP_DISTANCE_WITHOUT_SEPARATOR = GROUP_DISTANCE_WITHOUT_SEPARATOR + COMPACT_FIRST_ROW_DISTANCE;
|
||||||
public static final double TWICE_FIRST_ROW_AND_GROUP_DISTANCE = GROUP_DISTANCE + TWICE_FIRST_ROW_DISTANCE;
|
public static final double TWICE_FIRST_ROW_AND_GROUP_DISTANCE = GROUP_DISTANCE + TWICE_FIRST_ROW_DISTANCE;
|
||||||
public static final double PADDING_WINDOW = 20d;
|
public static final double PADDING_WINDOW = 20d;
|
||||||
public static double PADDING = 10d;
|
public static double PADDING = 10d;
|
||||||
|
|
Loading…
Add table
Reference in a new issue