Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY1718S2#105 from Robert-Peng/PetPatien…
Browse files Browse the repository at this point in the history
…tCard

Created PetPatientCard and Panel & Update GUI test
  • Loading branch information
chialejing authored Mar 30, 2018
2 parents d20bed0 + 354d099 commit 585cca8
Show file tree
Hide file tree
Showing 18 changed files with 682 additions and 3 deletions.
25 changes: 23 additions & 2 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -422,12 +422,33 @@ Linking of pet patients to their respective owners and appointments will be impl

// tag::commandsyntax[]

=== Display List of PetPatients
==== Current Implemaentation
Since Veterinarians and their assistants have the need to view the PetPatients as a list and see how many PetPatients belong to the same Owner. It is necessary to implement the PetPatient List feature.

==== Design Consideration
* **Alternative 1:** Use tab function to switch between PetPatientList and PersonList

** Pros: The UI will be neat to see, saves more space for calendar view
** Cons: The user will not be able to see both PetPatient and Owners at the same time.

* **ALternative 2:** Implement another Panel to display PetPatients.

** Pros: User will be able to see both lists at the same time
** Cons: Takes up more space, making it difficult to display appointments in the future.

==== Current Limitations
More command and features relating to PetPatient List are to be properly developed, the tags of PetPatients are not properly organised.

==== Future Work
Implement the corresponding Add, Delete, List commands for petPatients and decide on the tags to be used for petPatients.

=== Show Appointments on calendar
==== Current Implementation

In the original AddressBook app, there's no appointment class to show. Since veterinarians and their assistants have the need to constantly check their schedule for upcoming appointments, a calender feature is required to show future appointments.
Since veterinarians and their assistants have the need to constantly check their schedule for upcoming appointments, a calender feature is required to show future appointments.

Third party API `CalendarF` is used as a Java calendar frame to show Appointments.
Third party API `CalendarFX` is used as a Java calendar frame to show Appointments.

==== Design Consideration
* **Alternative 1:** Use `iCalendar` from Jfxtra library
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package seedu.address.commons.events.ui;

import seedu.address.commons.events.BaseEvent;
import seedu.address.ui.PetPatientCard;

/**
* Represents a selection change in the PetPatient list Panel
*/
public class PetPatientPanelSelectionChangedEvent extends BaseEvent {
private final PetPatientCard newSelection;

public PetPatientPanelSelectionChangedEvent(PetPatientCard newSelection) {
this.newSelection = newSelection;
}

@Override
public String toString() {
return this.getClass().getSimpleName();
}

public PetPatientCard getNewSelection() {
return newSelection;
}
}
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import seedu.address.logic.parser.Prefix;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Person;
import seedu.address.model.petpatient.PetPatient;

/**
* API of the Logic component
Expand All @@ -25,6 +26,9 @@ public interface Logic {
/** Returns an unmodifiable view of the filtered list of persons */
ObservableList<Person> getFilteredPersonList();

/** Returns an unmodifiable view of the filtered list of petPatients */
ObservableList<PetPatient> getFilteredPetPatientList();

/** Returns the list of input entered by the user, encapsulated in a {@code ListElementPointer} object */
ListElementPointer getHistorySnapshot();

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public ObservableList<Person> getFilteredPersonList() {
return model.getFilteredPersonList();
}

@Override
public ObservableList<PetPatient> getFilteredPetPatientList() {
return model.getFilteredPetPatientList();
}

