Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination components and enhance header text display, update styles #645

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,17 @@
import com.dlsc.jfxcentral2.utils.MobileLinkUtil;
import com.dlsc.jfxcentral2.utils.ModelObjectTool;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.materialdesign.MaterialDesign;

import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

public class LearnPagination<T extends Learn> extends VBox {
public class LearnPagination<T extends Learn> extends MobilePagination<T> {

private static final String DEFAULT_STYLE_CLASS = "learn-pagination";
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
Expand All @@ -42,11 +33,6 @@ public class LearnPagination<T extends Learn> extends VBox {
public LearnPagination() {
getStyleClass().add(DEFAULT_STYLE_CLASS);

// Label title = new Label();
// title.getStyleClass().add("title");
// title.setWrapText(true);
// title.textProperty().bind(itemProperty().map(item -> item == null ? "" : item.getName()));

Label dateLabel = new Label();
dateLabel.getStyleClass().add("date-label");
dateLabel.textProperty().bind(itemProperty().map(item -> item == null ? "" : DATE_FORMATTER.format(item.getCreatedOn())));
Expand All @@ -67,9 +53,6 @@ public LearnPagination() {
authorBox.getChildren().add(avatarView);
}));
authorBox.getChildren().addAll(spacer, dateLabel);

// scroll to top
scrollPane.setVvalue(0);
});

CustomMarkdownView markdownView = new CustomMarkdownView();
Expand All @@ -90,90 +73,16 @@ public LearnPagination() {
return "";
}, itemProperty(), baseURLProperty()));

Button previousButton = new Button();
previousButton.getStyleClass().addAll("nav-button", "previous-button");
previousButton.setGraphic(new FontIcon(MaterialDesign.MDI_CHEVRON_LEFT));
previousButton.disableProperty().bind(index.isEqualTo(0));
previousButton.setOnAction(e -> setIndex(getIndex() - 1));

Button nextButton = new Button();
nextButton.getStyleClass().addAll("nav-button", "next-button");
nextButton.setGraphic(new FontIcon(MaterialDesign.MDI_CHEVRON_RIGHT));
nextButton.disableProperty().bind(Bindings.createBooleanBinding(() -> getIndex() >= items.size() - 1, indexProperty(), getItems()));
nextButton.setOnAction(e -> setIndex(getIndex() + 1));

Label pageLabel = new Label();
pageLabel.getStyleClass().add("page-label");
pageLabel.textProperty().bind(Bindings.concat(indexProperty().add(1), " / ", Bindings.size(items)));

HBox navBox = new HBox(previousButton, pageLabel, nextButton);
navBox.getStyleClass().add("nav-box");
pageLabel.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(pageLabel, Priority.ALWAYS);

VBox contentBox = new VBox(authorBox, markdownView);
contentBox.getStyleClass().add("content-box");

scrollPane.setContent(contentBox);
scrollPane.getStyleClass().add("mobile");
scrollPane.setMaxHeight(Double.MAX_VALUE);
VBox.setVgrow(scrollPane, Priority.ALWAYS);

getChildren().addAll(scrollPane, navBox);

itemProperty().bind(Bindings.createObjectBinding(() -> {
int currentIndex = getIndex();
int size = getItems().size();
if (currentIndex < 0 || currentIndex >= size) {
return null;
}

return getItems().get(currentIndex);
}, indexProperty(), getItems()));
}

public final void setSelectedItem(T item) {
setIndex(getItems().indexOf(item));
}

// learn items

private final ObservableList<T> items = FXCollections.observableArrayList();

public ObservableList<T> getItems() {
return items;
}

// index

private final IntegerProperty index = new SimpleIntegerProperty(this, "index", -1);

public final IntegerProperty indexProperty() {
return index;
}

public final int getIndex() {
return index.get();
}

public final void setIndex(int index) {
this.index.set(index);
}

// item

private final ReadOnlyObjectWrapper<T> item = new ReadOnlyObjectWrapper<>(this, "item");

public final T getItem() {
return item.get();
}

public final ReadOnlyObjectWrapper<T> itemProperty() {
return item;
}

private void setItem(T item) {
this.item.set(item);
setCellFactory(index -> {
scrollPane.setVvalue(0);
return scrollPane;
});
}

// base url
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.dlsc.jfxcentral2.mobile.components;

import com.dlsc.jfxcentral.data.DataRepository2;
import com.dlsc.jfxcentral.data.model.LinksOfTheWeek;
import com.dlsc.jfxcentral2.components.CustomMarkdownView;
import com.dlsc.jfxcentral2.components.PrettyScrollPane;
import javafx.beans.binding.Bindings;

