citadel-realms/js/ColorSchemeChooser.js
2024-11-12 17:26:26 -05:00

177 lines
5.7 KiB
JavaScript

var _a;
import Adw from 'gi://Adw';
import GObject from 'gi://GObject';
import GLib from 'gi://GLib';
import Gdk from 'gi://Gdk?version=4.0';
import Gtk from 'gi://Gtk?version=4.0';
import { ColorSchemeModel } from './ColorSchemeModel.js';
class PreviewRenderer {
constructor(theme) {
this.theme = theme;
this.buffer = '';
}
colorAttrib(name, color) {
this.buffer += ` ${name}='${color}'`;
}
colorSpan(fg, bg = null) {
this.buffer += '<span';
if (fg) {
this.colorAttrib("foreground", fg);
}
if (bg) {
this.colorAttrib("background", bg);
}
this.buffer += ">";
}
endSpan() {
this.buffer += '</span>';
}
nl() {
this.buffer += ' \n ';
return this;
}
print(idx, text) {
let s = GLib.markup_escape_text(text, text.length);
let c = this.theme.terminal_palette_color(idx);
this.colorSpan(c);
this.buffer += s;
this.endSpan();
return this;
}
vtype(text) {
return this.print(3, text);
}
konst(text) {
return this.print(1, text);
}
func(text) {
return this.print(4, text);
}
string(text) {
return this.print(2, text);
}
keyword(text) {
return this.print(5, text);
}
comment(text) {
return this.print(8, text);
}
text(text) {
let color = this.theme.terminal_foreground();
this.colorSpan(color);
this.buffer += text;
this.endSpan();
return this;
}
renderPreview() {
let name = this.theme.name;
this.nl()
.comment('/**').nl()
.comment(' * An example of how this color scheme').nl()
.comment(' * might look in a text editor with syntax').nl()
.comment(' * highlighting.').nl()
.comment(' */').nl()
.nl()
.func('#include ').string('<stdio.h>').nl()
.func('#include ').string('<stdlib.h>').nl()
.nl()
.vtype('static char').text(' theme[] = ').string(`"${name}"`).text(';').nl()
.nl()
.vtype('int').text(' main(').vtype('int').text(' argc, ').vtype('char').text(' **argv) {').nl()
.text(' printf(').string('"Hello, ').keyword('%s').text('!').keyword('\\n').string('"').text(', theme);').nl()
.text(' exit(').konst('0').text(');').nl()
.text('}')
.nl();
return this.buffer;
}
}
export class ColorSchemeChooser extends Adw.NavigationPage {
addExpandToggleShortcut(keyval) {
let trigger = Gtk.KeyvalTrigger.new(keyval, Gdk.ModifierType.NO_MODIFIER_MASK);
let action = Gtk.CallbackAction.new((expander) => expander.activate_action('listitem.toggle-expand', null));
Gtk.TreeExpander.add_shortcut(Gtk.Shortcut.new(trigger, action));
}
constructor() {
super();
this.model = new ColorSchemeModel();
this._previewLabel.add_css_class("preview");
this.css_provider = new Gtk.CssProvider();
const display = Gdk.Display.get_default();
if (display) {
Gtk.StyleContext.add_provider_for_display(display, this.css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
}
this.addExpandToggleShortcut(Gdk.KEY_space);
this.addExpandToggleShortcut(Gdk.KEY_l);
this._colorList.connect('activate', () => {
this.previewSelectedTheme();
});
this._colorList.single_click_activate = true;
this._colorList.model = this.model.selection;
const keyController = new Gtk.EventControllerKey();
keyController.connect('key-pressed', (_, keyval) => {
switch (keyval) {
case Gdk.KEY_j:
case Gdk.KEY_Down:
this.nextScheme();
break;
case Gdk.KEY_k:
case Gdk.KEY_Up:
this.prevScheme();
break;
}
});
this._colorList.add_controller(keyController);
}
nextScheme() {
let pos = this.model.changeSelected(1);
if (pos) {
this._colorList.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, null);
}
}
prevScheme() {
let pos = this.model.changeSelected(-1);
if (pos) {
this._colorList.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, null);
}
}
selectTheme(id) {
const DEFAULT_THEME = '3024';
let row = this.model.searchId(id !== null && id !== void 0 ? id : DEFAULT_THEME);
if (row) {
let pos = row.get_position();
this.model.selectPosition(pos);
this._colorList.scroll_to(pos, Gtk.ListScrollFlags.SELECT | Gtk.ListScrollFlags.FOCUS, null);
this.previewSelectedTheme();
}
}
getSelectedTheme() {
return this.model.selectedTheme();
}
previewSelectedTheme() {
let theme = this.model.selectedTheme();
if (theme) {
this.setBackgroundColor(theme);
let renderer = new PreviewRenderer(theme);
// @ts-ignore
this._previewLabel.label = renderer.renderPreview();
}
}
setBackgroundColor(theme) {
let css = `
label.preview {
background-color: ${theme.terminal_background()};
font-family: monospace;
font-size: 14pt;
}`;
this.css_provider.load_from_string(css);
}
}
_a = ColorSchemeChooser;
(() => {
GObject.registerClass({
GTypeName: 'ColorSchemeChooser',
Template: 'resource:///com/subgraph/citadel/Realms/ui/ColorSchemeChooser.ui',
InternalChildren: ['colorList', 'previewLabel'],
}, _a);
})();