From 8e8d040858fa4b480d9da390fe011750841541e8 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 21:55:55 +0800 Subject: [PATCH 1/7] Add blank UI section under Implementation --- docs/_dg/Implementation.md | 4 ++++ docs/_dg/implementations/UserInterface.md | 0 2 files changed, 4 insertions(+) create mode 100644 docs/_dg/implementations/UserInterface.md diff --git a/docs/_dg/Implementation.md b/docs/_dg/Implementation.md index 978862944db..9db7e0d2f4a 100644 --- a/docs/_dg/Implementation.md +++ b/docs/_dg/Implementation.md @@ -24,3 +24,7 @@ There are four main groups of features that are implemented: ### General Features {% include_relative _dg/implementations/GeneralFeatures.md %} + +### User Interface + +{% include_relative _dg/implementations/UserInterface.md %} diff --git a/docs/_dg/implementations/UserInterface.md b/docs/_dg/implementations/UserInterface.md new file mode 100644 index 00000000000..e69de29bb2d From cba47739aa12bf8a008459d1f7c2157d74ba8223 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 22:13:05 +0800 Subject: [PATCH 2/7] Reformat markdown files --- docs/_dg/AboutDG.md | 3 ++- docs/_dg/Effort.md | 2 +- docs/_dg/UIComponent.md | 2 +- docs/_dg/implementations/GeneralFeatures.md | 8 +++++--- docs/_ug/TryingFirstCommand.md | 2 +- docs/team/ferusel.md | 16 ++++++++-------- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/_dg/AboutDG.md b/docs/_dg/AboutDG.md index 975c2c8536f..a06c737cae2 100644 --- a/docs/_dg/AboutDG.md +++ b/docs/_dg/AboutDG.md @@ -1,7 +1,8 @@ {{ site.data.foodrem.about.summary_dg }} -This Developer Guide provides in-depth documentation on how FoodRem is designed and implemented. It covers the architecture of FoodRem, detailed specifications on smaller pieces of the design, and an outline of all parts of the software and how they will work. + +This Developer Guide provides in-depth documentation on how FoodRem is designed and implemented. It covers the architecture of FoodRem, detailed specifications on smaller pieces of the design, and an outline of all parts of the software and how they will work. You can use this guide to maintain, upgrade, and evolve FoodRem. diff --git a/docs/_dg/Effort.md b/docs/_dg/Effort.md index 676d7485696..4080402cd56 100644 --- a/docs/_dg/Effort.md +++ b/docs/_dg/Effort.md @@ -9,4 +9,4 @@ One challenge we ran into during the project was implementing a batch feature fo ### Revamping of UI -We wanted a simple yet appealing [[ graphical-user-interface:graphical user interface ]] for our application's users. As such, we decided to change the original UI of AB3 into our own new FoodRem UI. As our team was not familiar with JavaFX initially, it took us considerable time and effort to produce an eventual satisfactory and working UI that we were proud to adopt and incorporate into our application. +We wanted a simple yet appealing [[ graphical-user-interface:graphical user interface ]] for our application's users. As such, we decided to change the original UI of AB3 into our own new FoodRem UI. As our team was not familiar with JavaFX initially, it took us considerable time and effort to produce an eventual satisfactory and working UI that we were proud to adopt and incorporate into our application. diff --git a/docs/_dg/UIComponent.md b/docs/_dg/UIComponent.md index d51ef2da1dc..53efce0f9ae 100644 --- a/docs/_dg/UIComponent.md +++ b/docs/_dg/UIComponent.md @@ -7,7 +7,7 @@ The UI component handles the user-interface portion of the application. The UI consists of a `MainWindow` that is made up of parts, e.g.`CommandBox`, `ResultDisplay`, `ItemListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible [[ graphical-user-interface:GUI ]]. -The `UI` component uses the JavaFx UI framework. The layout of these UI parts is defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [MainWindow]({{ page.master_branch }}/{{ page.main_src }}/ui/MainWindow.java) is specified in [MainWindow.fxml]({{ page.master_branch }}/src/main/resources/view/MainWindow.fxml) +The `UI` component uses the JavaFX UI framework. The layout of these UI parts is defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [MainWindow]({{ page.master_branch }}/{{ page.main_src }}/ui/MainWindow.java) is specified in [MainWindow.fxml]({{ page.master_branch }}/src/main/resources/view/MainWindow.fxml) The `UI` component, diff --git a/docs/_dg/implementations/GeneralFeatures.md b/docs/_dg/implementations/GeneralFeatures.md index 678d4abe3e9..b3af239cc20 100644 --- a/docs/_dg/implementations/GeneralFeatures.md +++ b/docs/_dg/implementations/GeneralFeatures.md @@ -5,10 +5,12 @@ -The `Exit command` and `Reset command` do not contain complex implementations. +The `Exit command` and `Reset command` do not contain complex implementations. + +Exit command returns a `CommandResult` that returns `true` when calling the method `shouldExit()` on it. + +The reset command functions like most other commands. -Exit command returns a `CommandResult` that returns `true` when calling the method `shouldExit()` on it. -The reset command functions like most other commands. The `HelpCommand` is worth looking into, as it involves opening a separate window (`HelpWindow`). #### Displaying Help Dialogs diff --git a/docs/_ug/TryingFirstCommand.md b/docs/_ug/TryingFirstCommand.md index 3345f410720..29f9682d29a 100644 --- a/docs/_ug/TryingFirstCommand.md +++ b/docs/_ug/TryingFirstCommand.md @@ -84,7 +84,7 @@ You should now have a better understanding of how commands are formatted and use Here is a checklist you can use before running a [[ command ]]: -* [ ] I know the restrictions of the command +* [ ] I know the restrictions of the command * [ ] I know what [[ parameter:parameters ]] are supplied to the command * [ ] I know the [[ flag:flags ]] for each parameter to be supplied * [ ] I know the restrictions of each parameter diff --git a/docs/team/ferusel.md b/docs/team/ferusel.md index 982af9f22ae..7da07c76b5d 100644 --- a/docs/team/ferusel.md +++ b/docs/team/ferusel.md @@ -14,10 +14,10 @@ Given below are my contributions to the project. * **New Feature**: Statistics feature - * What it does: Calculates some statistics regarding the Items and Tags in FoodRem's inventory, and displays them to the user. Statistics include: Top three most commonly used tags, top three most expensive items in inventory, total cost accrued due to food waste. - * Highlights: These statistics were chosen after discussion as they were determined to be most useful and provided a high degree of flexibility. It was not easy to choose the statistics. + * What it does: Calculates some statistics regarding the Items and Tags in FoodRem's inventory, and displays them to the user. Statistics include: Top three most commonly used tags, top three most expensive items in inventory, total cost accrued due to food waste. + * Highlights: These statistics were chosen after discussion as they were determined to be most useful and provided a high degree of flexibility. It was not easy to choose the statistics. * Credits: N/A - + * **New Feature**: `Item` class * What it does: Provides an internal representation of an `Item` in FoodRem. Adapted from the original AB3's `Person` class, I laid the foundation by adding the necessary attributes to represent an `Item`. I also wrote test cases for the `Item` class. @@ -28,7 +28,7 @@ Given below are my contributions to the project. * **New Feature**: `inc`, `dec`, `view` commands * What it does: `inc` allows the user to increment a chosen item by a specified quantity. `dec` allows the user to decrement a chosen item by a specified quantity. `view` displays all relevant information about an `Item`, such as the quantity, name, tags, to the user. - * Justification: These are key features for FoodRem. + * Justification: These are key features for FoodRem. * **New Feature**: `sort` command @@ -58,7 +58,7 @@ Given below are my contributions to the project. * Improve UG for v1.3 [[PR#335]] * Fix UG after Peer Review [[PR#351]] * Fix find command description in Command Summary [[PR#324]] - + * Developer Guide: * Add Glossary, UC3, UC4 to Developer Guide [[PR#87]] * Add Glossary section to Developer Guide [[PR#164]] @@ -66,7 +66,7 @@ Given below are my contributions to the project. * Add Sort Command UML [[PR#232]] * Update Developer Guide with v1.3 [[PR#295]] -* ** Features**: +* **Features**: * Add Item model [[PR#143]] * Add Sort Command [[PR#158]] * Add Increment and Decrement Command [[PR#161]] @@ -74,10 +74,10 @@ Given below are my contributions to the project. * Add Statistics Command [[PR#360]] * Update find command [[PR#367]] * Fix stats command [[PR#372]] - + * **Community**: - * Created [forum discussion](https://github.com/nus-cs2103-AY2223S1/forum/issues/413) + * Created [forum discussion](https://github.com/nus-cs2103-AY2223S1/forum/issues/413) * **Misc PRs**: * Add profile picture [[PR#67]] From 84255ecfc48ce9d67f0d6bc0ada6aef3aa72cc07 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 22:50:05 +0800 Subject: [PATCH 3/7] Add UI implementation section --- docs/_dg/implementations/UserInterface.md | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/_dg/implementations/UserInterface.md b/docs/_dg/implementations/UserInterface.md index e69de29bb2d..fbb2b47f1bc 100644 --- a/docs/_dg/implementations/UserInterface.md +++ b/docs/_dg/implementations/UserInterface.md @@ -0,0 +1,42 @@ + +#### General Implementation Details + +FoodRem's User Interface or UI (more specifically, it is a [[ graphical-user-interface:GUI ]]) consists of a main window and the Help Window. In this section, we will focus on the main window only, specifically, the Command Output Box component of the main window and its use of the "views", "models" and "view models". + +#### General Design Considerations + +The main window comprises of three components: the [[ command-input-box:Command Input Box ]] and [[ item-list-box:Item List Box ]] on the left half of the main window, as well as the [[ command-output-box:Command Output Box ]] on the right half. For the Command Input Box, it only needs to render the same component each time in order to provide a text field for the user to type their commands into. Likewise, for the Item List Box, it only needs to render a list each time. While the number of items in the list may be variable, it is still the same component to render the list (specifically, it is JavaFX's `ListView` component). This means that when a command is executed, any UI updates to these first two components can be achieved relatively easily. + +However, the Command Output Box needs to be able to have potentially different rendered views to be shown to the user, depending on what command was run. This is where the "views", "models" and "view models" come in. They are clarified as follows: + +* "Views" return a JavaFX `Node` object in order to place into the Command Output Box +* "Models" represent data entities used in FoodRem. See the [Model Component](#model-component) section above for more information. The "models" that are concerned in the process of rendering outputs to the GUI are [[ item:items ]] and [[ tag:tags ]]. +* "View models" are not always present, and act as a bridge for when the data contained in a single "model" is not enough for the corresponding "view" to be generated. As a "view" can only be generated from a single "view model", when data from one or more "models" need to be processed and/or augmented before a "view" can be generated, the "view model" acts as a bridge to facilitate the process. + +#### Rendering Command Output + +[`UiView`]({{ page.master_branch }}/{{ page.main_src }}/views/UiView.java) is the main class responsible for rendering the view to the Command Output Box. This is achieved when a caller calls `UiView`'s `viewFrom` method. The method then calls the `from` method of one of nine "views", depending on the type of the object that was requested to be rendered. + +The nine "views" are as follows: + +| Class Name | Description | +|------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [`FilterByTagView`]({{ page.master_branch }}/{{ page.main_src }}/views/FilterByTagView.java) | A view resulting from the `filtertag` command. | +| [`ItemView`]({{ page.master_branch }}/{{ page.main_src }}/views/ItemView.java) | A view resulting from the `view` command, as well as a generic view for items which may be used elsewhere. | +| [`ItemWithMessageView`]({{ page.master_branch }}/{{ page.main_src }}/views/ItemWithMessageView.java) | A generic view of an item with a single message above it. This view results from the `dec`, `del`, `edit`, `inc`, `new`, `rmk`, `tag` and `untag` commands. | +| [`StatsView`]({{ page.master_branch }}/{{ page.main_src }}/views/StatsView.java) | A view resulting from the `stats` command. | +| [`StringView`]({{ page.master_branch }}/{{ page.main_src }}/views/StringView.java) | A generic view for a string message. This view is used to display command errors, as well as the outputs of the `exit`, `help`, `reset`, `find`, `list`, and `sort` commands. | +| [`TagToRenameView`]({{ page.master_branch }}/{{ page.main_src }}/views/TagToRenameView.java) | A view resulting from the `renametag` command. | +| [`TagView`]({{ page.master_branch }}/{{ page.main_src }}/views/TagView.java) | A generic view for a [[ tag:Tag ]]. Used in other views to ensure consistency of how a Tag looks like. | +| [`TagsView`]({{ page.master_branch }}/{{ page.main_src }}/views/TagsView.java) | A generic view for multiple [[ tag:tags ]], for use in other views. | +| [`TagsWithMessageView`]({{ page.master_branch }}/{{ page.main_src }}/views/TagsWithMessageView.java) | A view of some tag(s) with a message above them. This view results from the `deletetag`, `listtag` and `newtag` commands. | + +The individual "view" is responsible to generate the JavaFX `Node` structure to be placed into the Command Output Box. This node structure is then placed by `UiView`. + +A sequence diagram of this process is as follows: + + + +```note +This sequence diagram assumes the caller requested a `String` to be rendered. +``` From e90d8b1b4d070ed36f4d4c0a6c34a5ddcc89d671 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 22:56:28 +0800 Subject: [PATCH 4/7] Add future extensions section --- docs/_dg/implementations/UserInterface.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/_dg/implementations/UserInterface.md b/docs/_dg/implementations/UserInterface.md index fbb2b47f1bc..b3b7ef07714 100644 --- a/docs/_dg/implementations/UserInterface.md +++ b/docs/_dg/implementations/UserInterface.md @@ -38,5 +38,11 @@ A sequence diagram of this process is as follows: ```note -This sequence diagram assumes the caller requested a `String` to be rendered. +The above sequence diagram assumes the caller requested a `String` to be rendered. ``` + +##### Future Extensions + +Currently, `UiView` uses a very hacky method to determine the type of the object that was requested to be rendered; it uses consecutive `instanceof` expressions. Ideally, there should be a common interface where the necessary operations required can be achieved through dynamic binding. A possible class diagram is as follows: + + From d7f4e5869bff79498648342a9231b73300df0f8e Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 23:15:13 +0800 Subject: [PATCH 5/7] Create PUML diagrams --- docs/diagrams/UIProposedClassDiagram.puml | 33 +++++++++++++++++++++++ docs/diagrams/UISequenceDiagram.puml | 29 ++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 docs/diagrams/UIProposedClassDiagram.puml create mode 100644 docs/diagrams/UISequenceDiagram.puml diff --git a/docs/diagrams/UIProposedClassDiagram.puml b/docs/diagrams/UIProposedClassDiagram.puml new file mode 100644 index 00000000000..f6c50ae8762 --- /dev/null +++ b/docs/diagrams/UIProposedClassDiagram.puml @@ -0,0 +1,33 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor UI_COLOR_T4 +skinparam classBackgroundColor UI_COLOR + +Class "<>\nViewable" as Viewable + +Class FilterByTagView +Class ItemView +Class ItemWithMessageView +Class StatsView +Class StringView +Class TagToRenameView +Class TagView +Class TagsView +Class TagsWithMessageView + +FilterByTagView ..|> Viewable +ItemView ..|> Viewable +ItemWithMessageView ..|> Viewable +StatsView ..|> Viewable +StringView ..|> Viewable +TagToRenameView ..|> Viewable +TagView ..|> Viewable +TagsView ..|> Viewable +TagsWithMessageView ..|> Viewable + +Class UiView + +Viewable -- UiView + +@enduml diff --git a/docs/diagrams/UISequenceDiagram.puml b/docs/diagrams/UISequenceDiagram.puml new file mode 100644 index 00000000000..5c1a1d258a3 --- /dev/null +++ b/docs/diagrams/UISequenceDiagram.puml @@ -0,0 +1,29 @@ +@startuml +!include style.puml + +' box Logic LOGIC_COLOR_T1 +' participant ":LogicManager" as LogicManager LOGIC_COLOR +' participant ":FoodRemParser" as FoodRemParser LOGIC_COLOR +' participant ":TagCommandParser" as TagCommandParser LOGIC_COLOR +' participant ":TagCommand" as TagCommand LOGIC_COLOR +' participant ":Item" as Item LOGIC_COLOR +' participant ":CommandResult" as CommandResult LOGIC_COLOR + +' end box + +' box Model MODEL_COLOR_T1 +' participant ":Model" as Model MODEL_COLOR +' end box + +[-> UiView : viewFrom("hello") +activate UiView + +UiView -> StringView : from("hello") +activate StringView + +UiView <-- StringView +deactivate StringView + +[<--UiView +deactivate UiView +@enduml From d48d91fce5831363f792f524c1c0040317f7661e Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 23:18:56 +0800 Subject: [PATCH 6/7] Remove unused comments --- docs/diagrams/UISequenceDiagram.puml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/diagrams/UISequenceDiagram.puml b/docs/diagrams/UISequenceDiagram.puml index 5c1a1d258a3..2879cc3123b 100644 --- a/docs/diagrams/UISequenceDiagram.puml +++ b/docs/diagrams/UISequenceDiagram.puml @@ -1,20 +1,6 @@ @startuml !include style.puml -' box Logic LOGIC_COLOR_T1 -' participant ":LogicManager" as LogicManager LOGIC_COLOR -' participant ":FoodRemParser" as FoodRemParser LOGIC_COLOR -' participant ":TagCommandParser" as TagCommandParser LOGIC_COLOR -' participant ":TagCommand" as TagCommand LOGIC_COLOR -' participant ":Item" as Item LOGIC_COLOR -' participant ":CommandResult" as CommandResult LOGIC_COLOR - -' end box - -' box Model MODEL_COLOR_T1 -' participant ":Model" as Model MODEL_COLOR -' end box - [-> UiView : viewFrom("hello") activate UiView From d386f01ad5416722d24c20aaa83f92e8e8c80128 Mon Sep 17 00:00:00 2001 From: Richard Dominick <34370238+RichDom2185@users.noreply.github.com> Date: Mon, 7 Nov 2022 23:20:32 +0800 Subject: [PATCH 7/7] Add diagram images to DG --- docs/_dg/implementations/UserInterface.md | 4 ++-- docs/images/UIProposedClassDiagram.png | Bin 0 -> 23285 bytes docs/images/UISequenceDiagram.png | Bin 0 -> 5340 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/images/UIProposedClassDiagram.png create mode 100644 docs/images/UISequenceDiagram.png diff --git a/docs/_dg/implementations/UserInterface.md b/docs/_dg/implementations/UserInterface.md index b3b7ef07714..42a04dd6d33 100644 --- a/docs/_dg/implementations/UserInterface.md +++ b/docs/_dg/implementations/UserInterface.md @@ -35,7 +35,7 @@ The individual "view" is responsible to generate the JavaFX `Node` structure to A sequence diagram of this process is as follows: - +![](images/UISequenceDiagram.png) ```note The above sequence diagram assumes the caller requested a `String` to be rendered. @@ -45,4 +45,4 @@ The above sequence diagram assumes the caller requested a `String` to be rendere Currently, `UiView` uses a very hacky method to determine the type of the object that was requested to be rendered; it uses consecutive `instanceof` expressions. Ideally, there should be a common interface where the necessary operations required can be achieved through dynamic binding. A possible class diagram is as follows: - +![](images/UIProposedClassDiagram.png) diff --git a/docs/images/UIProposedClassDiagram.png b/docs/images/UIProposedClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..afc44b3d5536d167f7d498e2f189d09df581406a GIT binary patch literal 23285 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 F{{U;o?F0Y- literal 0 HcmV?d00001 diff --git a/docs/images/UISequenceDiagram.png b/docs/images/UISequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..78d1f1cc7b64241bf61fb2b98ce3fb908e22d74f GIT binary patch literal 5340 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 P&xoa_q@`GR-y-NgbYDw6 literal 0 HcmV?d00001