diff --git a/CalendarFXResourceApp/src/main/java/com/calendarfx/resource/app/ResourceCalendarApp.java b/CalendarFXResourceApp/src/main/java/com/calendarfx/resource/app/ResourceCalendarApp.java index ffb85d1c..b249716a 100644 --- a/CalendarFXResourceApp/src/main/java/com/calendarfx/resource/app/ResourceCalendarApp.java +++ b/CalendarFXResourceApp/src/main/java/com/calendarfx/resource/app/ResourceCalendarApp.java @@ -25,7 +25,7 @@ import com.calendarfx.view.DayEntryView; import com.calendarfx.view.DayView; import com.calendarfx.view.EntryViewBase; -import com.calendarfx.view.ResourceCalendarView; +import com.calendarfx.view.resources.ResourceCalendarView; import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Insets; diff --git a/CalendarFXSampler/src/main/java/com/calendarfx/demo/CalendarFXSample.java b/CalendarFXSampler/src/main/java/com/calendarfx/demo/CalendarFXSample.java index 1960665f..e7bb9967 100644 --- a/CalendarFXSampler/src/main/java/com/calendarfx/demo/CalendarFXSample.java +++ b/CalendarFXSampler/src/main/java/com/calendarfx/demo/CalendarFXSample.java @@ -19,6 +19,7 @@ import com.calendarfx.util.CalendarFX; import com.calendarfx.view.CalendarFXControl; +import fr.brouillard.oss.cssfx.CSSFX; import fxsampler.SampleBase; import impl.com.calendarfx.view.CalendarPropertySheet; import javafx.geometry.Pos; @@ -37,6 +38,7 @@ public abstract class CalendarFXSample extends SampleBase { public Node getPanel(Stage stage) { control = createControl(); requireNonNull(control, "missing date control"); + CSSFX.start(); return wrap(control); } diff --git a/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/HelloResourcesCalendarView.java b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/HelloResourcesCalendarView.java index a9c5e353..cc5b237a 100644 --- a/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/HelloResourcesCalendarView.java +++ b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/HelloResourcesCalendarView.java @@ -26,7 +26,7 @@ import com.calendarfx.view.DayEntryView; import com.calendarfx.view.DayView; import com.calendarfx.view.DayViewBase.OverlapResolutionStrategy; -import com.calendarfx.view.ResourceCalendarView; +import com.calendarfx.view.resources.ResourceCalendarView; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; diff --git a/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloDetailedResourcesDayView.java b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloDetailedResourcesDayView.java new file mode 100644 index 00000000..c36ba456 --- /dev/null +++ b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloDetailedResourcesDayView.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 Dirk Lemmermann Software & Consulting (dlsc.com) + * Copyright (C) 2006 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.calendarfx.demo.views.resources; + +import com.calendarfx.demo.CalendarFXDateControlSample; +import com.calendarfx.model.Calendar.Style; +import com.calendarfx.view.DateControl; +import com.calendarfx.view.resources.DetailedResourcesDayView; +import com.calendarfx.view.resources.Resource; +import javafx.scene.Node; +import javafx.scene.control.ToggleButton; + +public class HelloDetailedResourcesDayView extends CalendarFXDateControlSample { + + private DetailedResourcesDayView detailedResouresDayView; + + @Override + public String getSampleName() { + return "Detailed Resources Day View"; + } + + @Override + public String getSampleDescription() { + return "The detailed day view aggregates a day view, an all day view, a calendar header (for swimlane layout), and a time scale."; + } + + @Override + protected Class getJavaDocClass() { + return DetailedResourcesDayView.class; + } + + @Override + public Node getControlPanel() { + ToggleButton availabilityButton = new ToggleButton("Edit Schedule"); + availabilityButton.selectedProperty().bindBidirectional(detailedResouresDayView.editAvailabilityProperty()); + return availabilityButton; + } + + @Override + protected DateControl createControl() { + detailedResouresDayView = new DetailedResourcesDayView(); + detailedResouresDayView.setPrefHeight(800); + detailedResouresDayView.setPrefWidth(700); + detailedResouresDayView.getResources().addAll(create("Dirk", Style.STYLE1), create("Katja", Style.STYLE2), create("Philip", Style.STYLE3), create("Jule", Style.STYLE4), create("Armin", Style.STYLE5)); + return detailedResouresDayView; + } + + private Resource create(String name, Style style) { + Resource resource = new Resource(name); + resource.getAvailabilityCalendar().setName("Availability of " + name); + resource.getCalendar().setStyle(style); + resource.getCalendar().addEventHandler(evt -> System.out.println(evt)); + resource.getAvailabilityCalendar().addEventHandler(evt -> System.out.println(evt)); + return resource; + } + + public static void main(String[] args) { + launch(args); + } + +} diff --git a/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloMultiDayViewContainer.java b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloMultiDayViewContainer.java new file mode 100644 index 00000000..25f7b983 --- /dev/null +++ b/CalendarFXSampler/src/main/java/com/calendarfx/demo/views/resources/HelloMultiDayViewContainer.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2017 Dirk Lemmermann Software & Consulting (dlsc.com) + * Copyright (C) 2006 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.calendarfx.demo.views.resources; + +import com.calendarfx.demo.CalendarFXDateControlSample; +import com.calendarfx.model.Calendar; +import com.calendarfx.model.Entry; +import com.calendarfx.view.DateControl; +import com.calendarfx.view.resources.DetailedResourcesDayView; +import com.calendarfx.view.resources.MultiResourceDayViewContainer; +import com.calendarfx.view.resources.Resource; + +import java.time.LocalDate; +import java.time.LocalTime; + +public class HelloMultiDayViewContainer extends CalendarFXDateControlSample { + + private MultiResourceDayViewContainer> multiDayViewContainer; + + @Override + public String getSampleName() { + return "Multi Day View Container"; + } + + @Override + public String getSampleDescription() { + return "A specialized container for showing multiple DayView instances, one for each item added to it."; + } + + @Override + protected Class getJavaDocClass() { + return DetailedResourcesDayView.class; + } + + @Override + protected DateControl createControl() { + multiDayViewContainer = new MultiResourceDayViewContainer<>(); + multiDayViewContainer.getResources().addAll(create("Dirk"), create("Katja"), create("Philip"), create("Jule"), create("Armin")); + multiDayViewContainer.setPrefHeight(800); + return multiDayViewContainer; + } + + private Resource create(String name) { + Resource resource = new Resource(name); + resource.getCalendar().addEventHandler(evt -> System.out.println(evt)); + resource.getAvailabilityCalendar().addEventHandler(evt -> System.out.println(evt)); + return resource; + } + + class HelloCalendar extends Calendar { + + public HelloCalendar() { + LocalDate date = LocalDate.now(); + + for (int i = 1; i < 3; i++) { + + Entry entry = new Entry<>(); + entry.changeStartDate(date); + entry.changeEndDate(date); + + entry.setTitle("Entry " + i); + + int hour = (int) (Math.random() * 23); + int durationInHours = Math.min(24 - hour, + (int) (Math.random() * 4)); + + LocalTime startTime = LocalTime.of(hour, 0); + LocalTime endTime = startTime.plusHours(durationInHours); + + entry.changeStartTime(startTime); + entry.changeEndTime(endTime); + + if (Math.random() < .1) { + entry.setFullDay(true); + entry.setTitle("Full Day Entry"); + } + + entry.setCalendar(this); + } + } + } + + public static void main(String[] args) { + launch(args); + } + +} diff --git a/CalendarFXSampler/src/main/java/module-info.java b/CalendarFXSampler/src/main/java/module-info.java index 47df5411..7a9f75ef 100644 --- a/CalendarFXSampler/src/main/java/module-info.java +++ b/CalendarFXSampler/src/main/java/module-info.java @@ -3,7 +3,7 @@ requires transitive javafx.graphics; requires javafx.web; - + requires fr.brouillard.oss.cssfx; requires com.calendarfx.view; exports com.calendarfx.demo to org.controlsfx.fxsampler; diff --git a/CalendarFXView/pom.xml b/CalendarFXView/pom.xml index 68da92af..56e2f89e 100644 --- a/CalendarFXView/pom.xml +++ b/CalendarFXView/pom.xml @@ -57,13 +57,6 @@ - - - src/main/resources - true - - - org.asciidoctor @@ -171,32 +164,6 @@ - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - calendar.css - package - - java - - - com.sun.javafx.css.parser.Css2Bin - - - - ${project.basedir}/src/main/resources/com/calendarfx/view/calendar.css - - - ${project.basedir}/target/classes/com/calendarfx/view/calendar.bss - - - - - - diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/DateControl.java b/CalendarFXView/src/main/java/com/calendarfx/view/DateControl.java index 91048d65..590ace5d 100644 --- a/CalendarFXView/src/main/java/com/calendarfx/view/DateControl.java +++ b/CalendarFXView/src/main/java/com/calendarfx/view/DateControl.java @@ -2514,8 +2514,7 @@ public final Calendar getAvailabilityCalendar() { } /** - * A background calendar can be used to display "availability" of - * a person or a resource. + * A background calendar used to display "availability" of a resource. * * @return the background calendar used for this view */ @@ -2523,8 +2522,8 @@ public final ObjectProperty availabilityCalendarProperty() { return availabilityCalendar; } - public final void setAvailabilityCalendar(Calendar availabilityGrid) { - this.availabilityCalendar.set(availabilityGrid); + public final void setAvailabilityCalendar(Calendar calendar) { + this.availabilityCalendar.set(calendar); } private final ObjectProperty availabilityGrid = new SimpleObjectProperty<>(this, "availabilityGrid", new VirtualGrid("30 Minutes", "30 Minutes", ChronoUnit.MINUTES, 30)); diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/DayViewBase.java b/CalendarFXView/src/main/java/com/calendarfx/view/DayViewBase.java index e47a7c04..1b50bafe 100644 --- a/CalendarFXView/src/main/java/com/calendarfx/view/DayViewBase.java +++ b/CalendarFXView/src/main/java/com/calendarfx/view/DayViewBase.java @@ -16,6 +16,7 @@ package com.calendarfx.view; +import com.calendarfx.model.Calendar; import com.calendarfx.model.Entry; import com.calendarfx.model.Interval; import com.calendarfx.util.LoggingDomain; @@ -71,6 +72,7 @@ public abstract class DayViewBase extends DateControl implements ZonedDateTimePr * Constructs a new view. */ public DayViewBase() { + scrollingEnabledProperty().addListener(it -> Thread.dumpStack()); MapChangeListener propertiesListener = change -> { if (change.wasAdded()) { @@ -102,6 +104,17 @@ public DayViewBase() { latestTimeUsedProperty().addListener(trimListener); trimTimeBoundsProperty().addListener(trimListener); + installDefaultLassoFinishedBehaviour(); + } + + /** + * Registers a {@link #onLassoFinishedProperty()} that will add a + * calendar entry for the lasso selection into the current availability + * calendar. + * + * @see #availabilityCalendarProperty() + */ + public void installDefaultLassoFinishedBehaviour() { setOnLassoFinished((start, end) -> { if (start == null || end == null) { return; @@ -115,7 +128,8 @@ public DayViewBase() { } Entry entry = new Entry<>("Availability Entry", new Interval(start, end, getZoneId())); - getAvailabilityCalendar().addEntry(entry); + Calendar availabilityCalendar = getAvailabilityCalendar(); + availabilityCalendar.addEntry(entry); } }); } diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/resources/DetailedResourcesDayView.java b/CalendarFXView/src/main/java/com/calendarfx/view/resources/DetailedResourcesDayView.java new file mode 100644 index 00000000..fe58c609 --- /dev/null +++ b/CalendarFXView/src/main/java/com/calendarfx/view/resources/DetailedResourcesDayView.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2017 Dirk Lemmermann Software & Consulting (dlsc.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.calendarfx.view.resources; + +import com.calendarfx.view.AllDayView; +import com.calendarfx.view.CalendarHeaderView; +import com.calendarfx.view.DayView; +import com.calendarfx.view.DayViewBase; +import com.calendarfx.view.TimeScaleView; +import impl.com.calendarfx.view.resources.DetailedResourcesDayViewSkin; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ListProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.control.Skin; +import javafx.util.Callback; + +/** + * The detailed day view is a composite control consisting of a {@link DayView}, + * an {@link AllDayView}, an {@link CalendarHeaderView}, and a + * {@link TimeScaleView}. The image below shows the standard appearance of the + * view. The second image shows the same view with the optional agenda view made + * visible. + * + * Detailed Day View + * Detailed Day View Agenda + * + */ +public class DetailedResourcesDayView> extends DayViewBase { + + private static final String DEFAULT_STYLE = "detailed-resources-day-view"; + + /** + * Constructs a new day view. + */ + public DetailedResourcesDayView() { + getStyleClass().add(DEFAULT_STYLE); + } + + @Override + protected Skin createDefaultSkin() { + return new DetailedResourcesDayViewSkin(this); + } + + private final ObjectProperty> resourceHeaderFactory = new SimpleObjectProperty<>(this,"headerFactory", resource -> { + Label label = new Label(resource.toString()); + label.setAlignment(Pos.CENTER); + label.getStyleClass().add("resource-header-label"); + label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); + return label; + }); + + public final Callback getResourceHeaderFactory() { + return resourceHeaderFactory.get(); + } + + public final ObjectProperty> resourceHeaderFactoryProperty() { + return resourceHeaderFactory; + } + + public final void setResourceHeaderFactory(Callback resourceHeaderFactory) { + this.resourceHeaderFactory.set(resourceHeaderFactory); + } + + private final ListProperty resources = new SimpleListProperty<>(this, "resources", FXCollections.observableArrayList()); + + public final ObservableList getResources() { + return resources.get(); + } + + public final ListProperty resourcesProperty() { + return resources; + } + + public final void setResources(ObservableList resources) { + this.resources.set(resources); + } + + // show all day view support + + private final BooleanProperty showAllDayView = new SimpleBooleanProperty(this, "showAllDayView", true); + + /** + * A property used to toggle the visibility of the all day view. + * + * @return true if the all day view will be visible + */ + public final BooleanProperty showAllDayViewProperty() { + return showAllDayView; + } + + /** + * Sets the value of {@link #showAllDayViewProperty()}. + * + * @return true if the all day view will be visible + */ + public final boolean isShowAllDayView() { + return showAllDayViewProperty().get(); + } + + /** + * Sets the value of {@link #showAllDayViewProperty()}. + * + * @param show + * true if the all day view will be visible + */ + public final void setShowAllDayView(boolean show) { + showAllDayViewProperty().set(show); + } + + // show timescale view support + + private final BooleanProperty showTimeScaleView = new SimpleBooleanProperty(this, "showTimeScaleView", true); + + /** + * A property used to toggle the visibility of the time scale view. + * + * @return true if the timescale view will be visible + */ + public final BooleanProperty showTimeScaleViewProperty() { + return showTimeScaleView; + } + + /** + * Returns the value of {@link #showTimeScaleViewProperty()}. + * + * @return true if the timescale view will be visible + */ + public final boolean isShowTimeScaleView() { + return showTimeScaleViewProperty().get(); + } + + /** + * Sets the value of {@link #showTimeScaleViewProperty()}. + * + * @param show + * if true the timescale view will be visible + */ + public final void setShowTimeScaleView(boolean show) { + showTimeScaleViewProperty().set(show); + } + + // show scrollbar support + + private final BooleanProperty showScrollBar = new SimpleBooleanProperty(this, "showScrollBar", true); + + /** + * A property used to control the visibility of the vertial scrollbar. + * + * @return true if the scrollbar should be shown to the user + */ + public final BooleanProperty showScrollBarProperty() { + return showScrollBar; + } + + /** + * Sets the value of {@link #showScrollBarProperty()}. + * + * @param showScrollBar + * if true the scrollbar will be visible + */ + public final void setShowScrollBar(boolean showScrollBar) { + this.showScrollBar.set(showScrollBar); + } + + /** + * Returns the value of {@link #showScrollBarProperty()}. + * + * @return true if the scrollbar will be visible + */ + public final boolean isShowScrollBar() { + return showScrollBar.get(); + } +} diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/resources/MultiResourceDayViewContainer.java b/CalendarFXView/src/main/java/com/calendarfx/view/resources/MultiResourceDayViewContainer.java new file mode 100644 index 00000000..9fac3d62 --- /dev/null +++ b/CalendarFXView/src/main/java/com/calendarfx/view/resources/MultiResourceDayViewContainer.java @@ -0,0 +1,36 @@ +package com.calendarfx.view.resources; + +import com.calendarfx.view.DayViewBase; +import impl.com.calendarfx.view.resources.MultiResourceDayViewContainerSkin; +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.Skin; + +public class MultiResourceDayViewContainer> extends DayViewBase { + + public MultiResourceDayViewContainer() { + getStyleClass().add("multi-resource-day-view-container"); + } + + @Override + protected Skin createDefaultSkin() { + return new MultiResourceDayViewContainerSkin<>(this); + } + + private final ListProperty resources = new SimpleListProperty<>(this, "resources", FXCollections.observableArrayList()); + + public final ObservableList getResources() { + return resources.get(); + } + + public final ListProperty resourcesProperty() { + return resources; + } + + public final void setResources(ObservableList resources) { + this.resources.set(resources); + } +} + diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/resources/Resource.java b/CalendarFXView/src/main/java/com/calendarfx/view/resources/Resource.java new file mode 100644 index 00000000..50aa8e56 --- /dev/null +++ b/CalendarFXView/src/main/java/com/calendarfx/view/resources/Resource.java @@ -0,0 +1,62 @@ +package com.calendarfx.view.resources; + +import com.calendarfx.model.Calendar; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + +public class Resource { + + public Resource() { + } + + public Resource(T userObject) { + setUserObject(userObject); + } + + private final ObjectProperty userObject = new SimpleObjectProperty<>(this, "userObject"); + + public final T getUserObject() { + return userObject.get(); + } + + public final ObjectProperty userObjectProperty() { + return userObject; + } + + public final void setUserObject(T userObject) { + this.userObject.set(userObject); + } + + public final ObjectProperty calendar = new SimpleObjectProperty<>(this, "calendar", new Calendar()); + + public final Calendar getCalendar() { + return calendar.get(); + } + + public final ObjectProperty calendarProperty() { + return calendar; + } + + public final void setCalendar(Calendar calendar) { + this.calendar.set(calendar); + } + + public final ObjectProperty availabilityCalendar = new SimpleObjectProperty<>(this, "availabilityCalendar", new Calendar()); + + public Calendar getAvailabilityCalendar() { + return availabilityCalendar.get(); + } + + public ObjectProperty availabilityCalendarProperty() { + return availabilityCalendar; + } + + public void setAvailabilityCalendar(Calendar availabilityCalendar) { + this.availabilityCalendar.set(availabilityCalendar); + } + + @Override + public String toString() { + return getUserObject().toString(); + } +} diff --git a/CalendarFXView/src/main/java/com/calendarfx/view/ResourceCalendarView.java b/CalendarFXView/src/main/java/com/calendarfx/view/resources/ResourceCalendarView.java similarity index 96% rename from CalendarFXView/src/main/java/com/calendarfx/view/ResourceCalendarView.java rename to CalendarFXView/src/main/java/com/calendarfx/view/resources/ResourceCalendarView.java index fa812ca7..6fbd6fb7 100644 --- a/CalendarFXView/src/main/java/com/calendarfx/view/ResourceCalendarView.java +++ b/CalendarFXView/src/main/java/com/calendarfx/view/resources/ResourceCalendarView.java @@ -1,7 +1,9 @@ -package com.calendarfx.view; +package com.calendarfx.view.resources; import com.calendarfx.model.Marker; -import impl.com.calendarfx.view.ResourceCalendarViewSkin; +import com.calendarfx.view.DayView; +import com.calendarfx.view.DayViewBase; +import impl.com.calendarfx.view.resources.ResourceCalendarViewSkin; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ListProperty; diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewBaseSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewBaseSkin.java index e28812d5..c449824f 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewBaseSkin.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewBaseSkin.java @@ -74,6 +74,7 @@ public DayViewBaseSkin(T view) { private void registerLayoutListener(Observable obs) { obs.addListener(layoutListener); } + @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewEditController.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewEditController.java index 2b362145..8938500f 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewEditController.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewEditController.java @@ -87,6 +87,12 @@ public DayViewEditController(DayViewBase dayView) { } })); dayView.addEventFilter(MouseEvent.MOUSE_MOVED, this::mouseMoved); + + lassoStartProperty().addListener(it -> dayView.setLassoStart(getLassoStart())); + lassoEndProperty().addListener(it -> dayView.setLassoEnd(getLassoEnd())); + + setOnLassoFinished(dayView.getOnLassoFinished()); + dayView.onLassoFinishedProperty().addListener(it -> setOnLassoFinished(dayView.getOnLassoFinished())); } private enum Handle { @@ -176,6 +182,10 @@ private void mousePressed(MouseEvent evt) { setLassoEnd(grid(dayViewBase.getInstantAt(evt), availabilityGrid).plus(availabilityGrid.getAmount(), availabilityGrid.getUnit())); } + if (dayViewBase.isEditAvailability()) { + return; + } + dragMode = null; handle = null; @@ -320,7 +330,7 @@ private void mouseDragged(MouseEvent evt) { setLassoEnd(grid(dayViewBase.getInstantAt(evt), dayViewBase.getAvailabilityGrid())); } - if (!evt.getButton().equals(MouseButton.PRIMARY) || dragMode == null || !dragging) { + if (dayViewBase.isEditAvailability() || !evt.getButton().equals(MouseButton.PRIMARY) || dragMode == null || !dragging) { return; } diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewSkin.java index 4ef7a480..e5db79d3 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewSkin.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DayViewSkin.java @@ -155,10 +155,6 @@ public DayViewSkin(T view) { * installed on the week view, not on the individual days. */ controller = new DayViewEditController(view); - controller.onLassoFinishedProperty().bind(view.onLassoFinishedProperty()); - - view.lassoStartProperty().bind(controller.lassoStartProperty()); - view.lassoEndProperty().bind(controller.lassoEndProperty()); } setupCurrentTimeMarkerSupport(); @@ -1062,11 +1058,14 @@ public void draw() { Calendar availabilityCalendar = dayView.getAvailabilityCalendar(); if (availabilityCalendar != null) { + System.out.println("drawing: " + availabilityCalendar.getName()); gc.setFill(dayView.getAvailabilityFill()); LocalDate date = dayView.getDate(); Map>> entries = availabilityCalendar.findEntries(date, date, dayView.getZoneId()); List> entriesOnDate = entries.get(date); + System.out.println("entries on date" + entriesOnDate); if (entriesOnDate != null) { + System.out.println("size: " + entriesOnDate.size()); entriesOnDate.forEach(entry -> { ZonedDateTime startAsZonedDateTime = entry.getStartAsZonedDateTime(); ZonedDateTime endAsZonedDateTime = entry.getEndAsZonedDateTime(); diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DetailedDayViewSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DetailedDayViewSkin.java index 12a7257e..b71ded56 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/DetailedDayViewSkin.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/DetailedDayViewSkin.java @@ -106,7 +106,6 @@ public DetailedDayViewSkin(DetailedDayView view) { calendarHeaderView.visibleProperty().bind(view.layoutProperty().isEqualTo(DateControl.Layout.SWIMLANE)); agendaView = view.getAgendaView(); -// agendaView.addEventHandler(RequestEvent.REQUEST_ENTRY, evt -> dayView.editEntry(evt.getEntry())); RowConstraints row0 = new RowConstraints(); row0.setFillHeight(true); diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/WeekViewSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/WeekViewSkin.java index 3eee8123..e05dd02e 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/WeekViewSkin.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/WeekViewSkin.java @@ -37,8 +37,6 @@ public class WeekViewSkin extends SkinBase { private final GridPane dayGridPane = new GridPane(); - private final DayViewEditController controller; - public WeekViewSkin(WeekView view) { super(view); @@ -54,11 +52,7 @@ public WeekViewSkin(WeekView view) { clip.heightProperty().bind(view.heightProperty()); view.setClip(clip); - controller = new DayViewEditController(view); - controller.onLassoFinishedProperty().bind(view.onLassoFinishedProperty()); - - view.lassoStartProperty().bind(controller.lassoStartProperty()); - view.lassoEndProperty().bind(controller.lassoEndProperty()); + new DayViewEditController(view); getChildren().add(dayGridPane); } diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/DetailedResourcesDayViewSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/DetailedResourcesDayViewSkin.java new file mode 100644 index 00000000..809d2bbe --- /dev/null +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/DetailedResourcesDayViewSkin.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2017 Dirk Lemmermann Software & Consulting (dlsc.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package impl.com.calendarfx.view.resources; + +import com.calendarfx.model.CalendarSource; +import com.calendarfx.view.AllDayView; +import com.calendarfx.view.TimeScaleView; +import com.calendarfx.view.resources.DetailedResourcesDayView; +import com.calendarfx.view.resources.MultiResourceDayViewContainer; +import com.calendarfx.view.resources.Resource; +import impl.com.calendarfx.view.DateControlSkin; +import impl.com.calendarfx.view.DayViewScrollPane; +import javafx.application.Platform; +import javafx.beans.InvalidationListener; +import javafx.beans.Observable; +import javafx.beans.binding.Bindings; +import javafx.collections.ObservableList; +import javafx.geometry.Orientation; +import javafx.scene.Node; +import javafx.scene.control.ScrollBar; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.RowConstraints; +import javafx.scene.layout.VBox; +import javafx.util.Callback; + +import static com.calendarfx.util.ViewHelper.scrollToRequestedTime; + +public class DetailedResourcesDayViewSkin> extends DateControlSkin> { + + private final GridPane gridPane; + private final MultiResourceDayViewContainer dayViewContainer; + private final DayViewScrollPane timeScaleScrollPane; + private final DayViewScrollPane dayViewsScrollPane; + private final ScrollBar scrollBar; + + public DetailedResourcesDayViewSkin(DetailedResourcesDayView view) { + super(view); + + scrollBar = new ScrollBar(); + scrollBar.setOrientation(Orientation.VERTICAL); + + TimeScaleView timeScale = new TimeScaleView(); + view.bind(timeScale, true); + + // time scale scroll pane + timeScaleScrollPane = new DayViewScrollPane(timeScale, scrollBar); + timeScaleScrollPane.getStyleClass().addAll("calendar-scroll-pane", "day-view-timescale-scroll-pane"); + timeScaleScrollPane.setMinWidth(Region.USE_PREF_SIZE); + + final InvalidationListener visibilityListener = it -> updateView(); + view.showAllDayViewProperty().addListener(visibilityListener); + view.showTimeScaleViewProperty().addListener(visibilityListener); + view.layoutProperty().addListener(visibilityListener); + view.showScrollBarProperty().addListener(visibilityListener); + + RowConstraints row0 = new RowConstraints(); + row0.setFillHeight(true); + row0.setPrefHeight(Region.USE_COMPUTED_SIZE); + row0.setVgrow(Priority.NEVER); + + RowConstraints row1 = new RowConstraints(); + row1.setFillHeight(true); + row1.setVgrow(Priority.ALWAYS); + + gridPane = new GridPane(); + gridPane.getRowConstraints().setAll(row0, row1); + gridPane.getStyleClass().add("container"); + + dayViewContainer = new MultiResourceDayViewContainer<>(); + dayViewContainer.resourcesProperty().bind(view.resourcesProperty()); + view.bind(dayViewContainer, true); + + getChildren().add(gridPane); + + dayViewsScrollPane = new DayViewScrollPane(dayViewContainer, scrollBar); + + /* + * Run later when the control has become visible. + */ + Platform.runLater(() -> scrollToRequestedTime(view, dayViewsScrollPane)); + + view.requestedTimeProperty().addListener(it -> scrollToRequestedTime(view, dayViewsScrollPane)); + + view.resourcesProperty().addListener((Observable it) -> updateView()); + updateView(); + } + + + private void updateView() { + gridPane.getChildren().clear(); + gridPane.getColumnConstraints().clear(); + + final DetailedResourcesDayView view = getSkinnable(); + + if (view.isShowTimeScaleView()) { + ColumnConstraints timeScaleColumn = new ColumnConstraints(); + timeScaleColumn.setFillWidth(true); + timeScaleColumn.setHgrow(Priority.NEVER); + gridPane.getColumnConstraints().add(timeScaleColumn); + gridPane.add(timeScaleScrollPane, 0, 1); + } + + HBox headerBox = new HBox(); + headerBox.getStyleClass().add("header-box"); + + headerBox.setFillHeight(true); + gridPane.add(headerBox, 1, 0); + + Callback resourceHeaderFactory = view.getResourceHeaderFactory(); + + ObservableList resources = view.getResources(); + for (int i = 0; i < resources.size(); i++) { + T resource = resources.get(i); + Node headerNode = resourceHeaderFactory.call(resource); + VBox resourceHeader = new VBox(headerNode); + + if (view.isShowAllDayView()) { + AllDayView allDayView = new AllDayView(); + + view.bind(allDayView, true); + Bindings.unbindBidirectional(view.defaultCalendarProviderProperty(), allDayView.defaultCalendarProviderProperty()); + Bindings.unbindBidirectional(view.draggedEntryProperty(), allDayView.draggedEntryProperty()); + Bindings.unbindContentBidirectional(view.getCalendarSources(), allDayView.getCalendarSources()); + + allDayView.setNumberOfDays(1); + CalendarSource calendarSource = createCalendarSource(resource); + allDayView.getCalendarSources().setAll(calendarSource); + allDayView.setDefaultCalendarProvider(control -> calendarSource.getCalendars().get(0)); + + resourceHeader.getChildren().add(allDayView); + } + + resourceHeader.getStyleClass().add("resource-header-view"); + HBox.setHgrow(resourceHeader, Priority.ALWAYS); + + headerBox.getChildren().add(resourceHeader); + } + + ColumnConstraints dayViewsConstraints = new ColumnConstraints(); + dayViewsConstraints.setFillWidth(true); + dayViewsConstraints.setHgrow(Priority.ALWAYS); + gridPane.getColumnConstraints().add(dayViewsConstraints); + gridPane.add(dayViewsScrollPane, 1, 1); + + if (view.isShowScrollBar()) { + ColumnConstraints scrollbarConstraint = new ColumnConstraints(); + scrollbarConstraint.setFillWidth(true); + scrollbarConstraint.setHgrow(Priority.NEVER); + scrollbarConstraint.setPrefWidth(Region.USE_COMPUTED_SIZE); + gridPane.getColumnConstraints().add(scrollbarConstraint); + + gridPane.add(scrollBar, 2, 1); + } + } + + private CalendarSource createCalendarSource(T resource) { + CalendarSource source = new CalendarSource(resource.getUserObject().toString()); + source.getCalendars().add(resource.getCalendar()); + return source; + } +} diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/MultiResourceDayViewContainerSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/MultiResourceDayViewContainerSkin.java new file mode 100644 index 00000000..b8a04e54 --- /dev/null +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/MultiResourceDayViewContainerSkin.java @@ -0,0 +1,69 @@ +package impl.com.calendarfx.view.resources; + +import com.calendarfx.model.CalendarSource; +import com.calendarfx.view.DayView; +import com.calendarfx.view.resources.MultiResourceDayViewContainer; +import com.calendarfx.view.resources.Resource; +import impl.com.calendarfx.view.DayViewBaseSkin; +import javafx.beans.Observable; +import javafx.beans.binding.Bindings; +import javafx.collections.ObservableList; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; + +public class MultiResourceDayViewContainerSkin> extends DayViewBaseSkin> { + + private final HBox container = new HBox(); + + public MultiResourceDayViewContainerSkin(MultiResourceDayViewContainer view) { + super(view); + container.getStyleClass().add("inner-container"); + view.getResources().addListener((Observable it) -> updateView()); + updateView(); + getChildren().add(container); + } + + private void updateView() { + container.getChildren().clear(); + + MultiResourceDayViewContainer multiResourceDayViewContainer = getSkinnable(); + ObservableList resources = multiResourceDayViewContainer.getResources(); + for (int i = 0; i < resources.size(); i++) { + DayView dayView = new DayView(); + + // bind day view to container but remove bindings that interfere + multiResourceDayViewContainer.bind(dayView, true); + Bindings.unbindBidirectional(multiResourceDayViewContainer.defaultCalendarProviderProperty(), dayView.defaultCalendarProviderProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.draggedEntryProperty(), dayView.draggedEntryProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.enableCurrentTimeMarkerProperty(), dayView.enableCurrentTimeMarkerProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.enableCurrentTimeCircleProperty(), dayView.enableCurrentTimeCircleProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.availabilityCalendarProperty(), dayView.availabilityCalendarProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.lassoStartProperty(), dayView.lassoStartProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.lassoEndProperty(), dayView.lassoEndProperty()); + Bindings.unbindBidirectional(multiResourceDayViewContainer.onLassoFinishedProperty(), dayView.onLassoFinishedProperty()); + Bindings.unbindContentBidirectional(multiResourceDayViewContainer.getCalendarSources(), dayView.getCalendarSources()); + + dayView.setEnableCurrentTimeCircle(i == 0); + dayView.setEnableCurrentTimeMarker(true); + + T resource = resources.get(i); + + dayView.setAvailabilityCalendar(resource.getAvailabilityCalendar()); + dayView.installDefaultLassoFinishedBehaviour(); + + CalendarSource calendarSource = createCalendarSource(resource); + dayView.getCalendarSources().setAll(calendarSource); + dayView.setDefaultCalendarProvider(control -> calendarSource.getCalendars().get(0)); + + container.getChildren().add(dayView); + HBox.setHgrow(dayView, Priority.ALWAYS); + } + } + + private CalendarSource createCalendarSource(T resource) { + CalendarSource source = new CalendarSource(resource.getUserObject().toString()); + source.setName(resource.getUserObject().toString()); + source.getCalendars().setAll(resource.getCalendar()); + return source; + } +} \ No newline at end of file diff --git a/CalendarFXView/src/main/java/impl/com/calendarfx/view/ResourceCalendarViewSkin.java b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/ResourceCalendarViewSkin.java similarity index 98% rename from CalendarFXView/src/main/java/impl/com/calendarfx/view/ResourceCalendarViewSkin.java rename to CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/ResourceCalendarViewSkin.java index b22cf721..adf3f9e6 100644 --- a/CalendarFXView/src/main/java/impl/com/calendarfx/view/ResourceCalendarViewSkin.java +++ b/CalendarFXView/src/main/java/impl/com/calendarfx/view/resources/ResourceCalendarViewSkin.java @@ -1,10 +1,11 @@ -package impl.com.calendarfx.view; +package impl.com.calendarfx.view.resources; import com.calendarfx.model.Marker; import com.calendarfx.view.DayView; -import com.calendarfx.view.ResourceCalendarView; +import com.calendarfx.view.resources.ResourceCalendarView; import com.calendarfx.view.TimeScaleView; import com.calendarfx.view.VirtualGrid; +import impl.com.calendarfx.view.DayViewBaseSkin; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.Observable; diff --git a/CalendarFXView/src/main/java/module-info.java b/CalendarFXView/src/main/java/module-info.java index aa685b63..55a97e63 100644 --- a/CalendarFXView/src/main/java/module-info.java +++ b/CalendarFXView/src/main/java/module-info.java @@ -14,12 +14,15 @@ exports com.calendarfx.view.page; exports com.calendarfx.view.popover; exports com.calendarfx.view.print; + exports com.calendarfx.view.resources; exports impl.com.calendarfx.view; exports impl.com.calendarfx.view.page; exports impl.com.calendarfx.view.popover; exports impl.com.calendarfx.view.print; + exports impl.com.calendarfx.view.resources; exports impl.com.calendarfx.view.util; opens com.calendarfx.view; + opens com.calendarfx.view.resources; } \ No newline at end of file diff --git a/CalendarFXView/src/main/resources/com/calendarfx/view/calendar.css b/CalendarFXView/src/main/resources/com/calendarfx/view/calendar.css index 4afaa0cc..5a85d233 100644 --- a/CalendarFXView/src/main/resources/com/calendarfx/view/calendar.css +++ b/CalendarFXView/src/main/resources/com/calendarfx/view/calendar.css @@ -2029,4 +2029,17 @@ */ .time-field > .box { -fx-spacing: 2px; +} + +/* + * -------------------------------------------------------------------------------------------------------------- + * Styles for the DetailedResourcesDayView control. + */ +.detailed-resources-day-view { +} + +.detailed-resources-day-view .header-box .resource-header-view .resource-header-label { + -fx-padding: 5px; + -fx-font-weight: bold; + -fx-alignment: center; } \ No newline at end of file