Inceptum/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/util/ListIndex.java

193 lines
7.8 KiB
Java

package io.gitlab.jfronny.inceptum.gtk.util;
import io.github.jwharm.javagi.*;
import io.gitlab.jfronny.inceptum.gtk.GtkMain;
import io.gitlab.jfronny.inceptum.gtk.callback.*;
import org.gtk.gio.ListModel;
import org.gtk.gio.ListModelInterface;
import org.gtk.glib.Type;
import org.gtk.gobject.*;
import org.gtk.gtk.*;
import java.lang.foreign.*;
import java.lang.invoke.VarHandle;
public class ListIndex extends GObject {
private static final int PROP_ITEM_TYPE = 1;
private static final String PROP_NAME = "item-type";
private static final String TYPE_NAME = "ListIndex";
private static final Type PARENT_TYPE = GObject.getType();
private static final MemoryLayout memoryLayout = MemoryLayout.structLayout(
GObject.getMemoryLayout().withName("parent_instance"),
Interop.valueLayout.C_INT.withName("index"),
Interop.valueLayout.C_INT.withName("size")
).withName(TYPE_NAME);
private static Type type;
public static Type getType() {
if (type == null) {
// Register the new gtype
type = GObjects.typeRegisterStaticSimple(
PARENT_TYPE,
TYPE_NAME,
(short) ObjectClass.getMemoryLayout().byteSize(),
classInit,
(short) memoryLayout.byteSize(),
instanceInit,
TypeFlags.NONE
);
GObjects.typeAddInterfaceStatic(type, ListModel.getType(), InterfaceInfo.builder()
.setInterfaceInit(interfaceInit)
.setInterfaceData(null)
.setInterfaceFinalize(null)
.build());
}
return type;
}
private static final VarHandle index = memoryLayout.varHandle(MemoryLayout.PathElement.groupElement("index"));
private static final VarHandle size = memoryLayout.varHandle(MemoryLayout.PathElement.groupElement("size"));
public static ListIndex castFrom(GObject gobject) {
if (GObjects.typeCheckInstanceIsA(TypeInstance.fromAddress.marshal(gobject.handle(), Ownership.NONE), getType())) {
return new ListIndex(gobject.handle(), gobject.yieldOwnership());
} else {
throw new ClassCastException("Object type is not an instance of ListIndex");
}
}
public static final Marshal<Addressable, ListIndex> fromAddress = (input, ownership) -> input.equals(MemoryAddress.NULL) ? null : new ListIndex(input, ownership);
protected ListIndex(Addressable address, Ownership ownership) {
super(address, ownership);
}
public ListIndex(int size) {
this();
setSizeIntenal(size);
}
public ListIndex() {
super(new GObject(getType(), PROP_NAME, getType()).handle(),
Ownership.FULL);
}
private static final InstanceInitFunc instanceInit = (instance, gClass) -> fromAddress.marshal(instance.handle(), Ownership.NONE).initInstance();
private void initInstance() {
setIndex(0);
setSizeIntenal(0);
}
private static TypeClass parentClass = null;
private static final DisposeCallback instanceDispose = pointer -> {
if (parentClass == null) System.out.println("ListIndex::instanceDispose (no parent)");
else {
InteropException ie = new InteropException("Could not dispose ListIndex");
GtkMain.schedule(() -> {
try {
var func = (MemoryAddress) ObjectClass.getMemoryLayout()
.varHandle(MemoryLayout.PathElement.groupElement("dispose"))
.get(MemorySegment.ofAddress(parentClass.handle().address(), ObjectClass.getMemoryLayout().byteSize(), Interop.getScope()));
var linked = Linker.nativeLinker().downcallHandle(func, DisposeCallback.DESCRIPTOR);
linked.invoke(pointer);
} catch (Throwable e) {
throw (InteropException) ie.initCause(e);
}
});
}
};
private static final SetPropertyCallback setProperty = (object, propertyId, value, paramSpec) -> {
if (propertyId != PROP_ITEM_TYPE) System.out.println("ListIndex::setProperty (unknown property)");
};
private static final GetPropertyCallback getProperty = (object, propertyId, value, paramSpec) -> {
if (propertyId == PROP_ITEM_TYPE) value.setGtype(getType());
else System.out.println("ListIndex::getProperty (unknown property)");
};
private static final ClassInitFunc classInit = (klass, data) -> {
System.out.println("ListIndex::classInit");
parentClass = klass.peekParent();
ObjectClass objectClass = ObjectClass.fromAddress.marshal(GObjects.typeCheckClassCast(klass, PARENT_TYPE).handle(), Ownership.NONE);
objectClass.setDispose(instanceDispose.toCallback());
objectClass.setGetProperty(getProperty.toCallback());
objectClass.setSetProperty(setProperty.toCallback());
ParamSpec paramType = GObjects.paramSpecGtype(PROP_NAME, "", "", PARENT_TYPE,
ParamFlags.CONSTRUCT
.or(ParamFlags.READWRITE,
ParamFlags.STATIC_NAME,
ParamFlags.STATIC_NICK,
ParamFlags.STATIC_BLURB)
);
objectClass.installProperty(PROP_ITEM_TYPE, paramType);
};
private static final GetItemTypeCallback getItemType = address -> {
System.out.println("ListIndex::getItemType");
return getType().getValue();
};
private static final GetNItemsCallback getNItems = address -> fromAddress.marshal(address, Ownership.NONE).getSize();
private static final GetItemCallback getItem = (inst, position) -> {
ListIndex item = fromAddress.marshal(inst, Ownership.NONE).getItem(position);
if (item == null) return MemoryAddress.NULL;
return item.handle();
};
public ListIndex getItem(int position) {
if (position >= getSize() || position <= -1) return null;
ListIndex result = new ListIndex(getSize());
result.setIndex(position);
return result;
}
private static final InterfaceInitFunc interfaceInit = (iface, data) -> {
System.out.println("ListIndex::interfaceInit");
ListModelInterface lmi = ListModelInterface.fromAddress.marshal(iface.handle(), Ownership.NONE);
lmi.setGetItem(getItem.toCallback());
lmi.setGetNItems(getNItems.toCallback());
lmi.setGetItemType(getItemType.toCallback());
};
public int getIndex() {
return (int) ListIndex.index.get(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()));
}
public void setIndex(int index) {
ListIndex.index.set(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()), index);
}
public int getSize() {
return (int) ListIndex.size.get(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()));
}
public void setSize(int size) {
int oldSize = getSize();
setSizeIntenal(size);
asListModel().itemsChanged(0, oldSize, size);
}
private void setSizeIntenal(int size) {
ListIndex.size.set(MemorySegment.ofAddress((MemoryAddress) handle(), memoryLayout.byteSize(), Interop.getScope()), size);
}
public ListModel asListModel() {
return ListModel.castFrom(this);
}
public SingleSelection inSingleSelection() {
return new SingleSelection(asListModel());
}
public SelectionModel inSelectionModel() {
return SelectionModel.castFrom(inSingleSelection());
}
public static int toIndex(ListItem item) {
return castFrom(item.getItem()).getIndex();
}
}