From b99534ebdfd7b447fe0e4e8f648622911de44b39 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Sat, 6 Apr 2024 02:35:06 -0400 Subject: [PATCH] Add WIP color sliders --- puter-gui.json | 3 +- src/UI/UIWindowThemeDialog.js | 110 ++++++++++++++++++++++++++++++++++ src/css/style.css | 33 +++++++++- src/css/theme.css | 7 +++ src/definitions.js | 3 + src/initgui.js | 27 +++++++++ src/services/ThemeService.js | 34 +++++++++++ 7 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 src/UI/UIWindowThemeDialog.js create mode 100644 src/css/theme.css create mode 100644 src/definitions.js create mode 100644 src/services/ThemeService.js diff --git a/puter-gui.json b/puter-gui.json index 1d3579bc9..af7691d9f 100644 --- a/puter-gui.json +++ b/puter-gui.json @@ -19,7 +19,8 @@ "css_paths": [ "/css/normalize.css", "/lib/jquery-ui-1.13.2/jquery-ui.min.css", - "/css/style.css" + "/css/style.css", + "/css/theme.css" ], "js_paths": [ "/src/initgui.js", diff --git a/src/UI/UIWindowThemeDialog.js b/src/UI/UIWindowThemeDialog.js new file mode 100644 index 000000000..3eaead6c4 --- /dev/null +++ b/src/UI/UIWindowThemeDialog.js @@ -0,0 +1,110 @@ +import UIWindow from "./UIWindow.js"; + +const UIWindowThemeDialog = async function UIWindowThemeDialog () { + const services = globalThis.services; + const svc_theme = services.get('theme'); + + const w = await UIWindow({ + title: null, + icon: null, + uid: null, + is_dir: false, + message: 'message', + // body_icon: options.body_icon, + // backdrop: options.backdrop ?? false, + is_resizable: false, + is_droppable: false, + has_head: true, + stay_on_top: true, + selectable_body: false, + draggable_body: true, + allow_context_menu: false, + show_in_taskbar: false, + window_class: 'window-alert', + dominant: true, + body_content: '', + width: 350, + // parent_uuid: options.parent_uuid, + // ...options.window_options, + window_css:{ + height: 'initial', + }, + body_css: { + width: 'initial', + padding: '20px', + 'background-color': 'rgba(231, 238, 245, .95)', + 'backdrop-filter': 'blur(3px)', + } + }); + const w_body = w.querySelector('.window-body'); + + const Slider = ({ name, label, min, max, initial, step }) => { + label = label ?? name; + const wrap = document.createElement('div'); + const el = document.createElement('input'); + wrap.appendChild(el); + el.type = 'range'; + el.min = min; + el.max = max; + el.defaultValue = initial ?? min; + el.step = step ?? 1; + el.classList.add('theme-dialog-slider'); + const label_el = document.createElement('label'); + label_el.textContent = label; + wrap.appendChild(label_el); + + return { + appendTo (parent) { + parent.appendChild(wrap); + return this; + }, + onChange (cb) { + el.addEventListener('input', e => { + e.meta = { label }; + cb(e); + }); + return this; + }, + }; + }; + + const state = {}; + + const slider_ch = (e) => { + state[e.meta.label] = e.target.value; + svc_theme.apply(state); + }; + + Slider({ + name: 'hue', min: 0, max: 360, + initial: svc_theme.get('hue'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'sat', min: 0, max: 100, + initial: svc_theme.get('sat'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'lig', min: 0, max: 100, + initial: svc_theme.get('lig'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + Slider({ + name: 'alpha', min: 0, max: 1, step: 0.01, + initial: svc_theme.get('alpha'), + }) + .appendTo(w_body) + .onChange(slider_ch) + ; + + return {}; +} + +export default UIWindowThemeDialog; diff --git a/src/css/style.css b/src/css/style.css index 8553d8fec..816311152 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -3618,4 +3618,35 @@ label { .confirm-user-deletion-password{ width: 100%; margin-bottom: 20px; -} \ No newline at end of file +} + +.theme-dialog-slider { + --webkit-appearance: none; + width: 100%; + height: 25px; + background: #d3d3d3; + outline: none; + opacity: 0.7; + --webkit-transition: .2s; + transition: opacity .2s; +} + +.theme-dialog-slider:hover { + opacity: 1; +} + +.theme-dialog-slider::-webkit-slider-thumb { + --webkit-appearance: none; + appearance: none; + width: 25px; + height: 25px; + background: #04AA6D; + cursor: pointer; +} + +.theme-dialog-slider::-moz-range-thumb { + width: 25px; + height: 25px; + background: #04AA6D; + cursor: pointer; +} diff --git a/src/css/theme.css b/src/css/theme.css new file mode 100644 index 000000000..3438204d6 --- /dev/null +++ b/src/css/theme.css @@ -0,0 +1,7 @@ +/* used for pseudo-stylesheet */ + +/* + +hue = 320; ss.addRule('.taskbar, .window-head, .window-sidebar', `background-color: hsl(${hue}, 65.1%, 70.78%)`) + +*/ \ No newline at end of file diff --git a/src/definitions.js b/src/definitions.js new file mode 100644 index 000000000..8bca70ef9 --- /dev/null +++ b/src/definitions.js @@ -0,0 +1,3 @@ +export class Service { + // +}; diff --git a/src/initgui.js b/src/initgui.js index 3e5f340e7..c199c288d 100644 --- a/src/initgui.js +++ b/src/initgui.js @@ -34,6 +34,31 @@ import update_last_touch_coordinates from './helpers/update_last_touch_coordinat import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js'; import PuterDialog from './UI/PuterDialog.js'; import determine_active_container_parent from './helpers/determine_active_container_parent.js'; +import { ThemeService } from './services/ThemeService.js'; +import UIWindowThemeDialog from './UI/UIWindowThemeDialog.js'; + +const launch_services = async function () { + const services_l_ = []; + const services_m_ = {}; + globalThis.services = { + get: (name) => services_m_[name], + }; + + const register = (name, instance) => { + services_l_.push([name, instance]); + services_m_[name] = instance; + } + + register('theme', new ThemeService()); + + for (const [_, instance] of services_l_) { + await instance._init(); + } + + setTimeout(() => { + UIWindowThemeDialog(); + }, 1000); +}; window.initgui = async function(){ let url = new URL(window.location); @@ -1947,6 +1972,8 @@ window.initgui = async function(){ // go to home page window.location.replace("/"); }); + + await launch_services(); } function requestOpenerOrigin() { diff --git a/src/services/ThemeService.js b/src/services/ThemeService.js new file mode 100644 index 000000000..01c2903ee --- /dev/null +++ b/src/services/ThemeService.js @@ -0,0 +1,34 @@ +import { Service } from "../definitions.js"; + +export class ThemeService extends Service { + async _init () { + this.state = { + sat: 100, + hue: 200, + lig: 70, + alpha: 1, + }; + this.ss = new CSSStyleSheet(); + document.adoptedStyleSheets.push(this.ss); + } + + apply (values) { + this.state = { + ...this.state, + ...values, + }; + this.reload_(); + } + + get (key) { return this.state[key]; } + + reload_ () { + // debugger; + const s = this.state; + this.ss.replace(` + .taskbar, .window-head, .window-sidebar { + background-color: hsla(${s.hue}, ${s.sat}%, ${s.lig}%, ${s.alpha}); + } + `) + } +}