diff --git a/build.gradle b/build.gradle index 077ce09ba8a..85b5bbf63be 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id 'jacoco' id 'checkstyle' id 'com.github.kt3k.coveralls' version '2.4.0' - id 'com.github.johnrengelman.shadow' version '4.0.4' + id 'com.github.johnrengelman.shadow' version '5.1.0' id 'org.asciidoctor.convert' version '1.5.6' id 'application' } @@ -72,9 +72,10 @@ dependencies { } shadowJar { - archiveName = 'addressbook.jar' - - destinationDir = file("${buildDir}/jar/") + archiveBaseName = 'Mortago' + archiveVersion = "v1.2.1" + archiveClassifier = null + archiveAppendix = null } task coverage(type: JacocoReport) { diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index e5cfb161b73..453e69d2903 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -6,7 +6,9 @@ import java.util.logging.Logger; import javafx.application.Application; +import javafx.application.Platform; import javafx.stage.Stage; +import javafx.stage.StageStyle; import seedu.address.commons.core.Config; import seedu.address.commons.core.LogsCenter; import seedu.address.commons.core.Version; @@ -36,7 +38,7 @@ */ public class MainApp extends Application { - public static final Version VERSION = new Version(0, 6, 0, true); + public static final Version VERSION = new Version(1, 2, 1, true); private static final Logger logger = LogsCenter.getLogger(MainApp.class); @@ -168,6 +170,7 @@ protected UserPrefs initPrefs(UserPrefsStorage storage) { @Override public void start(Stage primaryStage) { logger.info("Starting AddressBook " + MainApp.VERSION); + primaryStage.initStyle(StageStyle.TRANSPARENT); ui.start(primaryStage); } @@ -179,5 +182,7 @@ public void stop() { } catch (IOException e) { logger.severe("Failed to save preferences " + StringUtil.getDetails(e)); } + Platform.exit(); + System.exit(0); } } diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index f9bbf0cc05e..f12a1cda9bb 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -67,14 +67,14 @@ public interface Logic { * Selected body in the filtered body list. * null if no body is selected. * - * @see seedu.address.model.Model#selectedPersonProperty() + * @see seedu.address.model.Model#selectedBodyProperty() */ ReadOnlyProperty selectedBodyProperty(); /** - * Sets the selected person in the filtered person list. + * Sets the selected person in the filtered body list. * - * @see seedu.address.model.Model#setSelectedPerson(Person) + * @see seedu.address.model.Model#setSelectedBody(Body) */ void setSelectedBody(Body body); //@@ shaoyi1997-reused diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index 84ede69d003..58ad8c3c290 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -106,6 +106,8 @@ public CommandResult execute(Model model) throws CommandException { model.addEntity(toAdd); if (toAdd instanceof Body) { + SelectCommand selectCommand = new SelectCommand(toAdd.getIdNum().getIdNum()); + selectCommand.execute(model); Body body = (Body) toAdd; NotifCommand notifCommand = new NotifCommand(new Notif(body), NOTIF_PERIOD, TimeUnit.SECONDS); this.notifCommand = notifCommand; diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index b84ebb7af56..a4088748f98 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; +import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.AddressBook; import seedu.address.model.Model; import seedu.address.model.ReadOnlyAddressBook; @@ -23,12 +24,13 @@ public class ClearCommand extends UndoableCommand { @Override - public CommandResult execute(Model model) { + public CommandResult execute(Model model) throws CommandException { requireNonNull(model); savedModel = new AddressBook(model.getAddressBook()); model.setAddressBook(new AddressBook()); UniqueIdentificationNumberMaps.clearAllEntries(); - + SelectCommand selectCommand = new SelectCommand(Integer.MAX_VALUE); + selectCommand.execute(model); setUndoable(); model.addExecutedCommand(this); return new CommandResult(MESSAGE_SUCCESS); diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index bc672ddd2ca..2b9203ef183 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -99,6 +99,8 @@ public CommandResult execute(Model model) throws CommandException { targetIdNum.removeMapping(); setUndoable(); model.addExecutedCommand(this); + SelectCommand selectCommand = new SelectCommand(Integer.MAX_VALUE); + selectCommand.execute(model); return new CommandResult(String.format(MESSAGE_DELETE_ENTITY_SUCCESS, entityToDelete)); } else { throw new CommandException(Messages.MESSAGE_INVALID_ENTITY_DISPLAYED_INDEX); diff --git a/src/main/java/seedu/address/logic/commands/NotifCommand.java b/src/main/java/seedu/address/logic/commands/NotifCommand.java index 6230f6b1804..a7d22e91d5e 100644 --- a/src/main/java/seedu/address/logic/commands/NotifCommand.java +++ b/src/main/java/seedu/address/logic/commands/NotifCommand.java @@ -17,9 +17,9 @@ import seedu.address.model.entity.body.Body; import seedu.address.model.notif.Notif; import seedu.address.ui.NotifWindow; +import seedu.address.ui.NotificationButton; //@@author arjavibahety - /** * Notifies a user when there is an automatic change in BodyStatus. */ @@ -104,6 +104,7 @@ public void startSesChangeBodyStatusUi(Model model) throws CommandException { logger.info("Error updating the body and fridge "); } } + NotificationButton.getInstanceOfNotifButton().setIconNumber(model.getNumberOfNotifs()); }); ses.schedule(changeUi, period, timeUnit); diff --git a/src/main/java/seedu/address/logic/commands/SelectCommand.java b/src/main/java/seedu/address/logic/commands/SelectCommand.java index 73bdd52359e..0626552288b 100644 --- a/src/main/java/seedu/address/logic/commands/SelectCommand.java +++ b/src/main/java/seedu/address/logic/commands/SelectCommand.java @@ -2,12 +2,10 @@ import static java.util.Objects.requireNonNull; -import java.util.List; - import seedu.address.commons.core.Messages; -import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; +import seedu.address.model.entity.IdentificationNumber; import seedu.address.model.entity.body.Body; //@@ shaoyi1997-reused @@ -26,32 +24,33 @@ public class SelectCommand extends Command { public static final String MESSAGE_SELECT_BODY_SUCCESS = "Selected Body: %1$s"; - private final Index targetIndex; + private final int targetId; - public SelectCommand(Index targetIndex) { - this.targetIndex = targetIndex; + public SelectCommand(int targetId) { + this.targetId = targetId; } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - - List filteredBodyList = model.getFilteredBodyList(); - - if (targetIndex.getZeroBased() >= filteredBodyList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_ENTITY_DISPLAYED_INDEX); + IdentificationNumber targetIdNum = IdentificationNumber.customGenerateId("B", + targetId); + if (!IdentificationNumber.isExistingIdentificationNumber(targetIdNum)) { + model.setSelectedBody(null); + if (targetId != Integer.MAX_VALUE) { + throw new CommandException(Messages.MESSAGE_INVALID_ENTITY_DISPLAYED_INDEX); + } } - - model.setSelectedBody(filteredBodyList.get(targetIndex.getZeroBased())); - return new CommandResult(String.format(MESSAGE_SELECT_BODY_SUCCESS, targetIndex.getOneBased())); - + Body selectedBody = (Body) targetIdNum.getMapping(); + model.setSelectedBody(selectedBody); + return new CommandResult(String.format(MESSAGE_SELECT_BODY_SUCCESS, targetId)); } @Override public boolean equals(Object other) { return other == this // short circuit if same object || (other instanceof SelectCommand // instanceof handles nulls - && targetIndex.equals(((SelectCommand) other).targetIndex)); // state check + && targetId == ((SelectCommand) other).targetId); // state check } } //@@ shaoyi1997-reused diff --git a/src/main/java/seedu/address/logic/commands/UpdateCommand.java b/src/main/java/seedu/address/logic/commands/UpdateCommand.java index 8a49ef019ba..aa864701ed0 100644 --- a/src/main/java/seedu/address/logic/commands/UpdateCommand.java +++ b/src/main/java/seedu/address/logic/commands/UpdateCommand.java @@ -165,6 +165,8 @@ public CommandResult execute(Model model) throws CommandException { } else { model.setEntity(entity, updateEntityDescriptor.apply(entity)); } + SelectCommand selectCommand = new SelectCommand(Integer.MAX_VALUE); + selectCommand.execute(model); } catch (NullPointerException e) { throw new CommandException(MESSAGE_ENTITY_NOT_FOUND); } diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 5e73eb7f91f..63182043e56 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -153,6 +153,9 @@ private static Body parseFieldsBody(ArgumentMultimap argMultimap) throws ParseEx String details = ParserUtil.parseStringFields(argMultimap.getValue(PREFIX_BODY_DETAILS).orElse("")); List organsForDonation = ParserUtil.parseOrgansForDonation( argMultimap.getValue(PREFIX_ORGANS_FOR_DONATION).orElse("")); + Religion religion = ParserUtil.parseReligion(argMultimap.getValue(PREFIX_RELIGION).orElse("")); + String relationship = ParserUtil.parseStringFields(argMultimap.getValue(PREFIX_RELATIONSHIP) + .orElse("")); IdentificationNumber fridgeId = ParserUtil.parseIdentificationNumber( argMultimap.getValue(PREFIX_FRIDGE_ID).orElse("")); if (fridgeId != null) { @@ -163,11 +166,8 @@ private static Body parseFieldsBody(ArgumentMultimap argMultimap) throws ParseEx throw new ParseException(MESSAGE_INEXISTENT_FRIDGE); } } - Religion religion = ParserUtil.parseReligion(argMultimap.getValue(PREFIX_RELIGION).orElse("")); - String relationship = ParserUtil.parseStringFields(argMultimap.getValue(PREFIX_RELATIONSHIP) - .orElse("")); - return new Body(false, 1, dateOfAdmission, name, sex, nric, religion, + return new Body(dateOfAdmission, name, sex, nric, religion, causeOfDeath, organsForDonation, status, fridgeId, dateOfBirth, dateOfDeath, nameNok, relationship, phoneNok); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index e8dc217b5fc..4960560e0f5 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -20,8 +20,8 @@ public class CliSyntax { public static final Prefix PREFIX_DATE_OF_ADMISSION = new Prefix("/doa"); public static final Prefix PREFIX_NRIC = new Prefix("/nric"); public static final Prefix PREFIX_RELIGION = new Prefix("/religion"); - public static final Prefix PREFIX_NAME_NOK = new Prefix("/nameNOK"); - public static final Prefix PREFIX_PHONE_NOK = new Prefix("/phoneNOK"); + public static final Prefix PREFIX_NAME_NOK = new Prefix("/NOKname"); + public static final Prefix PREFIX_PHONE_NOK = new Prefix("/NOKphone"); public static final Prefix PREFIX_CAUSE_OF_DEATH = new Prefix("/cod"); public static final Prefix PREFIX_BODY_DETAILS = new Prefix("/details"); public static final Prefix PREFIX_ORGANS_FOR_DONATION = new Prefix("/organsForDonation"); diff --git a/src/main/java/seedu/address/logic/parser/SelectCommandParser.java b/src/main/java/seedu/address/logic/parser/SelectCommandParser.java index da408e0ed82..e5ced9ec295 100644 --- a/src/main/java/seedu/address/logic/parser/SelectCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/SelectCommandParser.java @@ -21,7 +21,7 @@ public class SelectCommandParser implements Parser { public SelectCommand parse(String args) throws ParseException { try { Index index = ParserUtil.parseIndex(args); - return new SelectCommand(index); + return new SelectCommand(index.getOneBased()); } catch (ParseException pe) { throw new ParseException( String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE), pe); diff --git a/src/main/java/seedu/address/logic/parser/utility/UpdateBodyDescriptor.java b/src/main/java/seedu/address/logic/parser/utility/UpdateBodyDescriptor.java index a4261482508..ceb86be515b 100644 --- a/src/main/java/seedu/address/logic/parser/utility/UpdateBodyDescriptor.java +++ b/src/main/java/seedu/address/logic/parser/utility/UpdateBodyDescriptor.java @@ -72,7 +72,7 @@ public UpdateBodyDescriptor(Body body) { this.nric = body.getNric().orElse(null); this.religion = body.getReligion().orElse(null); this.causeOfDeath = body.getCauseOfDeath().orElse(null); - this.organsForDonation = body.getOrgansForDonation().orElse(null); + this.organsForDonation = body.getOrgansForDonation(); this.bodyStatus = body.getBodyStatus().orElse(null); this.fridgeId = body.getFridgeId().orElse(null); this.dateOfBirth = body.getDateOfBirth().orElse(null); @@ -104,7 +104,7 @@ public Entity apply(Entity entity) { body.setNric(this.getNric().orElse(body.getNric().orElse(null))); body.setReligion(this.getReligion().orElse(body.getReligion().orElse(null))); body.setCauseOfDeath(this.getCauseOfDeath().orElse(body.getCauseOfDeath().orElse(null))); - body.setOrgansForDonation(this.getOrgansForDonation().orElse(body.getOrgansForDonation().orElse(null))); + body.setOrgansForDonation(this.getOrgansForDonation().orElse(body.getOrgansForDonation())); body.setBodyStatus(this.getBodyStatus().orElse(body.getBodyStatus().orElse(null))); body.setFridgeId(this.getFridgeId().orElse(body.getFridgeId().orElse(null))); body.setDateOfBirth(this.getDateOfBirth().orElse(body.getDateOfBirth().orElse(null))); diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index b6bedc5042a..48c1932a3cf 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -147,6 +147,10 @@ public interface Model { */ void setNotif(Notif target, Notif editedNotif); + /** + * Returns the total number of notifications in the system. + */ + int getNumberOfNotifs(); /** Returns an unmodifiable view of the filtered person list */ ObservableList getFilteredPersonList(); diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 482a846be9b..5d2f3847132 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -210,6 +210,11 @@ public void setNotif(Notif target, Notif editedNotif) { addressBook.setNotif(target, editedNotif); } + + @Override + public int getNumberOfNotifs() { + return filteredNotifs.size(); + } //=========== Filtered Body List Accessors ============================================================= /** * Returns an unmodifiable view of the list of {@code Worker} backed by the internal list of diff --git a/src/main/java/seedu/address/model/UniqueNotifsList.java b/src/main/java/seedu/address/model/UniqueNotifsList.java index 2b124083add..ac4dbf6a0e6 100644 --- a/src/main/java/seedu/address/model/UniqueNotifsList.java +++ b/src/main/java/seedu/address/model/UniqueNotifsList.java @@ -108,7 +108,6 @@ public void setNotifs(List notifs) { internalListNotifs.setAll(notifs); } - /** * Returns the backing Notif list as an unmodifiable {@code ObservableList}. */ diff --git a/src/main/java/seedu/address/model/entity/IdentificationNumber.java b/src/main/java/seedu/address/model/entity/IdentificationNumber.java index 9733b98c2ba..a37dc6b12d9 100644 --- a/src/main/java/seedu/address/model/entity/IdentificationNumber.java +++ b/src/main/java/seedu/address/model/entity/IdentificationNumber.java @@ -28,7 +28,6 @@ public class IdentificationNumber { private int idNum; private String typeOfEntity; - private boolean isTestId = false; protected IdentificationNumber(Entity entity) { requireNonNull(entity); @@ -57,10 +56,9 @@ protected IdentificationNumber(Entity entity, int id) { } //@@author - private IdentificationNumber(String typeOfEntity, int idNum, boolean isTestId) { + private IdentificationNumber(String typeOfEntity, int idNum) { this.typeOfEntity = typeOfEntity; this.idNum = idNum; - this.isTestId = isTestId; } public static IdentificationNumber generateNewBodyId(Body body) { @@ -88,11 +86,7 @@ public static IdentificationNumber generateNewFridgeId(Fridge fridge, int id) { } public static IdentificationNumber customGenerateId(String typeOfEntity, int idNum) { - return new IdentificationNumber(typeOfEntity, idNum, false); - } - - public static IdentificationNumber customGenerateTestId(String typeOfEntity, int idNum) { - return new IdentificationNumber(typeOfEntity, idNum, true); + return new IdentificationNumber(typeOfEntity, idNum); } private static boolean isValidIdPrefix (String prefix) { @@ -143,6 +137,13 @@ public static boolean isExistingIdentificationNumber(String fullIdString) { } } + /** + * Checks if given {@code IdentificationNumber id} already exists in Mortago. + */ + public static boolean isExistingIdentificationNumber(IdentificationNumber id) { + return isExistingIdentificationNumber(id.toString()); + } + public String getTypeOfEntity() { return typeOfEntity; } diff --git a/src/main/java/seedu/address/model/entity/UniqueIdentificationNumberMaps.java b/src/main/java/seedu/address/model/entity/UniqueIdentificationNumberMaps.java index a14e3450439..1583f52442f 100644 --- a/src/main/java/seedu/address/model/entity/UniqueIdentificationNumberMaps.java +++ b/src/main/java/seedu/address/model/entity/UniqueIdentificationNumberMaps.java @@ -166,6 +166,10 @@ public static void clearAllEntries() { uniqueWorkerMap.clear(); } + /** + * Returns the entity that belongs to the supplied Identification Number details. + * Guarantee: Identification Number is present and will not retrieve a null. + */ public static Entity getMapping(String typeOfEntity, int id) { if (typeOfEntity.equals("W")) { return uniqueWorkerMap.get(id); diff --git a/src/main/java/seedu/address/model/entity/body/Body.java b/src/main/java/seedu/address/model/entity/body/Body.java index 809d4d009da..03baa37c2ad 100644 --- a/src/main/java/seedu/address/model/entity/body/Body.java +++ b/src/main/java/seedu/address/model/entity/body/Body.java @@ -28,7 +28,7 @@ public class Body implements Entity { private Optional religion; private Optional causeOfDeath; - private Optional> organsForDonation; + private List organsForDonation; private Optional bodyStatus; private Optional fridgeId; private Optional dateOfBirth; @@ -43,23 +43,18 @@ public Body(Date dateOfAdmission) { this.dateOfAdmission = dateOfAdmission; } - public Body(boolean isTestUnit, int identificationNumber, Date dateOfAdmission, Name name, Sex sex, Nric nric, + public Body(Date dateOfAdmission, Name name, Sex sex, Nric nric, Religion religion, String causeOfDeath, List organsForDonation, BodyStatus bodyStatus, IdentificationNumber fridgeId, Date dateOfBirth, Date dateOfDeath, Name nextOfKin, String relationship, PhoneNumber kinPhoneNumber) { - if (isTestUnit) { - this.bodyIdNum = IdentificationNumber.customGenerateTestId("B", - identificationNumber); - } else { - this.bodyIdNum = IdentificationNumber.generateNewBodyId(this); - } + this.bodyIdNum = IdentificationNumber.generateNewBodyId(this); this.dateOfAdmission = dateOfAdmission; this.name = name; this.sex = sex; this.nric = Optional.ofNullable(nric); this.religion = Optional.ofNullable(religion); this.causeOfDeath = Optional.ofNullable(causeOfDeath); - this.organsForDonation = Optional.ofNullable(organsForDonation); + this.organsForDonation = organsForDonation; this.bodyStatus = Optional.ofNullable(bodyStatus); this.fridgeId = Optional.ofNullable(fridgeId); this.dateOfBirth = Optional.ofNullable(dateOfBirth); @@ -178,12 +173,12 @@ public void setCauseOfDeath(String causeOfDeath) { this.causeOfDeath = Optional.ofNullable(causeOfDeath); } - public Optional> getOrgansForDonation() { + public List getOrgansForDonation() { return organsForDonation; } public void setOrgansForDonation(List organsForDonation) { - this.organsForDonation = Optional.ofNullable(organsForDonation); + this.organsForDonation = organsForDonation; } public Optional getBodyStatus() { @@ -235,7 +230,7 @@ && getRelationship().equals(body.getRelationship()) @Override public int hashCode() { - return Objects.hash(getIdNum(), getDateOfAdmission(), getName(), getSex(), getNric(), + return Objects.hash(getDateOfAdmission(), getName(), getSex(), getNric(), getReligion(), getCauseOfDeath(), getOrgansForDonation(), getBodyStatus(), getFridgeId(), getDateOfBirth(), getDateOfDeath(), getNextOfKin(), getRelationship(), getKinPhoneNumber()); } @@ -284,6 +279,8 @@ public boolean isSameBodyIdNum(Object o) { public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(getName()) + .append(" Body ID: ") + .append(getIdNum()) .append(" Sex: ") .append(getSex()) .append(" NRIC: ") @@ -299,7 +296,7 @@ public String toString() { .append(" Date of Birth: ") .append(dateOfBirth.isPresent() ? dateOfBirth.get() : OPTIONAL_FIELD_EMPTY) .append(" Organs for Donation: ") - .append(organsForDonation.isPresent() ? organsForDonation.get() : OPTIONAL_FIELD_EMPTY) + .append(organsForDonation) .append(" Fridge ID: ") .append(fridgeId.isPresent() ? fridgeId.get() : OPTIONAL_FIELD_EMPTY) .append(" Body Status: ") diff --git a/src/main/java/seedu/address/model/entity/fridge/Fridge.java b/src/main/java/seedu/address/model/entity/fridge/Fridge.java index a8b1267b53c..e058a40f4f4 100644 --- a/src/main/java/seedu/address/model/entity/fridge/Fridge.java +++ b/src/main/java/seedu/address/model/entity/fridge/Fridge.java @@ -31,16 +31,6 @@ public Fridge() { this.body = Optional.ofNullable(null); } - public Fridge(boolean isTestFridge) { - if (isTestFridge) { - fridgeIdNum = IdentificationNumber.customGenerateTestId("F", 1); - } else { - this.fridgeIdNum = IdentificationNumber.generateNewFridgeId(this); - } - this.fridgeStatus = FridgeStatus.UNOCCUPIED; - this.body = Optional.ofNullable(null); - } - public Fridge(Body body) { this.fridgeIdNum = IdentificationNumber.generateNewFridgeId(this); this.body = Optional.ofNullable(body); @@ -51,24 +41,10 @@ public Fridge(Body body) { } } - public Fridge(Body body, boolean isTestFridge) { - if (isTestFridge) { - this.fridgeIdNum = IdentificationNumber.customGenerateTestId("F", 1); - } else { - this.fridgeIdNum = IdentificationNumber.generateNewFridgeId(this); - } - this.body = Optional.ofNullable(body); - if (body == null) { - this.fridgeStatus = FridgeStatus.UNOCCUPIED; - } else { - this.fridgeStatus = FridgeStatus.OCCUPIED; - } - } - //@@author ambervoong - private Fridge(boolean isTest, boolean wasStored) { - if (isTest && !wasStored) { - fridgeIdNum = IdentificationNumber.customGenerateTestId("F", 1); + private Fridge(boolean wasStored) { + if (!wasStored) { + fridgeIdNum = IdentificationNumber.customGenerateId("F", 1); } } //@@author @@ -82,7 +58,7 @@ public static Fridge generateNewStoredFridge(int id) { if (id <= 0) { throw new IllegalArgumentException(); } - Fridge fridge = new Fridge(false, true); + Fridge fridge = new Fridge(true); fridge.fridgeIdNum = IdentificationNumber.generateNewFridgeId(fridge, id); return fridge; } @@ -164,7 +140,7 @@ public boolean equals(Object other) { @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(fridgeIdNum); + return Objects.hash(getIdNum()); } @Override diff --git a/src/main/java/seedu/address/model/entity/worker/Worker.java b/src/main/java/seedu/address/model/entity/worker/Worker.java index a7dc89991ce..1952eec65cc 100644 --- a/src/main/java/seedu/address/model/entity/worker/Worker.java +++ b/src/main/java/seedu/address/model/entity/worker/Worker.java @@ -35,27 +35,11 @@ public Worker(Name name, PhoneNumber phone, Sex sex, String employmentStatus, Da String designation) { this.workerIdNum = IdentificationNumber.generateNewWorkerId(this); this.name = name; - this.phone = Optional.ofNullable(phone); this.sex = sex; - this.employmentStatus = Optional.ofNullable(employmentStatus); - this.dateOfBirth = Optional.ofNullable(dateOfBirth); this.dateJoined = dateJoined; - this.designation = Optional.ofNullable(designation); - } - - public Worker(Name name, PhoneNumber phone, Sex sex, String employmentStatus, Date dateOfBirth, Date dateJoined, - String designation, boolean isTestWorker) { - if (isTestWorker) { - this.workerIdNum = IdentificationNumber.customGenerateTestId("W", 1); - } else { - this.workerIdNum = IdentificationNumber.generateNewWorkerId(this); - } - this.name = name; this.phone = Optional.ofNullable(phone); - this.sex = sex; this.employmentStatus = Optional.ofNullable(employmentStatus); this.dateOfBirth = Optional.ofNullable(dateOfBirth); - this.dateJoined = dateJoined; this.designation = Optional.ofNullable(designation); } @@ -63,6 +47,10 @@ public Worker(Name name, Sex sex, Date dateJoined) { this.name = name; this.sex = sex; this.dateJoined = dateJoined; + this.employmentStatus = Optional.empty(); + this.designation = Optional.empty(); + this.phone = Optional.empty(); + this.dateOfBirth = Optional.empty(); } /** @@ -84,7 +72,6 @@ public static Worker generateNewStoredWorker(Name name, Sex sex, Date dateJoined return worker; } - public IdentificationNumber getIdNum() { return workerIdNum; } @@ -189,7 +176,7 @@ public boolean equals(Object other) { @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, sex, workerIdNum, employmentStatus, dateJoined, dateOfBirth, designation); + return Objects.hash(name, phone, sex, employmentStatus, dateJoined, dateOfBirth, designation); } @Override diff --git a/src/main/java/seedu/address/storage/JsonAdaptedBody.java b/src/main/java/seedu/address/storage/JsonAdaptedBody.java index b6975ac60c7..c13b60b2483 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedBody.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedBody.java @@ -120,7 +120,7 @@ public JsonAdaptedBody(Body source) { } if (!(source.getOrgansForDonation().isEmpty())) { - organsForDonation.addAll(source.getOrgansForDonation().get()); + organsForDonation.addAll(source.getOrgansForDonation()); } } diff --git a/src/main/java/seedu/address/storage/ReportGenerator.java b/src/main/java/seedu/address/storage/ReportGenerator.java index def38cf8d50..fcaefb9edbb 100644 --- a/src/main/java/seedu/address/storage/ReportGenerator.java +++ b/src/main/java/seedu/address/storage/ReportGenerator.java @@ -80,13 +80,11 @@ private static void addOtherDetails(Document document, Body body) throws Documen new PdfPCell(new Paragraph(String.format("%s", body.getCauseOfDeath())))); } List organList = new List(); - if (body.getOrgansForDonation().isPresent()) { - for (String organ : body.getOrgansForDonation().get()) { - organList.add(new ListItem(organ)); - } - if (organList.isEmpty()) { - organList.add("No organs for donation."); - } + for (String organ : body.getOrgansForDonation()) { + organList.add(new ListItem(organ)); + } + if (organList.isEmpty()) { + organList.add("No organs for donation."); } PdfPCell cell = new PdfPCell(); cell.addElement(organList); diff --git a/src/main/java/seedu/address/ui/BodyCardSelected.java b/src/main/java/seedu/address/ui/BodyCardSelected.java index 0a5cc6c7a76..e35698ad57e 100644 --- a/src/main/java/seedu/address/ui/BodyCardSelected.java +++ b/src/main/java/seedu/address/ui/BodyCardSelected.java @@ -1,9 +1,12 @@ package seedu.address.ui; +import java.util.Comparator; + import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.control.Label; -import javafx.scene.layout.HBox; +import javafx.scene.image.ImageView; +import javafx.scene.layout.FlowPane; import javafx.scene.layout.Region; import seedu.address.model.entity.body.Body; @@ -12,7 +15,8 @@ */ public class BodyCardSelected extends UiPart { - private static final String FXML = "BodyListCard.fxml"; + private static final String FXML = "SelectedBodyCard.fxml"; + private static final String NO_INPUT_DISPLAY = "-"; /** * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. @@ -25,29 +29,94 @@ public class BodyCardSelected extends UiPart { public final Body body = null; @FXML - private HBox cardPane; + private Label selectedBodyId; + @FXML + private Label selectedBodyName; + @FXML + private Label selectedBodySex; + @FXML + private ImageView sexIcon; + @FXML + private Label selectedBodyNric; + @FXML + private Label selectedBodyReligion; @FXML - private Label name; + private Label selectedBodyDateOfAdmission; @FXML - private Label id; + private Label selectedBodyDateOfDeath; @FXML - private Label bodyId; + private Label selectedBodyDateOfBirth; @FXML - private Label dateOfAdmission; + private FlowPane organs; + @FXML + private Label selectedBodyNokName; + @FXML + private Label selectedBodyNokRelationship; + @FXML + private Label selectedBodyNokPhone; + @FXML + private Label selectedBodyCauseOfDeath; + public BodyCardSelected(ObservableValue selectedBody) { super(FXML); // Load body card when selected card changes. selectedBody.addListener((observable, oldValue, newValue) -> { if (newValue == null) { + setUnselectedDetails(); return; } - name.setText(newValue.getName().fullName); - bodyId.setText(newValue.getIdNum().toString()); - dateOfAdmission.setText(newValue.getDateOfAdmission().toString()); + setSelectedBodyDetails(newValue); }); } + private void setUnselectedDetails() { + selectedBodyName.setText("Name"); + selectedBodyId.setText("Body ID"); + selectedBodySex.setText("Sex"); + selectedBodyDateOfAdmission.setText("Date of Admission:"); + selectedBodyDateOfDeath.setText("Date of Death:"); + selectedBodyDateOfBirth.setText("Date of Birth"); + selectedBodyNric.setText("NRIC"); + selectedBodyReligion.setText("Religion"); + selectedBodyNokName.setText("NOK Name"); + selectedBodyNokRelationship.setText("NOK Relationship"); + selectedBodyNokPhone.setText("NOK Phone"); + selectedBodyCauseOfDeath.setText("COD"); + organs.getChildren().clear(); + } + + private void setSelectedBodyDetails(Body newValue) { + selectedBodyName.setText(newValue.getName().fullName); + selectedBodyId.setText(newValue.getIdNum().toString()); + selectedBodySex.setText(newValue.getSex().toString()); + selectedBodyDateOfAdmission.setText(newValue.getDateOfAdmission().toString()); + selectedBodyDateOfDeath.setText(toStringNullable(newValue.getDateOfDeath().orElse(null))); + selectedBodyDateOfBirth.setText(toStringNullable(newValue.getDateOfBirth().orElse(null))); + selectedBodyNric.setText(toStringNullable(newValue.getNric().orElse(null))); + selectedBodyReligion.setText(toStringNullable(newValue.getReligion().orElse(null))); + selectedBodyNokName.setText(toStringNullable(newValue.getNextOfKin().orElse(null))); + selectedBodyNokRelationship.setText(toStringNullable(newValue.getRelationship().orElse(null))); + selectedBodyNokPhone.setText(toStringNullable(newValue.getKinPhoneNumber().orElse(null))); + selectedBodyCauseOfDeath.setText(toStringNullable(newValue.getCauseOfDeath().orElse(null))); + + organs.getChildren().clear(); + newValue.getOrgansForDonation().stream() + .sorted(Comparator.comparing(String::toString)) + .forEach(organ -> organs.getChildren().add(new Label(organ))); + } + + /** + * Returns {@code NO_INPUT_DISPLAY} ("-") when the field is not available. + */ + private String toStringNullable(Object o) { + if (o == null) { + return NO_INPUT_DISPLAY; + } else { + return o.toString(); + } + } + @Override public boolean equals(Object other) { // short circuit if same object @@ -62,7 +131,7 @@ public boolean equals(Object other) { // state check BodyCardSelected card = (BodyCardSelected) other; - return id.getText().equals(card.id.getText()) + return selectedBodyId.getText().equals(card.selectedBodyId.getText()) && body.equals(card.body); } } diff --git a/src/main/java/seedu/address/ui/BodyTableView.java b/src/main/java/seedu/address/ui/BodyTableView.java index d4988c93fc0..cade679d0af 100644 --- a/src/main/java/seedu/address/ui/BodyTableView.java +++ b/src/main/java/seedu/address/ui/BodyTableView.java @@ -12,12 +12,16 @@ import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import javafx.fxml.FXML; +import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; -import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.text.Text; +import javafx.util.Callback; import seedu.address.commons.core.LogsCenter; import seedu.address.model.entity.IdentificationNumber; import seedu.address.model.entity.body.Body; @@ -29,6 +33,12 @@ public class BodyTableView extends UiPart { private static final String FXML = "BodyTableView.fxml"; + private static final double COLUMN_WIDTH_FRIDGE_ID = 0.1; + private static final double COLUMN_WIDTH_NAME = 0.2; + private static final double COLUMN_WIDTH_ID = 0.15; + private static final double COLUMN_WIDTH_DATE_OF_ADMISSION = 0.275; + private static final double COLUMN_WIDTH_BODY_STATUS = 0.26; + private final Logger logger = LogsCenter.getLogger(BodyTableView.class); @FXML @@ -37,11 +47,14 @@ public class BodyTableView extends UiPart { public BodyTableView (ObservableList bodyList, ObservableValue selectedBody, Consumer onSelectedBodyChange) { super(FXML); - setColumns(); + setupColumns(); bodyTableView.setItems(bodyList); + setCellSelectionHandler(selectedBody, onSelectedBodyChange); + } - //@@ shaoyi1997-reused - //Reused from SE-EDU Address Book Level 4 + //@@ shaoyi1997-reused + //Reused from SE-EDU Address Book Level 4 + private void setCellSelectionHandler(ObservableValue selectedBody, Consumer onSelectedBodyChange) { bodyTableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { logger.fine("Selection in body table view changed to : '" + newValue + "'"); onSelectedBodyChange.accept(newValue); @@ -63,30 +76,101 @@ public BodyTableView (ObservableList bodyList, ObservableValue selec bodyTableView.getSelectionModel().clearAndSelect(index); } }); - //@@author shaoyi1997 + } + //@@author shaoyi1997 + + private void setupColumns() { + TableColumn fridgeId = setupFridgeIdColumn(); + TableColumn name = setupNameColumn(); + TableColumn id = setupBodyIdColumn(); + TableColumn dateOfAdmission = setupDateOfAdmissionColumn(); + TableColumn bodyStatus = setupBodyStatusColumn(); + bodyTableView.getColumns().addAll(fridgeId, name, id, dateOfAdmission, bodyStatus); + } + + private TableColumn setupFridgeIdColumn() { + TableColumn fridgeId = new TableColumn<>("Fridge ID"); + fridgeId.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getFridgeId().orElse(null))); + fridgeId.setCellFactory(tableColumn -> new FridgeIdTableCell()); + fridgeId.prefWidthProperty().bind(bodyTableView.widthProperty().multiply(COLUMN_WIDTH_FRIDGE_ID)); + return fridgeId; } - private void setColumns() { - TableColumn name = new TableColumn<>("Name"); - name.setCellValueFactory(new PropertyValueFactory("Name")); - name.setSortType(TableColumn.SortType.ASCENDING); + private TableColumn setupNameColumn() { + return setupStringColumn("Name", COLUMN_WIDTH_NAME, + param -> new ReadOnlyObjectWrapper<>(param.getValue().getName().toString())); + } - TableColumn id = new TableColumn<>("Body ID"); - id.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getIdNum())); + private TableColumn setupBodyIdColumn() { + return setupStringColumn("Body ID", COLUMN_WIDTH_ID, + param -> new ReadOnlyObjectWrapper<>(param.getValue().getIdNum().toString())); + } - TableColumn dateOfAdmission = new TableColumn<>("Date Of Admission"); - dateOfAdmission.setCellValueFactory(new PropertyValueFactory("dateOfAdmission")); + private TableColumn setupDateOfAdmissionColumn() { + return setupStringColumn("Date of Admission", COLUMN_WIDTH_DATE_OF_ADMISSION, + param -> new ReadOnlyObjectWrapper<>(param.getValue().getDateOfAdmission().toString())); + } + private TableColumn setupBodyStatusColumn() { TableColumn bodyStatus = new TableColumn<>("Body Status"); bodyStatus.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getBodyStatus().get())); bodyStatus.setCellFactory(tableColumn -> new BodyStatusTableCell()); - bodyStatus.setStyle("-justify-self: center"); + bodyStatus.prefWidthProperty().bind(bodyTableView.widthProperty().multiply(COLUMN_WIDTH_BODY_STATUS)); + return bodyStatus; + } + + private TableColumn setupStringColumn(String nameOfColumn, double columnWidth, + Callback, ObservableValue> value) { + TableColumn col = new TableColumn<>(nameOfColumn); + col.prefWidthProperty().bind(bodyTableView.widthProperty() + .multiply(columnWidth)); + col.setCellValueFactory(value); + col.setCellFactory(tablecell -> new TableCellForStrings()); + return col; + } + + /** + * Custom {@code TableCell} that displays and vertically centralizes strings in the cell. + */ + class TableCellForStrings extends TableCell { + @Override + protected void updateItem(String str, boolean empty) { + super.updateItem(str, empty); - bodyTableView.getColumns().addAll(name, id, dateOfAdmission, bodyStatus); + if (empty | str == null) { + setGraphic(null); + setText(null); + } else { + StackPane pane = new StackPane(); + Text text = new Text(str); + text.setFill(Color.WHITE); + text.wrappingWidthProperty().bind(widthProperty()); + text.textProperty().bind(itemProperty()); + pane.getChildren().add(text); + setGraphic(pane); + } + } + } + + /** + * Custom {@code TableCell} that displays the {@code fridgeId} of a {@code Body}. + */ + class FridgeIdTableCell extends TableCell { + @Override + protected void updateItem(IdentificationNumber id, boolean empty) { + super.updateItem(id, empty); + + if (empty) { + setGraphic(null); + setText(null); + } else { + setGraphic(new FridgeIdLabel(id).getRoot()); + } + } } /** - * Custom {@code TableCell} that displays the graphics of a {@code Body}. + * Custom {@code TableCell} that displays the {@code bodyStatus} of a {@code Body}. */ class BodyStatusTableCell extends TableCell { @Override @@ -109,7 +193,10 @@ protected void updateItem(BodyStatus bodyStatus, boolean empty) { } else { label.getStyleClass().add("bodyStatusLabelPending"); } - setGraphic(label); + StackPane pane = new StackPane(); + pane.getChildren().add(label); + pane.setAlignment(Pos.CENTER_LEFT); + setGraphic(pane); } } } diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/address/ui/CommandBox.java index 7d76e691f52..e7e2620b0cb 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/address/ui/CommandBox.java @@ -73,5 +73,4 @@ public interface CommandExecutor { */ CommandResult execute(String commandText) throws CommandException, ParseException; } - } diff --git a/src/main/java/seedu/address/ui/FridgeIdLabel.java b/src/main/java/seedu/address/ui/FridgeIdLabel.java new file mode 100644 index 00000000000..6180cfb4558 --- /dev/null +++ b/src/main/java/seedu/address/ui/FridgeIdLabel.java @@ -0,0 +1,54 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.Region; +import javafx.scene.shape.Circle; +import seedu.address.model.entity.IdentificationNumber; + +/** + * An UI component that displays information of a {@code fridgeId}. + */ +public class FridgeIdLabel extends UiPart { + + private static final String FXML = "FridgeIdLabel.fxml"; + + public final IdentificationNumber fridgeId; + + @FXML + private Circle circle; + @FXML + private Label fridgeIdPlaceholder; + + public FridgeIdLabel(IdentificationNumber id) { + super(FXML); + this.fridgeId = id; + if (id == null) { + fridgeIdPlaceholder.setText("NA"); + circle.getStyleClass().add("fridgeIdCircleEmpty"); + } else { + fridgeIdPlaceholder.setText(id.toString()); + circle.getStyleClass().add("fridgeIdCircleFilled"); + } + fridgeIdPlaceholder.setStyle("-fx-font-weight: bold"); + circle.setStrokeWidth(0.0); + circle.setRadius(15.0); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof PersonCard)) { + return false; + } + + // state check + FridgeIdLabel label = (FridgeIdLabel) other; + return fridgeIdPlaceholder.getText().equals(label.fridgeIdPlaceholder.getText()); + } +} diff --git a/src/main/java/seedu/address/ui/LineChartPanel.java b/src/main/java/seedu/address/ui/LineChartPanel.java index 2d8903f48d2..db971a80f57 100644 --- a/src/main/java/seedu/address/ui/LineChartPanel.java +++ b/src/main/java/seedu/address/ui/LineChartPanel.java @@ -9,8 +9,8 @@ import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.fxml.FXML; +import javafx.scene.chart.AreaChart; import javafx.scene.chart.CategoryAxis; -import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.control.TextArea; @@ -30,7 +30,7 @@ public class LineChartPanel extends UiPart { final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, MMM d, yyyy"); final CategoryAxis xAxis = new CategoryAxis(); // we are gonna plot against time final NumberAxis yAxis = new NumberAxis(); - final LineChart lineChart = new LineChart<>(xAxis, yAxis); + final AreaChart lineChart = new AreaChart<>(xAxis, yAxis); private XYChart.Series series = new XYChart.Series<>(); private Map freqByDate = new TreeMap<>(); private ObservableList bodyList; @@ -43,7 +43,7 @@ public LineChartPanel(ObservableList bodyList) { this.bodyList = bodyList; } - public LineChart getLineChart() throws ParseException { + public AreaChart getLineChart() throws ParseException { initialiseTreeMap(); initialiseLineChart(); updateSeries(); diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 9574ca812b1..291759d9700 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -4,6 +4,8 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.TextInputControl; import javafx.scene.input.KeyCombination; @@ -26,12 +28,16 @@ public class MainWindow extends UiPart { private static final String FXML = "MainWindow.fxml"; + private static final int MINIMUM_HEIGHT = 650; + private static final int MINIMUM_WIDTH = 1250; private final Logger logger = LogsCenter.getLogger(getClass()); private Stage primaryStage; private Logic logic; private ReadOnlyAddressBook readOnlyAddressBook; + private double xOffset = 0; + private double yOffset = 0; // Independent Ui parts residing in this Ui container private PersonListPanel personListPanel; @@ -39,6 +45,20 @@ public class MainWindow extends UiPart { private ResultDisplay resultDisplay; private HelpWindow helpWindow; private BodyMasterDetailPane bodyMasterDetailPane; + private NotificationButton notificationButton; + private CommandBox commandBox; + + @FXML + private MenuBar menuBar; + + @FXML + private Button minimiseButton; + + @FXML + private Button maximiseButton; + + @FXML + private Button exitButton; @FXML private StackPane commandBoxPlaceholder; @@ -61,6 +81,9 @@ public class MainWindow extends UiPart { @FXML private StackPane bodyMasterListPlaceholder; + @FXML + private StackPane notificationButtonPlaceholder; + public MainWindow(Stage primaryStage, Logic logic) { super(FXML, primaryStage); @@ -71,6 +94,7 @@ public MainWindow(Stage primaryStage, Logic logic) { // Configure the UI setWindowDefaultSize(logic.getGuiSettings()); setWindowCloseHandler(); + setMenuBarHandlers(); setAccelerators(); @@ -131,13 +155,35 @@ void fillInnerParts() throws java.text.ParseException { StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath(), logic.getAddressBook()); statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); - CommandBox commandBox = new CommandBox(this::executeCommand); + commandBox = new CommandBox(this::executeCommand); commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); bodyMasterDetailPane = new BodyMasterDetailPane(new BodyTableView(logic.getFilteredBodyList(), logic.selectedBodyProperty(), logic::setSelectedBody), - new BodyCardSelected(logic.selectedBodyProperty())); + new BodyCardSelected(logic.selectedBodyProperty())); bodyMasterListPlaceholder.getChildren().add(bodyMasterDetailPane.getRoot()); + + notificationButton = NotificationButton.getInstanceOfNotifButton(); + notificationButtonPlaceholder.getChildren().add(notificationButton.getRoot()); + + + } + + private void setMenuBarHandlers() { + menuBar.setOnMousePressed((event) -> { + xOffset = event.getSceneX(); + yOffset = event.getSceneY(); + }); + + menuBar.setOnMouseDragged((event) -> { + primaryStage.setX(event.getScreenX() - xOffset); + primaryStage.setY(event.getScreenY() - yOffset); + }); + + setMaximiseButtonHandler(); + setMinimiseButtonHandler(); + ResizableWindow.enableResizableWindow(primaryStage, MINIMUM_WIDTH, MINIMUM_HEIGHT, + Double.MAX_VALUE, Double.MAX_VALUE); } /** @@ -159,6 +205,31 @@ private void setWindowCloseHandler() { primaryStage.getScene().getWindow().addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, e -> handleExit()); } + /** + * Sets the minimising handler for minimise button. + */ + private void setMinimiseButtonHandler() { + minimiseButton.setOnMouseClicked(click -> + primaryStage.setIconified(true) + ); + } + + /** + * Sets the maximising and restoring handler for maximise button + * Change button images respectively via css. + */ + private void setMaximiseButtonHandler() { + maximiseButton.setOnMouseClicked(click -> { + primaryStage.setMaximized(true); + maximiseButton.setId("restoreButton"); + }); + + maximiseButton.setOnMousePressed(click -> { + primaryStage.setMaximized(false); + maximiseButton.setId("maximiseButton"); + }); + } + /** * Opens the help window or focuses on it if it's already opened. */ diff --git a/src/main/java/seedu/address/ui/NotificationButton.java b/src/main/java/seedu/address/ui/NotificationButton.java new file mode 100644 index 00000000000..b3c8a142ec1 --- /dev/null +++ b/src/main/java/seedu/address/ui/NotificationButton.java @@ -0,0 +1,87 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.animation.Interpolator; +import javafx.animation.TranslateTransition; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import javafx.util.Duration; +import seedu.address.commons.core.LogsCenter; + +/** + * Singleton notification button to open up alerts view. + */ +public class NotificationButton extends UiPart { + + private static NotificationButton notificationButton = new NotificationButton(); + private static final Logger logger = LogsCenter.getLogger(NotificationButton.class); + private static final String FXML = "NotificationButton.fxml"; + + @FXML + private ImageView buttonIcon; + + @FXML + private Button notifButton; + + @FXML + private StackPane buttonPane; + + private Label iconNumber; + + private NotificationButton() { + super(FXML); + notifButton.setGraphic(buttonIcon); + notifButton.setStyle("-fx-border-width: 0"); + initIconNumber(); + } + + /** + * Returns the single instance of the notification button. + */ + public static NotificationButton getInstanceOfNotifButton() { + return notificationButton; + } + + /** + * Initializes the icon number. + */ + private void initIconNumber() { + iconNumber = new Label(); + iconNumber.setText("0"); + iconNumber.getStyleClass().add("notificationButtonLabel"); + addJumpingAnimation(); + bindIconNumberToStackPane(); + } + + /** + * Sets up the jumping animation for the icon number. + */ + private void addJumpingAnimation() { + TranslateTransition translateTransition = new TranslateTransition(Duration.millis(200), iconNumber); + double start = 0.0; + double end = start - 4.0; + translateTransition.setFromY(start); + translateTransition.setToY(end); + translateTransition.setCycleCount(-1); + translateTransition.setAutoReverse(true); + translateTransition.setInterpolator(Interpolator.EASE_BOTH); + translateTransition.play(); + } + + private void bindIconNumberToStackPane() { + buttonPane.setAlignment(iconNumber, Pos.TOP_RIGHT); + buttonPane.setMargin(iconNumber, new Insets(6, 6, 0, 0)); + buttonPane.getChildren().addAll(iconNumber); + } + + public void setIconNumber(int num) { + iconNumber.setText(num + ""); + } +} diff --git a/src/main/java/seedu/address/ui/ResizableWindow.java b/src/main/java/seedu/address/ui/ResizableWindow.java new file mode 100644 index 00000000000..b31755fc878 --- /dev/null +++ b/src/main/java/seedu/address/ui/ResizableWindow.java @@ -0,0 +1,191 @@ +package seedu.address.ui; + +import javafx.collections.ObservableList; +import javafx.event.EventHandler; +import javafx.event.EventType; +import javafx.scene.Cursor; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.input.MouseEvent; +import javafx.stage.Stage; + +//@@author shaoyi1997-reused +/** + * Enables the resizing of MainWindow by adding mouse event listeners. + * + * By: Evgenii Kanivets and Alexander.Berg + * Adapted From: https://stackoverflow.com/questions/19455059/allow-user-to-resize-an-undecorated-stage + */ +public class ResizableWindow { + + /** + * Registers an event handler for the Scene in the specified Stage (top-level UI container) + * @param stage + */ + public static void enableResizableWindow(Stage stage, + double minWidth, + double minHeight, + double maxWidth, + double maxHeight) { + ResizeHandler resizeHandler = new ResizeHandler(stage); + stage.getScene().addEventHandler(MouseEvent.MOUSE_MOVED, resizeHandler); + stage.getScene().addEventHandler(MouseEvent.MOUSE_PRESSED, resizeHandler); + stage.getScene().addEventHandler(MouseEvent.MOUSE_DRAGGED, resizeHandler); + stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED, resizeHandler); + stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, resizeHandler); + + resizeHandler.setMinWidth(minWidth); + resizeHandler.setMinHeight(minHeight); + resizeHandler.setMaxWidth(maxWidth); + resizeHandler.setMaxHeight(maxHeight); + + ObservableList children = stage.getScene().getRoot().getChildrenUnmodifiable(); + for (Node child : children) { + addHandlerToNodes(child, resizeHandler); + } + } + + /** + * Registers an event handler for each UI node in the hierarchy + * @param node + * @param handler + */ + private static void addHandlerToNodes(Node node, EventHandler handler) { + node.addEventHandler(MouseEvent.MOUSE_MOVED, handler); + node.addEventHandler(MouseEvent.MOUSE_PRESSED, handler); + node.addEventHandler(MouseEvent.MOUSE_DRAGGED, handler); + node.addEventHandler(MouseEvent.MOUSE_EXITED, handler); + node.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, handler); + if (node instanceof Parent) { + Parent parent = (Parent) node; + ObservableList children = parent.getChildrenUnmodifiable(); + for (Node child : children) { + addHandlerToNodes(child, handler); + } + } + } + + /** + * Configures mouse event handler + */ + static class ResizeHandler implements EventHandler { + private Stage stage; + private Cursor cursorEvent = Cursor.DEFAULT; + private int border = 4; + private double startX = 0; + private double startY = 0; + + // Max and min sizes for controlled stage + private double minWidth; + private double maxWidth; + private double minHeight; + private double maxHeight; + + public ResizeHandler(Stage stage) { + this.stage = stage; + } + + public void setMinWidth(double minWidth) { + this.minWidth = minWidth; + } + + public void setMinHeight(double minHeight) { + this.minHeight = minHeight; + } + + public void setMaxWidth(double maxWidth) { + this.maxWidth = maxWidth; + } + + public void setMaxHeight(double maxHeight) { + this.maxHeight = maxHeight; + } + + private void setStageWidth(double width) { + width = Math.min(width, maxWidth); + width = Math.max(width, minWidth); + stage.setWidth(width); + } + + private void setStageHeight(double height) { + height = Math.min(height, maxHeight); + height = Math.max(height, minHeight); + stage.setHeight(height); + } + + @Override + public void handle(MouseEvent mouseEvent) { + EventType mouseEventType = mouseEvent.getEventType(); + Scene scene = stage.getScene(); + + double mouseEventX = mouseEvent.getSceneX(); + double mouseEventY = mouseEvent.getSceneY(); + double sceneWidth = scene.getWidth(); + double sceneHeight = scene.getHeight(); + + if (MouseEvent.MOUSE_MOVED.equals(mouseEventType)) { + if (mouseEventX < border && mouseEventY < border) { + cursorEvent = Cursor.NW_RESIZE; + } else if (mouseEventX < border && mouseEventY > sceneHeight - border) { + cursorEvent = Cursor.SW_RESIZE; + } else if (mouseEventX > sceneWidth - border && mouseEventY < border) { + cursorEvent = Cursor.NE_RESIZE; + } else if (mouseEventX > sceneWidth - border && mouseEventY > sceneHeight - border) { + cursorEvent = Cursor.SE_RESIZE; + } else if (mouseEventX < border) { + cursorEvent = Cursor.W_RESIZE; + } else if (mouseEventX > sceneWidth - border) { + cursorEvent = Cursor.E_RESIZE; + } else if (mouseEventY < border) { + cursorEvent = Cursor.N_RESIZE; + } else if (mouseEventY > sceneHeight - border) { + cursorEvent = Cursor.S_RESIZE; + } else { + cursorEvent = Cursor.DEFAULT; + } + scene.setCursor(cursorEvent); + } else if (MouseEvent.MOUSE_EXITED.equals(mouseEventType) + || MouseEvent.MOUSE_EXITED_TARGET.equals(mouseEventType)) { + scene.setCursor(Cursor.DEFAULT); + } else if (MouseEvent.MOUSE_PRESSED.equals(mouseEventType)) { + startX = stage.getWidth() - mouseEventX; + startY = stage.getHeight() - mouseEventY; + } else if (MouseEvent.MOUSE_DRAGGED.equals(mouseEventType)) { + + if (!Cursor.DEFAULT.equals(cursorEvent)) { + if (!Cursor.W_RESIZE.equals(cursorEvent) && !Cursor.E_RESIZE.equals(cursorEvent)) { + double minHeight = stage.getMinHeight() > (border * 2) ? stage.getMinHeight() : (border * 2); + if (Cursor.NW_RESIZE.equals(cursorEvent) || Cursor.N_RESIZE.equals(cursorEvent) + || Cursor.NE_RESIZE.equals(cursorEvent)) { + if (stage.getHeight() > minHeight || mouseEventY < 0) { + setStageHeight(stage.getY() - mouseEvent.getScreenY() + stage.getHeight()); + stage.setY(mouseEvent.getScreenY()); + } + } else { + if (stage.getHeight() > minHeight || mouseEventY + startY - stage.getHeight() > 0) { + setStageHeight(mouseEventY + startY); + } + } + } + + if (!Cursor.N_RESIZE.equals(cursorEvent) && !Cursor.S_RESIZE.equals(cursorEvent)) { + double minWidth = stage.getMinWidth() > (border * 2) ? stage.getMinWidth() : (border * 2); + if (Cursor.NW_RESIZE.equals(cursorEvent) || Cursor.W_RESIZE.equals(cursorEvent) + || Cursor.SW_RESIZE.equals(cursorEvent)) { + if (stage.getWidth() > minWidth || mouseEventX < 0) { + setStageWidth(stage.getX() - mouseEvent.getScreenX() + stage.getWidth()); + stage.setX(mouseEvent.getScreenX()); + } + } else { + if (stage.getWidth() > minWidth || mouseEventX + startX - stage.getWidth() > 0) { + setStageWidth(mouseEventX + startX); + } + } + } + } + } + } + } +} +//@@author diff --git a/src/main/resources/images/bell_icon.png b/src/main/resources/images/bell_icon.png new file mode 100644 index 00000000000..4d77a67ae4f Binary files /dev/null and b/src/main/resources/images/bell_icon.png differ diff --git a/src/main/resources/images/close.png b/src/main/resources/images/close.png new file mode 100644 index 00000000000..fe3808b1a64 Binary files /dev/null and b/src/main/resources/images/close.png differ diff --git a/src/main/resources/images/maximise.png b/src/main/resources/images/maximise.png new file mode 100644 index 00000000000..74bd58ae708 Binary files /dev/null and b/src/main/resources/images/maximise.png differ diff --git a/src/main/resources/images/minimise.png b/src/main/resources/images/minimise.png new file mode 100644 index 00000000000..36748b138e3 Binary files /dev/null and b/src/main/resources/images/minimise.png differ diff --git a/src/main/resources/images/restore.png b/src/main/resources/images/restore.png new file mode 100644 index 00000000000..4154a924754 Binary files /dev/null and b/src/main/resources/images/restore.png differ diff --git a/src/main/resources/view/BodyListCard.fxml b/src/main/resources/view/BodyListCard.fxml index dae243ad225..0d5d74b3a61 100644 --- a/src/main/resources/view/BodyListCard.fxml +++ b/src/main/resources/view/BodyListCard.fxml @@ -9,7 +9,7 @@ - + diff --git a/src/main/resources/view/BodyMasterDetailPane.fxml b/src/main/resources/view/BodyMasterDetailPane.fxml index 5a78aa59920..ac854acadb2 100644 --- a/src/main/resources/view/BodyMasterDetailPane.fxml +++ b/src/main/resources/view/BodyMasterDetailPane.fxml @@ -3,4 +3,4 @@ - + diff --git a/src/main/resources/view/BodyTableView.fxml b/src/main/resources/view/BodyTableView.fxml index c70fd29cea3..e3875f3078a 100644 --- a/src/main/resources/view/BodyTableView.fxml +++ b/src/main/resources/view/BodyTableView.fxml @@ -2,8 +2,5 @@ - - - - - + + diff --git a/src/main/resources/view/CommandBox.fxml b/src/main/resources/view/CommandBox.fxml index 09f6d6fe9e4..6886189c3da 100644 --- a/src/main/resources/view/CommandBox.fxml +++ b/src/main/resources/view/CommandBox.fxml @@ -1,9 +1,16 @@ + + - - + + + + + + + + - diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 0f2667b134e..2fb254eda8b 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -1,32 +1,36 @@ +.root { + -fx-background-color: derive(#121212, 25%); +} + .background { - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: derive(#121212, 25%); background-color: #383838; /* Used in the default.html file */ } .label { - -fx-font-size: 11pt; - -fx-font-family: "Segoe UI Semibold"; - -fx-text-fill: #555555; - -fx-opacity: 0.9; + -fx-font-size: 8pt; + -fx-font-family: "Century Gothic"; + -fx-font-weight: 500; + -fx-text-fill: white; } .label-bright { -fx-font-size: 11pt; - -fx-font-family: "Segoe UI Semibold"; + -fx-font-family: "Century Gothic"; -fx-text-fill: white; -fx-opacity: 1; } .label-header { -fx-font-size: 32pt; - -fx-font-family: "Segoe UI Light"; + -fx-font-family: "Century Gothic"; -fx-text-fill: white; -fx-opacity: 1; } .text-field { -fx-font-size: 12pt; - -fx-font-family: "Segoe UI Semibold"; + -fx-font-family: "Century Gothic"; } .tab-pane { @@ -39,37 +43,38 @@ -fx-max-height: 0; } +.table-row-cell { + -fx-cell-size: 50px; +} + .table-view { - -fx-base: #1d1d1d; - -fx-control-inner-background: #1d1d1d; - -fx-background-color: #1d1d1d; + -fx-base: #121212; + -fx-control-inner-background: #121212; + -fx-background-color: #121212; -fx-table-cell-border-color: transparent; -fx-table-header-border-color: transparent; -fx-padding: 5; + -fx-background-insets: 10 10 10 10; } -.table-view .column-header-background { - -fx-background-color: #4d4d4d; +.table-view .scroll-bar { + -fx-background-color: #121212; } .table-view .column-header, .table-view .filler { - -fx-size: 20; - -fx-border-width: 0 0 1 0; - -fx-background-color: transparent; - -fx-border-color: - transparent - transparent - derive(-fx-base, 80%) - transparent; - -fx-border-insets: 0 10 1 0; + -fx-size: 16; + -fx-border-width: 0 0 0 0; + -fx-background-color: #121212; + -fx-border-insets: 0 0 0 0; } .table-view .column-header .label { - -fx-font-size: 12pt; - -fx-font-family: "Segoe UI Light"; - -fx-text-fill: white; + -fx-font-size: 10pt; + -fx-font-family: "Century Gothic"; + -fx-text-fill: grey; -fx-alignment: center-left; -fx-opacity: 1; + -fx-background-color: #121212; } .table-view:focused .table-row-cell:filled:focused:selected { @@ -77,34 +82,39 @@ } .split-pane:horizontal .split-pane-divider { - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: #121212; -fx-border-color: transparent transparent transparent #4d4d4d; } .split-pane { - -fx-border-radius: 1; + -fx-border-radius: 2; -fx-border-width: 1; - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: #121212; } .list-view { -fx-background-insets: 0; -fx-padding: 0; - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: #121212; + -fx-border-radius: 10; + -fx-background-radius: 5; + -fx-border-width: 2; + -fx-border-color: #121212; } .list-cell { -fx-label-padding: 0 0 0 0; -fx-graphic-text-gap : 0; -fx-padding: 0 0 0 0; + -fx-background-color: #121212; } .list-cell:filled:even { - -fx-background-color: #3c3e3f; + -fx-background-color: #121212; } .list-cell:filled:odd { - -fx-background-color: #515658; + -fx-background-color: derive(#121212, 2%); } .list-cell:filled:selected { @@ -112,7 +122,7 @@ } .list-cell:filled:selected #cardPane { - -fx-border-color: #3e7b91; + -fx-border-color: grey; -fx-border-width: 1; } @@ -121,35 +131,46 @@ } .cell_big_label { - -fx-font-family: "Segoe UI Semibold"; + -fx-font-family: "Century Gothic"; -fx-font-size: 16px; -fx-text-fill: #010504; } .cell_small_label { - -fx-font-family: "Segoe UI"; + -fx-font-family: "Century Gothic"; -fx-font-size: 13px; -fx-text-fill: #010504; } .stack-pane { - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: #121212; + -fx-border-radius: 10; + -fx-background-radius: 5; + -fx-border-width: 2; + -fx-border-color: #121212; +} + +.scroll-pane { + -fx-background-color: #121212; + -fx-border-radius: 0; + -fx-background-radius: 0; + -fx-border-color: #121212; } .pane-with-border { - -fx-background-color: derive(#1d1d1d, 20%); - -fx-border-color: derive(#1d1d1d, 10%); + -fx-background-color: #121212; + -fx-border-color: derive(#121212, 25%); -fx-border-top-width: 1px; } .status-bar { - -fx-background-color: derive(#1d1d1d, 30%); + -fx-background-color: derive(#121212, 25%); } .result-display { - -fx-background-color: transparent; - -fx-font-family: "Segoe UI Light"; - -fx-font-size: 13pt; + -fx-background-color: #121212; + -fx-font-family: "Century Gothic"; + -fx-font-size: 10pt; -fx-text-fill: white; } @@ -157,16 +178,29 @@ -fx-text-fill: black !important; } +.result-display .scroll-bar:horizontal .thumb { + -fx-pref-height: 1; + -fx-padding: -2; + -fx-arrows-visible: 2; + -fx-legend-visible: 2; + -fx-page-information-visible:2 +} + +#resultDisplay .content { + -fx-background-color: #121212; + -fx-background-radius: 0; +} + .status-bar .label { - -fx-font-family: "Segoe UI Light"; + -fx-font-family: "Century Gothic"; -fx-text-fill: white; -fx-padding: 4px; -fx-pref-height: 30px; } .status-bar-with-border { - -fx-background-color: derive(#1d1d1d, 30%); - -fx-border-color: derive(#1d1d1d, 25%); + -fx-background-color: derive(#121212, 25%); + -fx-border-color: derive(#121212, 25%); -fx-border-width: 1px; } @@ -175,17 +209,17 @@ } .grid-pane { - -fx-background-color: derive(#1d1d1d, 30%); - -fx-border-color: derive(#1d1d1d, 30%); + -fx-background-color: derive(#121212, 25%); + -fx-border-color: derive(#121212, 25%); -fx-border-width: 1px; } -.grid-pane .stack-pane { - -fx-background-color: derive(#1d1d1d, 30%); +.grid-pane { + -fx-background-color: derive(#121212, 25%); } .context-menu { - -fx-background-color: derive(#1d1d1d, 50%); + -fx-background-color: derive(#121212, 25%); } .context-menu .label { @@ -193,12 +227,13 @@ } .menu-bar { - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: #121212; + -fx-text-alignment: center; } .menu-bar .label { - -fx-font-size: 14pt; - -fx-font-family: "Segoe UI Light"; + -fx-font-size: 10pt; + -fx-font-family: "Century Gothic"; -fx-text-fill: white; -fx-opacity: 0.9; } @@ -213,15 +248,12 @@ * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/ */ .button { - -fx-padding: 5 22 5 22; - -fx-border-color: #e2e2e2; - -fx-border-width: 2; + -fx-padding: 3 8 3 8; -fx-background-radius: 0; - -fx-background-color: #1d1d1d; - -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif; + -fx-background-color: #121212; + -fx-font-family: "Century Gothic", Helvetica, Arial, sans-serif; -fx-font-size: 11pt; -fx-text-fill: #d8d8d8; - -fx-background-insets: 0 0 0 0, 0, 1, 2; } .button:hover { @@ -230,7 +262,9 @@ .button:pressed, .button:default:hover:pressed { -fx-background-color: white; - -fx-text-fill: #1d1d1d; + -fx-text-fill: derive(#121212, 25%); + -fx-padding: 3 8 3 8; + -fx-background-radius: 0; } .button:focused { @@ -243,7 +277,7 @@ .button:disabled, .button:default:disabled { -fx-opacity: 0.4; - -fx-background-color: #1d1d1d; + -fx-background-color: derive(#121212, 25%); -fx-text-fill: white; } @@ -257,11 +291,11 @@ } .dialog-pane { - -fx-background-color: #1d1d1d; + -fx-background-color: derive(#121212, 25%); } .dialog-pane > *.button-bar > *.container { - -fx-background-color: #1d1d1d; + -fx-background-color: derive(#121212, 25%); } .dialog-pane > *.label.content { @@ -271,7 +305,7 @@ } .dialog-pane:header *.header-panel { - -fx-background-color: derive(#1d1d1d, 25%); + -fx-background-color: #121212; } .dialog-pane:header *.header-panel *.label { @@ -282,29 +316,25 @@ } .scroll-bar { - -fx-background-color: derive(#1d1d1d, 20%); + -fx-background-color: derive(#121212, 20%); + -fx-background-radius: 10; } .scroll-bar .thumb { - -fx-background-color: derive(#1d1d1d, 50%); - -fx-background-insets: 3; + -fx-background-color: white; + -fx-background-radius: 5em; + -fx-opacity: 0.8; } .scroll-bar .increment-button, .scroll-bar .decrement-button { -fx-background-color: transparent; - -fx-padding: 0 0 0 0; + -fx-background-radius: 0em; + -fx-padding: 0 10 0 0; } .scroll-bar .increment-arrow, .scroll-bar .decrement-arrow { -fx-shape: " "; -} - -.scroll-bar:vertical .increment-arrow, .scroll-bar:vertical .decrement-arrow { - -fx-padding: 1 8 1 8; -} - -.scroll-bar:horizontal .increment-arrow, .scroll-bar:horizontal .decrement-arrow { - -fx-padding: 8 1 8 1; + -fx-padding: 0; } #cardPane { @@ -318,23 +348,26 @@ } #commandTextField { - -fx-background-color: transparent #383838 transparent #383838; + -fx-background-color: derive(#121212, 20%); + -fx-opacity: 0.8; -fx-background-insets: 0; - -fx-border-color: #383838 #383838 #ffffff #383838; + -fx-background-radius: 15; + -fx-border-color: derive(#121212, 10%); -fx-border-insets: 0; -fx-border-width: 1; - -fx-font-family: "Segoe UI Light"; - -fx-font-size: 13pt; + -fx-border-radius: 20; + -fx-font-family: "Century Gothic"; + -fx-font-size: 8pt; -fx-text-fill: white; } -#filterField, #personListPanel, #personWebpage { - -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0); +#commandBoxPlaceholder { + -fx-background-color: #121212; + -fx-border-color: #121212; } -#resultDisplay .content { - -fx-background-color: transparent, #383838, transparent, #383838; - -fx-background-radius: 0; +#filterField, #personListPanel { + -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0); } #tags { @@ -354,58 +387,76 @@ .bodyStatusLabelArrived { -fx-text-fill: black; -fx-background-color: #FF555E; - -fx-padding: 1 3 1 3; + -fx-padding: 2 5 2 5; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; -fx-alignment: center; + -fx-font-weight: bold; } .bodyStatusLabelClaimed { -fx-text-fill: black; -fx-background-color: #8BF18B; - -fx-padding: 1 3 1 3; + -fx-padding: 2 5 2 5; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; -fx-alignment: center; + -fx-font-weight: bold; } .bodyStatusLabelPending { -fx-text-fill: black; -fx-background-color: #FFE981; - -fx-padding: 1 3 1 3; + -fx-padding: 2 5 2 5; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; -fx-alignment: center; + -fx-font-weight: bold; } .bodyStatusLabelPendingPoliceReport { -fx-text-fill: black; -fx-background-color: #FF8650; - -fx-padding: 1 3 1 3; + -fx-padding: 2 5 2 5; -fx-border-radius: 2; -fx-background-radius: 2; -fx-font-size: 11; -fx-alignment: center; + -fx-font-weight: bold; +} + +.fridgeIdCircleEmpty { + -fx-fill: #FF7597; } +.fridgeIdCircleFilled { + -fx-fill: #4285F4; +} .chart { - -fx-padding: 10px; + -fx-padding: 0px; +} + +.chart-series-area-line { + -fx-stroke: #FF7597; } -.chart-content { + +.chart-series-area-fill { + -fx-fill: #FF7597; + -fx-opacity: 0.2; } .chart-title { -fx-text-fill: white; - -fx-font-family: "Segoe UI Semibold"; + -fx-font-family: "Century Gothic"; } .axis-label { -fx-text-fill: white; - -fx-font-family: "Segoe UI Semibold"; + -fx-font-family: "Century Gothic"; -fx-font-size: 1em; } @@ -423,7 +474,7 @@ } .chart-plot-background { - -fx-background-color: #383838; + -fx-background-color: #121212; } .chart-vertical-grid-lines { -fx-stroke: grey; @@ -435,3 +486,109 @@ -fx-stroke: #2B3941; -fx-stroke-width: 0; } + +#fridgeIdPlaceholder { + -fx-text-fill: white; + -fx-font-size: 10; +} + +.notificationButtonLabel { + -fx-text-fill: white; + -fx-font-weight: bold; + -fx-background-color: #FF0266; + -fx-padding: 1 3 1 3; + -fx-border-radius: 10; + -fx-background-radius: 10; + -fx-font-size: 8; + -fx-alignment: center; +} + +.box { + -fx-background-color: #121212; + -fx-border-width: 0; +} + +/* Styling for SelectedBodyCard */ + +#selectedBodyId { + -fx-text-fill: black; + -fx-background-color: linear-gradient(to right, #FF7597, #FF0266); + -fx-padding: 4 6 4 6; + -fx-border-width: 0; + -fx-background-radius: 5; + -fx-font-size: 12; + -fx-font-weight: bold; +} + +#selectedBodyName { + -fx-font-size: 15 +} + +#selectedBodySex { + -fx-font-size: 13 +} + +#selectedBodyNric { + -fx-font-size: 13 +} + +#selectedBodyReligion { + -fx-font-size: 13 +} + +#dateBox { + -fx-background-color: #FF7597; + -fx-background-radius: 10; +} + +#organs { + -fx-hgap: 7; + -fx-vgap: 3; +} + +#organs .label { + -fx-text-fill: white; + -fx-background-color: #3e7b91; + -fx-padding: 1 3 1 3; + -fx-border-radius: 2; + -fx-background-radius: 2; + -fx-font-size: 11; +} + +#NOK { + -fx-text-fill: #444444; + -fx-background-color: #FF7597; + -fx-padding: 22 20 22 40; + -fx-border-radius: 5; + -fx-background-radius: 5; + -fx-font-size: 14; + -fx-font-weight: 700 +} + +/* Window Buttons */ + +#exitButton { + -fx-background-image: url("../images/close.png"); + -fx-background-repeat: no-repeat; + -fx-background-position: center; + -fx-border-radius: 0 10 0 0; + -fx-background-radius: 0 10 0 0; +} + +#maximiseButton { + -fx-background-image: url("../images/maximise.png"); + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#restoreButton { + -fx-background-image: url("../images/restore.png"); + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#minimiseButton { + -fx-background-image: url("../images/minimise.png"); + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} diff --git a/src/main/resources/view/FridgeIdLabel.fxml b/src/main/resources/view/FridgeIdLabel.fxml new file mode 100644 index 00000000000..3e817a0ad88 --- /dev/null +++ b/src/main/resources/view/FridgeIdLabel.fxml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index 97c0d9e9264..069ea0a5ed0 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -3,71 +3,116 @@ + + + - + - + - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + +