Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Sidepane logic #8202

Merged
merged 37 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
13fc122
Add visibleProperty to SidePaneComponent
HoussemNasri Oct 30, 2021
9688ec6
Making progress into refactoring Sidepane logic
HoussemNasri Oct 31, 2021
e7ddff6
Populate SidePaneType with information
HoussemNasri Oct 31, 2021
eee68e7
Wrap the content of web search side pane into WebSearchPaneView
HoussemNasri Oct 31, 2021
9c3a314
Revert changes to SidePane
HoussemNasri Oct 31, 2021
f59bb3f
Refactor SidePaneContainer
HoussemNasri Oct 31, 2021
41dba61
Bind side pane check menu selection state to side pane visibility
HoussemNasri Oct 31, 2021
c839950
Fix checkstyle
HoussemNasri Oct 31, 2021
69c90df
Remove SidePaneViewModel.java
HoussemNasri Oct 31, 2021
a9e0419
Fix view menu for sidebar option out of sync with sidebar state
HoussemNasri Oct 31, 2021
289165b
Remove unused constructor parameters
HoussemNasri Oct 31, 2021
d807d9b
Remove deprecated Sidepane component
HoussemNasri Oct 31, 2021
971203a
Move Vbox.setVgrow() to SidePaneView
HoussemNasri Nov 1, 2021
2266a67
Merge SidePaneHeaderView into SidePaneView
HoussemNasri Nov 1, 2021
8224cc5
Avoid firing removed and added events on ObservableList
HoussemNasri Nov 2, 2021
5a877ab
Use shorter more declarative code for binding
HoussemNasri Nov 2, 2021
1d35778
Rename SidePaneView to SidePaneComponent and SidePaneContainerView to…
HoussemNasri Nov 6, 2021
6d9d52d
Rename initView() to initialize()
HoussemNasri Nov 6, 2021
2f0590d
Add an overloading of createCheckMenuItem() with a selected property
HoussemNasri Nov 6, 2021
58edb1c
Rename sidePaneVisibleProperty() to paneVisibleProperty()
HoussemNasri Nov 6, 2021
7e70c25
Use the name pane rather than sidePane to call components in the Side…
HoussemNasri Nov 6, 2021
9cd8894
Remove unused method createSidePaneCheckMenuItem()
HoussemNasri Nov 6, 2021
7176862
Share the visibility property of side pane components by moving it to…
HoussemNasri Nov 6, 2021
b0cae97
Remove comment
HoussemNasri Nov 6, 2021
85308f7
Use better names
HoussemNasri Nov 6, 2021
e44ae48
Fix checkstyle
HoussemNasri Nov 6, 2021
2616335
Move close/toggle pane actions to separate files
HoussemNasri Nov 8, 2021
ab49960
Move sidepane binding logic to SidePaneViewModel
HoussemNasri Nov 14, 2021
e2141bc
Merge remote-tracking branch 'upstream/main' into refactor-sidepane
calixtus Dec 1, 2021
e573811
Removed unnecessary properties in stateManager, refactored to mvvm pa…
calixtus Dec 5, 2021
2149f6c
Moved listener from sidepane visibility property to list of children …
calixtus Dec 5, 2021
e74403c
Removed unused method
calixtus Dec 6, 2021
531dafc
Fixed sidepane width issue on startup
calixtus Dec 11, 2021
1b56325
Created tests
calixtus Dec 11, 2021
9af0d79
Cleanups
calixtus Dec 11, 2021
ecfb529
CHANGELOG.md
calixtus Dec 11, 2021
2ff238b
more CHANGELOG.md
calixtus Dec 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.jabref.gui.sidepane;

import javafx.scene.control.Button;

import org.jabref.gui.DialogService;
import org.jabref.gui.Globals;
import org.jabref.gui.actions.ActionFactory;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.groups.GroupModeViewModel;
import org.jabref.gui.groups.GroupViewMode;
import org.jabref.gui.icon.IconTheme;
import org.jabref.logic.l10n.Localization;
import org.jabref.preferences.PreferencesService;

