Skip to content

Commit 4cc0972

Browse files
authored
Merge pull request nus-cs2103-AY2021S1#94 from Licheng-Wu/branch-timetable-view
Update GUI for Timetable view
2 parents 14b1952 + dee045e commit 4cc0972

File tree

16 files changed

+310
-23
lines changed

16 files changed

+310
-23
lines changed

src/main/java/seedu/address/logic/Logic.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public interface Logic {
4949
/** Returns an unmodifiable view of the filtered list of slots */
5050
ObservableList<Slot> getFilteredSlotList();
5151

52+
/** Returns an unmodifiable view of the filtered list of slots, filtered by chosen day */
53+
ObservableList<Slot> getFilteredSlotList(String day);
54+
5255
/**
5356
* Returns the user prefs' address book file path.
5457
*/

src/main/java/seedu/address/logic/LogicManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ public ObservableList<Slot> getFilteredSlotList() {
8888
return model.getFilteredSlotList();
8989
}
9090

91+
@Override
92+
public ObservableList<Slot> getFilteredSlotList(String day) {
93+
return model.getFilteredSlotList(day);
94+
}
95+
9196
@Override
9297
public Path getAddressBookFilePath() {
9398
return model.getAddressBookFilePath();

src/main/java/seedu/address/model/Model.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ public interface Model {
126126
*/
127127
ObservableList<Slot> getFilteredSlotList();
128128

129+
/**
130+
* Returns an unmodifiable view of the filtered slot list, filtered by the chosen day
131+
*/
132+
ObservableList<Slot> getFilteredSlotList(String day);
133+
129134
/**
130135
* Updates the filter of the filtered person list to filter by the given {@code predicate}.
131136
*

src/main/java/seedu/address/model/ModelManager.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import seedu.address.model.person.Routine;
1919
import seedu.address.model.person.RoutineNameContainsKeywordsPredicate;
2020
import seedu.address.model.person.Slot;
21+
import seedu.address.model.person.SlotDayPredicate;
2122

2223
/**
2324
* Represents the in-memory model of the address book data.
@@ -312,6 +313,18 @@ public ObservableList<Slot> getFilteredSlotList() {
312313
return filteredSlots;
313314
}
314315

316+
@Override
317+
public ObservableList<Slot> getFilteredSlotList(String day) {
318+
SlotDayPredicate predicate = new SlotDayPredicate(Arrays.asList(day));
319+
320+
ObservableList<Slot> slotObservableList = this.addressBook.getSlotList();
321+
FilteredList<Slot> filteredSlotsByDay = new FilteredList<>(slotObservableList);
322+
323+
requireNonNull(predicate);
324+
filteredSlotsByDay.setPredicate(predicate);
325+
return filteredSlotsByDay;
326+
}
327+
315328
@Override
316329
public void updateFilteredRoutineList(Predicate<Routine> predicate) {
317330
requireNonNull(predicate);

src/main/java/seedu/address/model/person/Slot.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import java.util.Objects;
66

7-
public class Slot {
7+
public class Slot implements Comparable<Slot> {
88

99
private final Activity activity;
1010

@@ -102,4 +102,9 @@ public int hashCode() {
102102
public String toString() {
103103
return activity.getName() + " on " + day.toString() + " " + duration.toString();
104104
}
105+
106+
@Override
107+
public int compareTo(Slot o) {
108+
return this.getDuration().getStartTime().compareTo(o.getDuration().getStartTime());
109+
}
105110
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package seedu.address.model.person;
2+
3+
import java.util.List;
4+
import java.util.function.Predicate;
5+
6+
import seedu.address.commons.util.StringUtil;
7+
8+
/**
9+
* Tests that a {@code Slot}'s {@code Day} matches the day given.
10+
*/
11+
public class SlotDayPredicate implements Predicate<Slot> {
12+
private final List<String> keywords;
13+
14+
public SlotDayPredicate(List<String> keywords) {
15+
this.keywords = keywords;
16+
}
17+
18+
@Override
19+
public boolean test(Slot slot) {
20+
return keywords.stream()
21+
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(slot.getDay().getDay(), keyword));
22+
}
23+
24+
@Override
25+
public boolean equals(Object other) {
26+
return other == this // short circuit if same object
27+
|| (other instanceof SlotDayPredicate // instanceof handles nulls
28+
&& keywords.equals(((SlotDayPredicate) other).keywords)); // state check
29+
}
30+
31+
}

src/main/java/seedu/address/model/person/UniqueSlotList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public void add(Slot toAdd) {
6060
throw new SlotOverlapDurationException();
6161
}
6262
internalList.add(toAdd);
63+
FXCollections.sort(internalList);
6364
}
6465

6566
/**
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package seedu.address.ui;
2+
3+
import javafx.fxml.FXML;
4+
import javafx.scene.control.Label;
5+
import javafx.scene.layout.FlowPane;
6+
import javafx.scene.layout.HBox;
7+
import javafx.scene.layout.Region;
8+
import seedu.address.model.person.Slot;
9+
10+
/**
11+
* An UI component that displays information of a {@code Slot}.
12+
*/
13+
public class SlotCard extends UiPart<Region> {
14+
15+
private static final String FXML = "SlotListCard.fxml";
16+
17+
/**
18+
* Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX.
19+
* As a consequence, UI elements' variable names cannot be set to such keywords
20+
* or an exception will be thrown by JavaFX during runtime.
21+
*
22+
* @see <a href="https://github.com/se-edu/addressbook-level4/issues/336">The issue on AddressBook level 4</a>
23+
*/
24+
25+
public final Slot slot;
26+
27+
@FXML
28+
private HBox cardPane;
29+
@FXML
30+
private Label name;
31+
@FXML
32+
private Label id;
33+
@FXML
34+
private Label time;
35+
@FXML
36+
private FlowPane tags;
37+
38+
/**
39+
* Creates a {@code SlotCode} with the given {@code Slot} and index to display.
40+
*/
41+
public SlotCard(Slot slot, int displayedIndex) {
42+
super(FXML);
43+
this.slot = slot;
44+
id.setText(displayedIndex + ". ");
45+
name.setText(slot.getActivity().getName().toString());
46+
time.setText(slot.getDuration().getStartTime().toString() + " - "
47+
+ slot.getDuration().getEndTime().toString());
48+
}
49+
50+
@Override
51+
public boolean equals(Object other) {
52+
// short circuit if same object
53+
if (other == this) {
54+
return true;
55+
}
56+
57+
// instanceof handles nulls
58+
if (!(other instanceof SlotCard)) {
59+
return false;
60+
}
61+
62+
// state check
63+
SlotCard card = (SlotCard) other;
64+
return id.getText().equals(card.id.getText())
65+
&& slot.equals(card.slot);
66+
}
67+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package seedu.address.ui;
2+
3+
import java.util.logging.Logger;
4+
5+
import javafx.collections.ObservableList;
6+
import javafx.fxml.FXML;
7+
import javafx.geometry.Orientation;
8+
import javafx.scene.control.ListCell;
9+
import javafx.scene.control.ListView;
10+
import javafx.scene.layout.Region;
11+
import seedu.address.commons.core.LogsCenter;
12+
import seedu.address.model.person.Slot;
13+
14+
/**
15+
* Panel containing the list of slots.
16+
*/
17+
public class SlotListPanel extends UiPart<Region> {
18+
private static final String FXML = "SlotListPanel.fxml";
19+
private final Logger logger = LogsCenter.getLogger(SlotListPanel.class);
20+
21+
@FXML
22+
private ListView<Slot> slotListView;
23+
24+
/**
25+
* Creates a {@code SlotListPanel} with the given {@code ObservableList}.
26+
*/
27+
public SlotListPanel(ObservableList<Slot> slotList) {
28+
super(FXML);
29+
slotListView.setItems(slotList);
30+
slotListView.setOrientation(Orientation.HORIZONTAL);
31+
slotListView.setCellFactory(listView -> new SlotListViewCell());
32+
}
33+
34+
/**
35+
* Custom {@code ListCell} that displays the graphics of a {@code Slot} using a {@code SlotCard}.
36+
*/
37+
class SlotListViewCell extends ListCell<Slot> {
38+
@Override
39+
protected void updateItem(Slot slot, boolean empty) {
40+
super.updateItem(slot, empty);
41+
42+
if (empty || slot == null) {
43+
setGraphic(null);
44+
setText(null);
45+
} else {
46+
setGraphic(new SlotCard(slot, getIndex() + 1).getRoot());
47+
}
48+
}
49+
}
50+
51+
}

src/main/java/seedu/address/ui/TimetablePanel.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import java.util.logging.Logger;
44

5+
import javafx.fxml.FXML;
56
import javafx.scene.layout.Region;
7+
import javafx.scene.layout.StackPane;
68
import seedu.address.commons.core.LogsCenter;
79
import seedu.address.logic.Logic;
810

@@ -13,6 +15,29 @@ public class TimetablePanel extends UiPart<Region> {
1315

1416
private Logic logic;
1517

18+
// Independent Ui parts residing in this Ui container
19+
private SlotListPanel mondayListPanel;
20+
private SlotListPanel tuesdayListPanel;
21+
private SlotListPanel wednesdayListPanel;
22+
private SlotListPanel thursdayListPanel;
23+
private SlotListPanel fridayListPanel;
24+
25+
@FXML
26+
private StackPane mondayListPanelPlaceholder;
27+
28+
@FXML
29+
private StackPane tuesdayListPanelPlaceholder;
30+
31+
@FXML
32+
private StackPane wednesdayListPanelPlaceholder;
33+
34+
@FXML
35+
private StackPane thursdayListPanelPlaceholder;
36+
37+
@FXML
38+
private StackPane fridayListPanelPlaceholder;
39+
40+
1641
/** Constructs TimetablePanel
1742
*
1843
* @param logic
@@ -21,5 +46,20 @@ public TimetablePanel(Logic logic) {
2146
super(FXML);
2247

2348
this.logic = logic;
49+
50+
mondayListPanel = new SlotListPanel(logic.getFilteredSlotList("Monday"));
51+
mondayListPanelPlaceholder.getChildren().add(mondayListPanel.getRoot());
52+
53+
tuesdayListPanel = new SlotListPanel(logic.getFilteredSlotList("Tuesday"));
54+
tuesdayListPanelPlaceholder.getChildren().add(tuesdayListPanel.getRoot());
55+
56+
wednesdayListPanel = new SlotListPanel(logic.getFilteredSlotList("Wednesday"));
57+
wednesdayListPanelPlaceholder.getChildren().add(wednesdayListPanel.getRoot());
58+
59+
thursdayListPanel = new SlotListPanel(logic.getFilteredSlotList("Thursday"));
60+
thursdayListPanelPlaceholder.getChildren().add(thursdayListPanel.getRoot());
61+
62+
fridayListPanel = new SlotListPanel(logic.getFilteredSlotList("Friday"));
63+
fridayListPanelPlaceholder.getChildren().add(fridayListPanel.getRoot());
2464
}
2565
}

0 commit comments

Comments
 (0)