public class LotwPagination extends MobilePagination<LinksOfTheWeek> {

private static final String DEFAULT_STYLE_CLASS = "lotw-pagination";
private final PrettyScrollPane scrollPane = new PrettyScrollPane();

public LotwPagination() {
getStyleClass().add(DEFAULT_STYLE_CLASS);

CustomMarkdownView markdownView = new CustomMarkdownView();
markdownView.mdStringProperty().bind(Bindings.createStringBinding(() -> {
LinksOfTheWeek lotw = getItem();
if (lotw == null) {
return "";
}
return DataRepository2.getInstance().getLinksOfTheWeekReadMe(lotw);
}, itemProperty()));

scrollPane.setContent(markdownView);
scrollPane.getStyleClass().add("mobile");

setCellFactory(index -> {
scrollPane.setVvalue(0);
return scrollPane;
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.dlsc.jfxcentral2.model.Size;
import com.dlsc.jfxcentral2.utils.MobileLinkUtil;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.Button;
Expand All @@ -21,6 +22,7 @@ public class MobilePageHeader extends StackPane {

private static final String DEFAULT_STYLE_CLASS = "mobile-page-header";
private final SizeSupport sizeSupport = new SizeSupport(this);
private final Label categoryTitle;

public MobilePageHeader() {
getStyleClass().add(DEFAULT_STYLE_CLASS);
Expand All @@ -33,8 +35,13 @@ public MobilePageHeader() {
HBox topBox = new HBox(backButton);
topBox.getStyleClass().add("top-box");

Label categoryTitle = new Label();
categoryTitle = new Label();
categoryTitle.getStyleClass().add("title");
categoryTitle.setWrapText(true);
categoryTitle.setMinHeight(-1);
categoryTitle.setMaxHeight(Double.MAX_VALUE);

// categoryTitle.
categoryTitle.textProperty().bind(titleProperty());
categoryTitle.graphicProperty().bind(Bindings.createObjectBinding(() -> {
Ikon icon = getIcon();
Expand All @@ -47,10 +54,29 @@ public MobilePageHeader() {
return null;
}, iconProperty(), previewImageProperty()));

BooleanBinding longTitleProperty = Bindings.createBooleanBinding(() -> {
String title = getTitle();
boolean isShortTitle = title == null || title.split(" ").length < 7 || title.length() < 38;
return getIcon() == null && getPreviewImage() == null && !isShortTitle;
}, widthProperty(), iconProperty(), previewImageProperty(), titleProperty());

updateLongTitle(longTitleProperty.get());
longTitleProperty.addListener((obs, oldVal, newVal) -> updateLongTitle(newVal));

getChildren().addAll(categoryTitle, topBox);
setMaxHeight(Region.USE_PREF_SIZE);
}

private void updateLongTitle(boolean isLongTitle) {
if (isLongTitle) {
if (!categoryTitle.getStyleClass().contains("long-title")) {
categoryTitle.getStyleClass().add("long-title");
}
} else {
getStyleClass().remove("long-title");
}
}

// size support

public final ObjectProperty<Size> sizeProperty() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package com.dlsc.jfxcentral2.mobile.components;

import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.materialdesign.MaterialDesign;

public class MobilePagination<T> extends VBox {

private static final String DEFAULT_STYLE_CLASS = "mobile-pagination";
private final StackPane contentWrapper;

public MobilePagination() {
getStyleClass().add(DEFAULT_STYLE_CLASS);

Button previousButton = new Button();
previousButton.getStyleClass().addAll("nav-button", "previous-button");
previousButton.setGraphic(new FontIcon(MaterialDesign.MDI_CHEVRON_LEFT));
previousButton.disableProperty().bind(index.isEqualTo(0));
previousButton.setOnAction(e -> setIndex(getIndex() - 1));

Button nextButton = new Button();
nextButton.getStyleClass().addAll("nav-button", "next-button");
nextButton.setGraphic(new FontIcon(MaterialDesign.MDI_CHEVRON_RIGHT));
nextButton.disableProperty().bind(Bindings.createBooleanBinding(() -> getIndex() >= items.size() - 1, indexProperty(), getItems()));
nextButton.setOnAction(e -> setIndex(getIndex() + 1));

Label pageLabel = new Label();
pageLabel.getStyleClass().add("page-label");
pageLabel.textProperty().bind(Bindings.concat(indexProperty().add(1), " / ", Bindings.size(items)));

HBox navBox = new HBox(previousButton, pageLabel, nextButton);
navBox.getStyleClass().add("nav-box");
pageLabel.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(pageLabel, Priority.ALWAYS);

contentWrapper = new StackPane();
contentWrapper.getStyleClass().add("content-wrapper");
VBox.setVgrow(contentWrapper, Priority.ALWAYS);

getChildren().addAll(contentWrapper, navBox);

itemProperty().bind(Bindings.createObjectBinding(() -> {
boolean validatedIndex = isValidIndex();
return validatedIndex ? getItems().get(getIndex()) : null;
}, indexProperty(), getItems()));

updatedPageView();
indexProperty().addListener(it -> updatedPageView());
}

protected void updatedPageView() {
boolean validatedIndex = isValidIndex();
if (validatedIndex) {
contentWrapper.getChildren().setAll(getCellFactory().call(getIndex()));
} else {
contentWrapper.getChildren().clear();
}
}

private boolean isValidIndex() {
int currentIndex = getIndex();
int size = getItems().size();
return currentIndex >= 0 && currentIndex < size;
}

public final void setSelectedItem(T item) {
setIndex(getItems().indexOf(item));
}

// items

private final ObservableList<T> items = FXCollections.observableArrayList();

public ObservableList<T> getItems() {
return items;
}

// index

private final IntegerProperty index = new SimpleIntegerProperty(this, "index", -1);

public final IntegerProperty indexProperty() {
return index;
}

public final int getIndex() {
return index.get();
}

public final void setIndex(int index) {
this.index.set(index);
}

// item

private final ReadOnlyObjectWrapper<T> item = new ReadOnlyObjectWrapper<>(this, "item");

public final T getItem() {
return item.get();
}

public final ReadOnlyObjectWrapper<T> itemProperty() {
return item;
}

private void setItem(T item) {
this.item.set(item);
}

// cellFactory

private final ObjectProperty<Callback<Integer, Node>> cellFactory = new SimpleObjectProperty<>(this, "cellFactory", i -> new Label("Page " + (i + 1)));

public final ObjectProperty<Callback<Integer, Node>> cellFactoryProperty() {
return cellFactory;
}

public final Callback<Integer, Node> getCellFactory() {
return cellFactory.get();
}

public final void setCellFactory(Callback<Integer, Node> cellFactory) {
cellFactoryProperty().set(cellFactory);
}

}
Loading
Loading