@Override
public ListElementPointer getHistorySnapshot() {
return new ListElementPointer(history.getHistory());
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/seedu/address/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class MainWindow extends UiPart<Stage> {
private CalendarWindow calendarWindow;
//private BrowserPanel browserPanel;
private PersonListPanel personListPanel;
private PetPatientListPanel petPatientListPanel;
private Config config;
private UserPrefs prefs;

Expand All @@ -54,6 +55,9 @@ public class MainWindow extends UiPart<Stage> {
@FXML
private StackPane personListPanelPlaceholder;

@FXML
private StackPane petPatientListPanelPlaceholder;

@FXML
private StackPane resultDisplayPlaceholder;

Expand Down Expand Up @@ -126,6 +130,9 @@ void fillInnerParts() {
personListPanel = new PersonListPanel(logic.getFilteredPersonList());
personListPanelPlaceholder.getChildren().add(personListPanel.getRoot());

petPatientListPanel = new PetPatientListPanel(logic.getFilteredPetPatientList());
petPatientListPanelPlaceholder.getChildren().add(petPatientListPanel.getRoot());

ResultDisplay resultDisplay = new ResultDisplay();
resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot());

Expand Down
93 changes: 93 additions & 0 deletions src/main/java/seedu/address/ui/PetPatientCard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package seedu.address.ui;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import seedu.address.model.petpatient.PetPatient;

/**
* AN UI component that displays the information of a {@code PetPatient}
*/
public class PetPatientCard extends UiPart<Region> {
private static final String FXML = "PetPatientListCard.fxml";

private static final String[] TAG_COLOR_STYLES =
{"teal", "red", "yellow", "blue", "orange", "brown", "green", "pink",
"black", "grey"};

public final PetPatient petPatient;

@FXML
private HBox cardPane;
@FXML
private Label name;
@FXML
private Label id;
@FXML
private Label species;
@FXML
private Label breed;
@FXML
private Label colour;
@FXML
private Label bloodType;
@FXML
private Label ownerNric;
@FXML
private FlowPane tags;

public PetPatientCard(PetPatient petPatient, int displayedIndex) {
super(FXML);
this.petPatient = petPatient;
id.setText(displayedIndex + ". ");
name.setText(petPatient.getName().toString());
species.setText(petPatient.getSpecies());
breed.setText(petPatient.getBreed());
colour.setText(petPatient.getColour());
bloodType.setText(petPatient.getBloodType());
ownerNric.setText(petPatient.getOwner().toString());
createTags(petPatient);
}

/**
* Returns the color style for {@code tagName}'s label.
* Solution below adopted from :
* https://github.com/se-edu/addressbook-level4/pull/798/commits/167b3d0b4f7ad34296d2fbf505f9ae71f983f53c
*/
private String getTagColorStyleFor(String tagName) {
// we use the hash code of the tag name to generate a random color, so that the color remain consistent
// between different runs of the program while still making it random enough between tags.
return TAG_COLOR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOR_STYLES.length];
}

/**
* Creates the tag labels for {@code PetPatient}.
*/
private void createTags(PetPatient petPatient) {
petPatient.getTags().forEach(tag -> {
Label tagLabel = new Label(tag.tagName);
tagLabel.getStyleClass().add(getTagColorStyleFor(tag.tagName));
tags.getChildren().add(tagLabel);
});
}

@Override
public boolean equals(Object other) {
// short circuit if same object
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof PetPatientCard)) {
return false;
}

// state check
PetPatientCard card = (PetPatientCard) other;
return id.getText().equals(card.id.getText())
&& petPatient.equals(card.petPatient);
}
}
88 changes: 88 additions & 0 deletions src/main/java/seedu/address/ui/PetPatientListPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package seedu.address.ui;

import java.util.logging.Logger;

import org.fxmisc.easybind.EasyBind;

import com.google.common.eventbus.Subscribe;

import javafx.application.Platform;
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.commons.events.ui.JumpToListRequestEvent;
import seedu.address.commons.events.ui.PetPatientPanelSelectionChangedEvent;
import seedu.address.model.petpatient.PetPatient;

/**
* Panel containing list of PetPatients
*/
public class PetPatientListPanel extends UiPart<Region> {
private static final String FXML = "PetPatientListPanel.fxml";
private final Logger logger = LogsCenter.getLogger(PetPatientListPanel.class);

@FXML
private ListView<PetPatientCard> petPatientListView;

public PetPatientListPanel(ObservableList<PetPatient> petPatientList) {
super(FXML);
setConnections(petPatientList);
registerAsAnEventHandler(this);
}

private void setConnections(ObservableList<PetPatient> petPatientList) {
ObservableList<PetPatientCard> mappedList = EasyBind.map(
petPatientList, (petPatient) -> new PetPatientCard(petPatient, petPatientList.indexOf(petPatient) + 1));
petPatientListView.setItems(mappedList);
petPatientListView.setCellFactory(listView -> new PetPatientListViewCell());
setEventHandlerForSelectionChangeEvent();
}

private void setEventHandlerForSelectionChangeEvent() {
petPatientListView.getSelectionModel().selectedItemProperty()
.addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
logger.fine("Selection in petPatient list panel changed to : '" + newValue + "'");
raise(new PetPatientPanelSelectionChangedEvent(newValue));
}
});
}

