From 7aae4d746ba16916e848fa8f6981feba326ba452 Mon Sep 17 00:00:00 2001 From: pra-navi Date: Wed, 18 Oct 2023 12:43:18 +0800 Subject: [PATCH 1/8] feat: GUI update to include TaskList --- src/main/resources/view/MainWindow.fxml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 7778f666a0a..a482238ecad 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -6,7 +6,6 @@ - From 7e87fc7f9603f3c86afa4dd99577230489d085c7 Mon Sep 17 00:00:00 2001 From: pra-navi Date: Wed, 18 Oct 2023 13:07:50 +0800 Subject: [PATCH 2/8] feat: GUI for Task List --- src/main/java/seedu/address/logic/Logic.java | 4 ++ .../seedu/address/logic/LogicManager.java | 6 +++ .../address/model/task/UniqueTaskList.java | 17 +++--- .../address/model/util/SampleDataUtil.java | 14 +++++ .../java/seedu/address/ui/MainWindow.java | 7 +++ src/main/java/seedu/address/ui/TaskCard.java | 46 ++++++++++++++++ .../java/seedu/address/ui/TaskListPanel.java | 49 ++++++++++++++++++ src/main/java/seedu/address/ui/UiManager.java | 2 +- src/main/resources/images/calendar.png | Bin 1215 -> 0 bytes ...ddress_book_32.png => coordimate_icon.png} | Bin src/main/resources/view/DarkTheme.css | 7 +++ src/main/resources/view/MainWindow.fxml | 39 +++++++++++--- src/main/resources/view/PersonListCard.fxml | 10 ++-- src/main/resources/view/PersonListPanel.fxml | 2 + src/main/resources/view/TaskListCard.fxml | 32 ++++++++++++ src/main/resources/view/TaskListPanel.fxml | 10 ++++ .../duplicatePersonAddressBook.json | 2 +- .../invalidPersonAddressBook.json | 2 +- .../typicalPersonsAddressBook.json | 2 +- .../address/commons/util/AppUtilTest.java | 2 +- .../logic/commands/CommandTestUtil.java | 4 +- 21 files changed, 230 insertions(+), 27 deletions(-) create mode 100644 src/main/java/seedu/address/ui/TaskCard.java create mode 100644 src/main/java/seedu/address/ui/TaskListPanel.java delete mode 100644 src/main/resources/images/calendar.png rename src/main/resources/images/{address_book_32.png => coordimate_icon.png} (100%) create mode 100644 src/main/resources/view/TaskListCard.fxml create mode 100644 src/main/resources/view/TaskListPanel.fxml diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index 92cd8fa605a..5e1f29acc2b 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -9,6 +9,7 @@ import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.person.Person; +import seedu.address.model.task.Task; /** * API of the Logic component @@ -33,6 +34,9 @@ public interface Logic { /** Returns an unmodifiable view of the filtered list of persons */ ObservableList getFilteredPersonList(); + /** Returns an unmodifiable view of the filtered list of tasks */ + ObservableList getFilteredTaskList(); + /** * Returns the user prefs' address book file path. */ diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index 5aa3b91c7d0..7f8e6e46399 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -16,6 +16,7 @@ import seedu.address.model.Model; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.person.Person; +import seedu.address.model.task.Task; import seedu.address.storage.Storage; /** @@ -71,6 +72,11 @@ public ObservableList getFilteredPersonList() { return model.getFilteredPersonList(); } + @Override + public ObservableList getFilteredTaskList() { + return model.getFilteredTaskList(); + } + @Override public Path getAddressBookFilePath() { return model.getAddressBookFilePath(); diff --git a/src/main/java/seedu/address/model/task/UniqueTaskList.java b/src/main/java/seedu/address/model/task/UniqueTaskList.java index 7ef5f302d2f..beaa69c5637 100644 --- a/src/main/java/seedu/address/model/task/UniqueTaskList.java +++ b/src/main/java/seedu/address/model/task/UniqueTaskList.java @@ -13,16 +13,16 @@ /** * A list of tasks that enforces uniqueness between its elements and does not allow nulls. - * A task is considered unique by comparing using {@code Task#isSameTask(Task)}. As such, adding and updating - * of tasks uses Task#isSameTask(Task) for equality to ensure that the task being added or updated is - * unique in terms of identity in the UniqueTaskList. However, the removal of a task uses Task#equals(Object) - * to ensure that the task with exactly the same fields will be removed. + * A task is considered unique by comparing using {@code Task#isSameTask(Task)}. As such, adding and updating of + * tasks uses Task#isSameTask(Task) for equality so as to ensure that the task being added or updated is + * unique in terms of identity in the UniqueTaskList. However, the removal of a task uses Task#equals(Task) so + * as to ensure that the task with exactly the same fields will be removed. + * * Supports a minimal set of list operations. * * @see Task#isSameTask(Task) */ public class UniqueTaskList implements Iterable { - private final ObservableList internalList = FXCollections.observableArrayList(); private final ObservableList internalUnmodifiableList = FXCollections.unmodifiableObservableList(internalList); @@ -79,9 +79,12 @@ public void remove(Task toRemove) { } /** - * Replaces the contents of this list with another {@code UniqueTaskList}. - * @param replacement the {@code UniqueTaskList} to replace this list with. + * Removes all tasks from the list. */ + public void removeAll() { + internalList.clear(); + } + public void setTasks(UniqueTaskList replacement) { requireNonNull(replacement); internalList.setAll(replacement.internalList); diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 1806da4facf..af3aee1507f 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -12,6 +12,9 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.tag.Tag; +import seedu.address.model.task.Title; +import seedu.address.model.task.Task; +import seedu.address.model.task.Note; /** * Contains utility methods for populating {@code AddressBook} with sample data. @@ -40,11 +43,22 @@ public static Person[] getSamplePersons() { }; } + public static Task[] getSampleTasks() { + return new Task[]{ + new Task(new Title("Buy Flowers"), new Note("from Gina")), + new Task(new Title("Buy Milk"), new Note("from NTUC")) + }; + } + public static ReadOnlyAddressBook getSampleAddressBook() { AddressBook sampleAb = new AddressBook(); for (Person samplePerson : getSamplePersons()) { sampleAb.addPerson(samplePerson); } + + for (Task sampleTask : getSampleTasks()) { + sampleAb.addTask(sampleTask); + } return sampleAb; } diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 79e74ef37c0..0a68dc3b6fc 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -32,12 +32,16 @@ public class MainWindow extends UiPart { // Independent Ui parts residing in this Ui container private PersonListPanel personListPanel; + private TaskListPanel taskListPanel; private ResultDisplay resultDisplay; private HelpWindow helpWindow; @FXML private StackPane commandBoxPlaceholder; + @FXML + private StackPane taskListPanelPlaceholder; + @FXML private MenuItem helpMenuItem; @@ -113,6 +117,9 @@ void fillInnerParts() { personListPanel = new PersonListPanel(logic.getFilteredPersonList()); personListPanelPlaceholder.getChildren().add(personListPanel.getRoot()); + taskListPanel = new TaskListPanel(logic.getFilteredTaskList()); + taskListPanelPlaceholder.getChildren().add(taskListPanel.getRoot()); + resultDisplay = new ResultDisplay(); resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot()); diff --git a/src/main/java/seedu/address/ui/TaskCard.java b/src/main/java/seedu/address/ui/TaskCard.java new file mode 100644 index 00000000000..7b317e239b2 --- /dev/null +++ b/src/main/java/seedu/address/ui/TaskCard.java @@ -0,0 +1,46 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import seedu.address.model.task.Task; + +/** + * An UI component that displays information of a {@code Task}. + */ +public class TaskCard extends UiPart { + + private static final String FXML = "TaskListCard.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final Task task; + + @FXML + private HBox cardPane; + @FXML + private Label title; + @FXML + private Label note; + + @FXML + private Label id; + + /** + * Creates a {@code TaskCode} with the given {@code Task} and index to display. + */ + public TaskCard(Task task, int displayedIndex) { + super(FXML); + this.task = task; + id.setText(displayedIndex + ". "); + title.setText(task.getTitle().toString()); + note.setText(task.getNote().toString()); + } +} diff --git a/src/main/java/seedu/address/ui/TaskListPanel.java b/src/main/java/seedu/address/ui/TaskListPanel.java new file mode 100644 index 00000000000..b7a3acdf106 --- /dev/null +++ b/src/main/java/seedu/address/ui/TaskListPanel.java @@ -0,0 +1,49 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.task.Task; + +/** + * Panel containing the list of persons. + */ +public class TaskListPanel extends UiPart { + private static final String FXML = "TaskListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(TaskListPanel.class); + + @FXML + private ListView taskListView; + + /** + * Creates a {@code TaskListPanel} with the given {@code ObservableList}. + */ + public TaskListPanel(ObservableList taskList) { + super(FXML); + taskListView.setItems(taskList); + taskListView.setCellFactory(listView -> new TaskListViewCell()); + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Task} using a {@code TaskCard}. + */ + class TaskListViewCell extends ListCell { + @Override + protected void updateItem(Task task, boolean empty) { + super.updateItem(task, empty); + + if (empty || task == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(new TaskCard(task, getIndex() + 1).getRoot()); + } + } + } + +} diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/address/ui/UiManager.java index fdf024138bc..748eda1504f 100644 --- a/src/main/java/seedu/address/ui/UiManager.java +++ b/src/main/java/seedu/address/ui/UiManager.java @@ -20,7 +20,7 @@ public class UiManager implements Ui { public static final String ALERT_DIALOG_PANE_FIELD_ID = "alertDialogPane"; private static final Logger logger = LogsCenter.getLogger(UiManager.class); - private static final String ICON_APPLICATION = "/images/address_book_32.png"; + private static final String ICON_APPLICATION = "/images/coordimate_icon.png"; private Logic logic; private MainWindow mainWindow; diff --git a/src/main/resources/images/calendar.png b/src/main/resources/images/calendar.png deleted file mode 100644 index 8b2bdf4f1c16ad2abafd46df82582aad743d1846..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1215 zcmaJ>-D}fO6pv1(lL-#-^XZx)DA*=9ZPGNX&NfMB#m?Ck9r$9F+_qs!ZcJ`%H}^0U z1odhEfiJ#^_$Vm&38IMTqy7P+FY1F2zUfKV&Vj>_+}wL|e&_toS8mQsPwm=yXeY;U zyDF!Q8oc+zb703XtYgcKHoOipbB@i@2J2W6;ffBOC#d3EO;RJ4vv~P6nc%pgZ*F~# z%~j86Huck1qLc3WA)q;KVzL`r_5xvOo;2N{z<+=Agh#GZ;4jEku^Q^6<(^uK$n4T| z-CkO-^A10G0!?%^FyIqrp|0-*vDPi{J-Zt06S2Ufo(fwi@N1;zsxwHZ5kYb~ld?sO zk)ot=R#p^z97!UU1QBi}g|nKhXi^UKFCM%_PD861<-RXC75Elop(Y5OPAA>Tq-oR? za6X?;Y)DcHG*a5#cz;rDHKde^Q4F_>QQIImB zYlQ+%i-PYbarLxgRwI9DY^ojC7egY{NKD(24fSY@55SPS|2rBeI`+C=*p9qjoQ^FJ zkN6~DF_6MNM!;M<8@W(G%QL9mPQF%*0^e@Cj;6?_lF5sTs_12mjZ#rDB|}wnx>?jq zSuvM5OAKrTf+Xz#R?TM0k|FD&k}F|sO8I=*C@N)DRgIji=1K!>C5V|7*d%e9VBNpi z(toj<9ubSts7|RjXqA~3Wi)Ql5b3iDI$E`CH%J7>l1lculE}S6oN`2c)GLMNZo)vs zDl}RSVw50!3@0^HHl>zEgSjALueWghAG zXwhT+o#!TfqIp)(goLCV(y-bd<4-ib#jxetG>9jJqz6400KMHBR@h*%C*IJs15KEO zWV=3sa9AH=62Rm}Frs&#ez*qX-K-eJdiT@(uiw8Xhen5gw3LEw?h#?vWo~uYWx4KVBJob7$nh^Bdz+Us?}F$6u_*`;NXk_h$QtGo#sUS$R48 scIpKz$F{vad2h$d;jDP|@X3`e+{NX)?EUBSdy`*E#hf + + + title="CoordiMate" minWidth="450" minHeight="600" onCloseRequest="#handleExit"> - + @@ -45,12 +47,33 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index f5e812e25e6..58d1745204b 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -19,18 +19,18 @@ - -