Add pseudo class 'first' for 'options-list-item'

Related: caf85d2a924e6707d7d7448a2a148d984feae42f
This commit is contained in:
yushijinhun 2018-10-02 20:38:41 +08:00
parent 2fa08e0a70
commit b8bf56c8c3
No known key found for this signature in database
GPG Key ID: 5BC167F73EA558E4
3 changed files with 22 additions and 71 deletions

View File

@ -21,18 +21,17 @@ import org.jackhuang.hmcl.util.javafx.MappedObservableList;
import javafx.beans.DefaultProperty;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.scene.Node;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
@DefaultProperty("content")
@ -101,15 +100,29 @@ public class ComponentList extends Control {
}
protected static class Skin extends SkinBase<ComponentList> {
private static final PseudoClass PSEUDO_CLASS_FIRST = PseudoClass.getPseudoClass("first");
private final ObservableList<Node> list;
private final ObjectBinding<Node> firstItem;
protected Skin(ComponentList control) {
super(control);
list = MappedObservableList.create(control.getContent(), ComponentListCell::new);
ListFirstElementListener.observe(list,
first -> first.getStyleClass().setAll("options-list-item-ahead"),
last -> last.getStyleClass().setAll("options-list-item"));
list = MappedObservableList.create(control.getContent(), node -> {
ComponentListCell cell = new ComponentListCell(node);
cell.getStyleClass().add("options-list-item");
return cell;
});
firstItem = Bindings.valueAt(list, 0);
firstItem.addListener((observable, oldValue, newValue) -> {
if (newValue != null)
newValue.pseudoClassStateChanged(PSEUDO_CLASS_FIRST, true);
if (oldValue != null)
oldValue.pseudoClassStateChanged(PSEUDO_CLASS_FIRST, false);
});
if (!list.isEmpty())
list.get(0).pseudoClassStateChanged(PSEUDO_CLASS_FIRST, true);
VBox vbox = new VBox();
Bindings.bindContent(vbox.getChildren(), list);

View File

@ -1,59 +0,0 @@
package org.jackhuang.hmcl.ui.construct;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.function.Consumer;
public class ListFirstElementListener<T> implements ListChangeListener<T> {
private final Consumer<? super T> first, last;
public ListFirstElementListener(Consumer<? super T> first, Consumer<? super T> last) {
this.first = first;
this.last = last;
}
@Override
public void onChanged(Change<? extends T> c) {
ObservableList<? extends T> list = c.getList();
if (list.isEmpty()) return;
while (c.next()) {
int from = c.getFrom();
int to = c.getTo();
if (c.wasPermutated()) {
for (int i = from; i < to; ++i) {
int newIdx = c.getPermutation(i);
if (i == 0 && newIdx != 0)
last.accept(list.get(newIdx));
else if (i != 0 && newIdx == 0)
first.accept(list.get(newIdx));
}
} else {
if (c.wasRemoved()) {
if (!list.isEmpty() && from == 0)
first.accept(list.get(0));
}
if (c.wasAdded()) {
for (int i = from; i < to; ++i) {
if (i == 0)
first.accept(list.get(0));
else
last.accept(list.get(i));
}
if (list.size() > to)
last.accept(list.get(to));
}
}
}
}
public static <T> void observe(ObservableList<? extends T> list, Consumer<? super T> first, Consumer<? super T> last) {
for (int i = 0; i < list.size(); ++i) {
if (i == 0) first.accept(list.get(i));
else last.accept(list.get(i));
}
list.addListener(new ListFirstElementListener<>(first, last));
}
}

View File

@ -732,11 +732,8 @@
-fx-font-size: 12;
}
.options-list-item-ahead {
-fx-background-radius: 2 2 0 0;
-fx-background-color: white;
-fx-padding: 10 16 10 16;
-fx-font-size: 12;
.options-list-item:first {
-fx-border-width: 0;
}
.options-list-item-expand-button {