/**
* Scrolls to the {@code PetPatientCard} at the {@code index} and selects it.
*/
private void scrollTo(int index) {
Platform.runLater(() -> {
petPatientListView.scrollTo(index);
petPatientListView.getSelectionModel().clearAndSelect(index);
});
}

@Subscribe
private void handleJumpToListRequestEvent(JumpToListRequestEvent event) {
logger.info(LogsCenter.getEventHandlingLogMessage(event));
scrollTo(event.targetIndex);
}

/**
* Custom {@code ListCell} that displays the graphics of a {@code PetPatientCard}.
*/
class PetPatientListViewCell extends ListCell<PetPatientCard> {

@Override
protected void updateItem(PetPatientCard petPatient, boolean empty) {
super.updateItem(petPatient, empty);

if (empty || petPatient == null) {
setGraphic(null);
setText(null);
} else {
setGraphic(petPatient.getRoot());
}
}
}

}
9 changes: 8 additions & 1 deletion src/main/resources/view/MainWindow.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<?import javafx.scene.layout.VBox?>

<fx:root type="javafx.stage.Stage" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
minWidth="450" minHeight="600">
minWidth="1200" minHeight="800">
<icons>
<Image url="@/images/address_book_32.png" />
</icons>
Expand Down Expand Up @@ -54,6 +54,13 @@
<StackPane fx:id="personListPanelPlaceholder" VBox.vgrow="ALWAYS"/>
</VBox>

<VBox fx:id="petPatientList" minWidth="340" prefWidth="340" SplitPane.resizableWithParent="false">
<padding>
<Insets top="10" right="10" bottom="10" left="10" />
</padding>
<StackPane fx:id="petPatientListPanelPlaceholder" VBox.vgrow="ALWAYS"/>
</VBox>

<StackPane fx:id="calendarPlaceholder" prefWidth="200" >
<padding>
<Insets top="10" right="10" bottom="10" left="10" />
Expand Down
38 changes: 38 additions & 0 deletions src/main/resources/view/PetPatientListCard.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>

<HBox id="cardPane" fx:id="cardPane" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
<GridPane HBox.hgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10" prefWidth="150" />
</columnConstraints>
<VBox alignment="CENTER_LEFT" minHeight="105" GridPane.columnIndex="0">
<padding>
<Insets bottom="5" left="15" right="5" top="5" />
</padding>
<HBox alignment="CENTER_LEFT" spacing="5">
<Label fx:id="id" styleClass="cell_big_label">
<minWidth>
<!-- Ensures that the label text is never truncated -->
<Region fx:constant="USE_PREF_SIZE" />
</minWidth>
</Label>
<Label fx:id="name" styleClass="cell_big_label" text="\$first" />
</HBox>
<FlowPane fx:id="tags" />
<Label fx:id="species" styleClass="cell_small_label" text="\$species" />
<Label fx:id="breed" styleClass="cell_small_label" text="\$breed" />
<Label fx:id="colour" styleClass="cell_small_label" text="\$colour" />
<Label fx:id="bloodType" styleClass="cell_small_label" text="\$bloodType" />
<Label fx:id="ownerNric" styleClass="cell_small_label" text="\$ownerNric" />
</VBox>
</GridPane>
</HBox>
8 changes: 8 additions & 0 deletions src/main/resources/view/PetPatientListPanel.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<ListView fx:id="petPatientListView" VBox.vgrow="ALWAYS" />
</VBox>
Loading

0 comments on commit 585cca8

Please sign in to comment.