162 lines
6.1 KiB
Java
162 lines
6.1 KiB
Java
package io.gitlab.jfronny.inceptum.gtk.window;
|
|
|
|
import ch.bailu.gtk.GTK;
|
|
import ch.bailu.gtk.adw.Clamp;
|
|
import ch.bailu.gtk.adw.StatusPage;
|
|
import ch.bailu.gtk.bridge.ListIndex;
|
|
import ch.bailu.gtk.gio.Menu;
|
|
import ch.bailu.gtk.glib.Glib;
|
|
import ch.bailu.gtk.gtk.*;
|
|
import ch.bailu.gtk.type.Str;
|
|
import io.gitlab.jfronny.inceptum.common.*;
|
|
import io.gitlab.jfronny.inceptum.gtk.GtkMenubar;
|
|
import io.gitlab.jfronny.inceptum.gtk.control.InstanceGridEntryFactory;
|
|
import io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory;
|
|
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder;
|
|
import io.gitlab.jfronny.inceptum.gtk.util.I18n;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
|
|
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.nio.file.*;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import static java.nio.file.StandardWatchEventKinds.*;
|
|
|
|
public class MainWindow extends ApplicationWindow {
|
|
private final Button listButton;
|
|
private final Button gridButton;
|
|
private final Stack stack;
|
|
private final StatusPage empty;
|
|
private final Clamp listView;
|
|
private final GridView gridView;
|
|
private final List<Instance> instanceList;
|
|
private final ListIndex instanceListIndex;
|
|
|
|
public MainWindow(Application app) {
|
|
super(app);
|
|
|
|
HeaderBar header = new HeaderBar();
|
|
Button newButton = new Button();
|
|
newButton.setIconName(new Str("list-add-symbolic"));
|
|
newButton.onClicked(NewInstanceWindow::createAndShow);
|
|
|
|
MenuButton accountsButton = new MenuButton();
|
|
accountsButton.setIconName(new Str("avatar-default-symbolic"));
|
|
accountsButton.setPopover(GtkMenubar.accountsMenu.asPopover());
|
|
|
|
listButton = new Button();
|
|
listButton.setIconName(new Str("view-list-symbolic"));
|
|
listButton.onClicked(() -> {
|
|
InceptumConfig.listView = true;
|
|
InceptumConfig.saveConfig();
|
|
generateWindowBody();
|
|
});
|
|
|
|
gridButton = new Button();
|
|
gridButton.setIconName(new Str("view-grid-symbolic"));
|
|
gridButton.onClicked(() -> {
|
|
InceptumConfig.listView = false;
|
|
InceptumConfig.saveConfig();
|
|
generateWindowBody();
|
|
});
|
|
|
|
//TODO search button like boxes
|
|
|
|
MenuBuilder uiMenu = new MenuBuilder(app, new Menu(), "hamburger");
|
|
uiMenu.button("support", () -> Utils.openWebBrowser(new URI("https://gitlab.com/jfmods/inceptum/-/issues")));
|
|
uiMenu.button("preferences", () -> {}); //TODO preferences UI inspired by boxes
|
|
uiMenu.button("about", AboutWindow::createAndShow);
|
|
MenuButton menuButton = new MenuButton();
|
|
menuButton.setIconName(new Str("open-menu-symbolic"));
|
|
menuButton.setPopover(uiMenu.asPopover());
|
|
|
|
header.packStart(newButton);
|
|
|
|
header.packEnd(menuButton);
|
|
header.packEnd(gridButton);
|
|
header.packEnd(listButton);
|
|
header.packEnd(accountsButton);
|
|
|
|
instanceList = new ArrayList<>();
|
|
instanceListIndex = new ListIndex();
|
|
|
|
listView = new Clamp();
|
|
listView.setMaximumSize(900);
|
|
listView.setChild(new ListView(instanceListIndex.inSelectionModel(), new InstanceListEntryFactory(instanceList)));
|
|
gridView = new GridView(instanceListIndex.inSelectionModel(), new InstanceGridEntryFactory(instanceList));
|
|
empty = new StatusPage();
|
|
empty.setTitle(I18n.str("main.empty.title"));
|
|
empty.setDescription(I18n.str("main.empty.description"));
|
|
//TODO empty.setIconName(new Str());
|
|
stack = new Stack();
|
|
stack.addChild(listView);
|
|
stack.addChild(gridView);
|
|
|
|
ScrolledWindow scroll = new ScrolledWindow();
|
|
scroll.setPolicy(PolicyType.NEVER, PolicyType.AUTOMATIC);
|
|
scroll.setChild(stack);
|
|
|
|
setDefaultSize(360, 720);
|
|
setTitle(new Str("Inceptum"));
|
|
setTitlebar(header);
|
|
setShowMenubar(GTK.FALSE);
|
|
setChild(scroll);
|
|
|
|
generateWindowBody();
|
|
//TODO DropTarget to add mods/instances
|
|
|
|
try {
|
|
setupDirWatcher();
|
|
} catch (IOException e) {
|
|
Utils.LOGGER.error("Could not set up watch service, live updates of the instance dir will be unavailable", e);
|
|
}
|
|
}
|
|
|
|
private void setupDirWatcher() throws IOException { //TODO test (including after lock state change)
|
|
WatchService ws = FileSystems.getDefault().newWatchService();
|
|
MetaHolder.INSTANCE_DIR.register(ws, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE);
|
|
int source = Glib.idleAdd(user_data -> {
|
|
//TODO watch instance dirs for locks
|
|
WatchKey key = ws.poll();
|
|
boolean instancesChanged = false;
|
|
if (key != null) {
|
|
for (WatchEvent<?> event : key.pollEvents()) {
|
|
if (event.context() instanceof Path p) {
|
|
p = MetaHolder.INSTANCE_DIR.resolve(p);
|
|
instancesChanged |= Files.exists(p.resolve("instance.json"));
|
|
}
|
|
}
|
|
}
|
|
if (instancesChanged) generateWindowBody();
|
|
return GTK.TRUE;
|
|
}, null);
|
|
onCloseRequest(() -> {
|
|
try {
|
|
ws.close();
|
|
} catch (IOException ignored) {
|
|
}
|
|
Glib.sourceRemove(source);
|
|
return GTK.FALSE;
|
|
});
|
|
}
|
|
|
|
private void generateWindowBody() {
|
|
if (listButton != null) listButton.setVisible(GTK.is(!InceptumConfig.listView));
|
|
if (gridButton != null) gridButton.setVisible(GTK.is(InceptumConfig.listView));
|
|
try {
|
|
instanceList.clear();
|
|
InstanceList.forEach(instanceList::add);
|
|
instanceListIndex.setSize(instanceList.size());
|
|
|
|
if (InstanceList.isEmpty()) stack.setVisibleChild(empty);
|
|
else if (InceptumConfig.listView) stack.setVisibleChild(listView);
|
|
else stack.setVisibleChild(gridView);
|
|
} catch (IOException e) {
|
|
Utils.LOGGER.error("Could not generate window body", e);
|
|
}
|
|
}
|
|
}
|