public class GroupsSidePaneHeaderView extends SidePaneHeaderView {
tobiasdiez marked this conversation as resolved.
Show resolved Hide resolved
private final PreferencesService preferences;
private final DialogService dialogService;
private final Button intersectionUnionToggle = IconTheme.JabRefIcons.GROUP_INTERSECTION.asButton();

public GroupsSidePaneHeaderView(SidePaneType sidePaneType, SimpleCommand closeCommand, SimpleCommand moveUpCommand, SimpleCommand moveDownCommand, PreferencesService preferences, DialogService dialogService) {
super(sidePaneType, closeCommand, moveUpCommand, moveDownCommand);
this.preferences = preferences;
this.dialogService = dialogService;
setupIntersectionUnionToggle();
}

private void setupIntersectionUnionToggle() {
addButtonAtPosition(intersectionUnionToggle, 2);
ActionFactory factory = new ActionFactory(Globals.getKeyPrefs());
factory.configureIconButton(getSidePaneType().getToggleAction(), new ToggleUnionIntersectionAction(), intersectionUnionToggle);
}

public void afterOpening() {
setGraphicsAndTooltipForButton(preferences.getGroupViewMode());
calixtus marked this conversation as resolved.
Show resolved Hide resolved
}

private void setGraphicsAndTooltipForButton(GroupViewMode mode) {
GroupModeViewModel modeViewModel = new GroupModeViewModel(mode);
intersectionUnionToggle.setGraphic(modeViewModel.getUnionIntersectionGraphic());
intersectionUnionToggle.setTooltip(modeViewModel.getUnionIntersectionTooltip());
}

public class ToggleUnionIntersectionAction extends SimpleCommand {

@Override
public void execute() {
GroupViewMode mode = preferences.getGroupViewMode();

if (mode == GroupViewMode.UNION) {
preferences.setGroupViewMode(GroupViewMode.INTERSECTION);
dialogService.notify(Localization.lang("Group view mode set to intersection"));
} else if (mode == GroupViewMode.INTERSECTION) {
preferences.setGroupViewMode(GroupViewMode.UNION);
dialogService.notify(Localization.lang("Group view mode set to union"));
}
setGraphicsAndTooltipForButton(mode);
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/jabref/gui/sidepane/GroupsSidePaneView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.jabref.gui.sidepane;

import javafx.scene.Node;
import javafx.scene.layout.Priority;

import org.jabref.gui.DialogService;
import org.jabref.preferences.PreferencesService;

public class GroupsSidePaneView extends SidePaneView {
HoussemNasri marked this conversation as resolved.
Show resolved Hide resolved
public GroupsSidePaneView(GroupsSidePaneHeaderView sidePaneHeaderView, Node content, Priority resizePolicy, PreferencesService preferences, DialogService dialogService) {
super(sidePaneHeaderView, content, resizePolicy);
}

public void afterOpening() {
((GroupsSidePaneHeaderView) (getSidePaneHeaderView())).afterOpening();
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/gui/sidepane/SidePane.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public SidePane(PreferencesService preferencesService,
this.dialogService = dialogService;
this.stateManager = stateManager;
this.undoManager = undoManager;
initComponents();

setId("sidePane");

Expand All @@ -53,7 +54,21 @@ public SidePane(PreferencesService preferencesService,
updateView();
}

private void initComponents() {
components.put(SidePaneType.GROUPS, new GroupSidePane(this, taskExecutor, stateManager, preferencesService, dialogService));
calixtus marked this conversation as resolved.
Show resolved Hide resolved
components.put(SidePaneType.OPEN_OFFICE, new OpenOfficeSidePanel(this, taskExecutor, preferencesService, dialogService, stateManager, undoManager));
components.put(SidePaneType.WEB_SEARCH, new WebSearchPane(this, preferencesService, dialogService, stateManager));
components.forEach((key, value) -> value.visibleProperty().addListener((x, y, isVisible) -> {
if (isVisible) {
show(key);
} else {
hide(key);
}
}));
}

public boolean isComponentVisible(SidePaneType type) {
// TODO('return getComponent(type).visiblePropertyProperty().get();')
return visibleComponents.contains(getComponent(type));
}

Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/jabref/gui/sidepane/SidePaneComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Collections;
import java.util.List;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
Expand All @@ -24,6 +26,7 @@ public abstract class SidePaneComponent {
private final JabRefIcon icon;
private final String title;
private Node contentNode;
private final BooleanProperty visible = new SimpleBooleanProperty();

public SidePaneComponent(SidePane sidePane, JabRefIcon icon, String title) {
this.sidePane = sidePane;
Expand All @@ -32,11 +35,25 @@ public SidePaneComponent(SidePane sidePane, JabRefIcon icon, String title) {
this.toggleCommand = new ToggleCommand(this);
}

public BooleanProperty visibleProperty() {
return visible;
}

public boolean isVisible() {
return visibleProperty().get();
}

// TODO ('hide() is only used in SidePane')
protected void hide() {
visible.setValue(false);
// TODO('Model should not update the view directly')
sidePane.hide(this.getType());
}

// TODO ('show() is only used in SidePane')
protected void show() {
visible.setValue(true);
// TODO('Model should not update the view directly')
sidePane.show(this.getType());
}

Expand Down Expand Up @@ -96,6 +113,7 @@ public final Node getContentPane() {
public final Node getHeader() {
Button close = IconTheme.JabRefIcons.CLOSE.asButton();
close.setTooltip(new Tooltip(Localization.lang("Hide panel")));
// TODO (Use visibleProperty inside onAction)
close.setOnAction(event -> hide());

Button up = IconTheme.JabRefIcons.UP.asButton();
Expand Down
109 changes: 109 additions & 0 deletions src/main/java/org/jabref/gui/sidepane/SidePaneContainerView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package org.jabref.gui.sidepane;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.undo.UndoManager;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

import org.jabref.gui.DialogService;
import org.jabref.gui.StateManager;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.groups.GroupTreeView;
import org.jabref.gui.util.TaskExecutor;
import org.jabref.preferences.PreferencesService;

public class SidePaneContainerView extends VBox {
private Map<SidePaneType, SidePaneView> sidePaneViewLookup;
// TODO('Use preferencesService.getSidePanePreferences().visiblePanes() as the single source of truth')
private final ObservableList<SidePaneType> visiblePanes = FXCollections.observableArrayList();

private final PreferencesService preferencesService;
private final TaskExecutor taskExecutor;
private final DialogService dialogService;
private final StateManager stateManager;
private final UndoManager undoManager;

public SidePaneContainerView(PreferencesService preferencesService,
TaskExecutor taskExecutor,
DialogService dialogService,
StateManager stateManager,
UndoManager undoManager) {
this.preferencesService = preferencesService;
this.taskExecutor = taskExecutor;
this.dialogService = dialogService;
this.stateManager = stateManager;
this.undoManager = undoManager;
initSidePanes();
}

private void initSidePanes() {
SidePaneView groupsPaneView = createGroupsPaneView();
}

private SidePaneView createGroupsPaneView() {
GroupsSidePaneHeaderView groupsHeader = new GroupsSidePaneHeaderView(SidePaneType.GROUPS,
new CloseSidePaneAction(SidePaneType.GROUPS), null, null, preferencesService, dialogService);
GroupTreeView groupsContent = new GroupTreeView(taskExecutor, stateManager, preferencesService, dialogService);

return new GroupsSidePaneView(groupsHeader, groupsContent, Priority.ALWAYS, preferencesService, dialogService);
}

private void showSidePanes(Set<SidePaneType> toShowSidePanes) {
getChildren().clear();
toShowSidePanes.forEach(type -> {
SidePaneView view = sidePaneViewLookup.get(type);
getChildren().add(view);
VBox.setVgrow(view, view.getResizePolicy());
tobiasdiez marked this conversation as resolved.
Show resolved Hide resolved
});
}

private void show(SidePaneType paneType) {
if (!visiblePanes.contains(paneType)) {
visiblePanes.add(paneType);
preferencesService.getSidePanePreferences().visiblePanes().add(paneType);
// TODO('Sort')
updateView();
}
}

private void hide(SidePaneType paneType) {
if (visiblePanes.contains(paneType)) {
// TODO('Before closing')
visiblePanes.remove(paneType);
preferencesService.getSidePanePreferences().visiblePanes().remove(paneType);
updateView();
}
}

private void moveUp(SidePaneType type) {

}

public ObservableList<SidePaneType> getVisiblePanes() {
return visiblePanes;
}

private void updateView() {
showSidePanes(new HashSet<>(visiblePanes));
setVisible(!visiblePanes.isEmpty());
}

private class CloseSidePaneAction extends SimpleCommand {
HoussemNasri marked this conversation as resolved.
Show resolved Hide resolved
private final SidePaneType toClosePaneType;

public CloseSidePaneAction(SidePaneType toClosePaneType) {
this.toClosePaneType = toClosePaneType;
}

@Override
public void execute() {
hide(toClosePaneType);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.jabref.gui.sidepane;

import org.jabref.gui.AbstractViewModel;

public class SidePaneContainerViewModel extends AbstractViewModel {

public void moveUp(SidePaneType sidePaneType) {

}

public void moveDown(SidePaneType sidePaneType) {

}

public void show(SidePaneType sidePaneType) {

}

public void hide(SidePaneType sidePaneType) {

}
}
61 changes: 61 additions & 0 deletions src/main/java/org/jabref/gui/sidepane/SidePaneHeaderView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.jabref.gui.sidepane;

import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;

import org.jabref.gui.Globals;
import org.jabref.gui.actions.ActionFactory;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.icon.IconTheme;
import org.jabref.logic.l10n.Localization;

public class SidePaneHeaderView extends BorderPane {
private final SidePaneType sidePaneType;
private final SimpleCommand closeCommand;
private final SimpleCommand moveUpCommand;
private final SimpleCommand moveDownCommand;

private HBox buttonContainer;

public SidePaneHeaderView(SidePaneType sidePaneType, SimpleCommand closeCommand, SimpleCommand moveUpCommand, SimpleCommand moveDownCommand) {
this.sidePaneType = sidePaneType;
this.closeCommand = closeCommand;
this.moveUpCommand = moveUpCommand;
this.moveDownCommand = moveDownCommand;
initView();
}

private void initView() {
ActionFactory factory = new ActionFactory(Globals.getKeyPrefs());
Button closeButton = IconTheme.JabRefIcons.CLOSE.asButton();
closeButton.setTooltip(new Tooltip(Localization.lang("Hide panel")));
factory.configureIconButton(sidePaneType.getToggleAction(), closeCommand, closeButton);

Button upButton = IconTheme.JabRefIcons.UP.asButton();
upButton.setTooltip(new Tooltip(Localization.lang("Move panel up")));
factory.configureIconButton(sidePaneType.getToggleAction(), moveUpCommand, upButton);

Button downButton = IconTheme.JabRefIcons.DOWN.asButton();
downButton.setTooltip(new Tooltip(Localization.lang("Move panel down")));
factory.configureIconButton(sidePaneType.getToggleAction(), moveDownCommand, downButton);

this.buttonContainer = new HBox();
buttonContainer.getChildren().addAll(upButton, downButton, closeButton);

Label label = new Label(sidePaneType.getTitle());
setCenter(label);
setRight(buttonContainer);
getStyleClass().add("sidePaneComponentHeader");
}

protected void addButtonAtPosition(Button button, int position) {
this.buttonContainer.getChildren().set(position, button);
}

public SidePaneType getSidePaneType() {
return sidePaneType;
}
}
32 changes: 29 additions & 3 deletions src/main/java/org/jabref/gui/sidepane/SidePaneType.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
package org.jabref.gui.sidepane;

import org.jabref.gui.actions.Action;
import org.jabref.gui.actions.StandardActions;
import org.jabref.gui.icon.JabRefIcon;

/**
* Definition of all possible components in the side pane.
*/
public enum SidePaneType {
OPEN_OFFICE,
WEB_SEARCH,
GROUPS
OPEN_OFFICE("", null, StandardActions.TOOGLE_OO),
WEB_SEARCH("", null, StandardActions.TOGGLE_WEB_SEARCH),
GROUPS("", null, StandardActions.TOGGLE_GROUPS);

private final String title;
private final JabRefIcon icon;
private final Action toggleAction;

SidePaneType(String title, JabRefIcon icon, Action toggleAction) {
this.title = title;
this.icon = icon;
this.toggleAction = toggleAction;
}

public String getTitle() {
return title;
}

public JabRefIcon getIcon() {
return icon;
}

public Action getToggleAction() {
return toggleAction;
}
}
Loading