From 07656b404ff1161fd47fb305bf2f837ab69c7150 Mon Sep 17 00:00:00 2001 From: sthag Date: Sun, 26 Oct 2025 15:19:14 +0100 Subject: [PATCH 01/12] feat: Introduce liquid templates --- .eleventy.js | 14 ++++++++++---- source/screens/hello.md | 10 ++++++++++ source/templates/hippie/world.liquid | 11 +++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 source/screens/hello.md create mode 100644 source/templates/hippie/world.liquid diff --git a/.eleventy.js b/.eleventy.js index 98082aa..3da1568 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,6 +1,14 @@ module.exports = function (eleventyConfig) { // eleventyConfig.addPlugin(EleventyHtmlBasePlugin); + eleventyConfig.setLiquidOptions({ + // greedy: false, + // trimOutputLeft: true, + // trimOutputRight: true, + // trimTagLeft: true, + // trimTagRight : true, + }); + eleventyConfig.setNunjucksEnvironmentOptions({ // throwOnUndefined: true, trimBlocks: true @@ -43,9 +51,7 @@ module.exports = function (eleventyConfig) { includes: "../templates", data: "../data" }, - markdownTemplateEngine: "njk", - htmlTemplateEngine: "njk", - templateFormats: ["html", "njk", "md"], + templateFormats: ["html", "liquid", "njk", "md"] // pathPrefix: './demo/' - } + }; }; diff --git a/source/screens/hello.md b/source/screens/hello.md new file mode 100644 index 0000000..d6ff3be --- /dev/null +++ b/source/screens/hello.md @@ -0,0 +1,10 @@ +--- +title: "Hello World" +tags: + - demoIndex +layout: hippie/world.liquid +--- + +# {{ title }} + +This is a simple example for a *screen* written in Markdown, using Liquid *templates*. \ No newline at end of file diff --git a/source/templates/hippie/world.liquid b/source/templates/hippie/world.liquid new file mode 100644 index 0000000..ca935dc --- /dev/null +++ b/source/templates/hippie/world.liquid @@ -0,0 +1,11 @@ + + + + + {{ title }} + + + +{{ content }} + + \ No newline at end of file From afc733f4d464bdeaccf4ad8949ac2189f3349cd8 Mon Sep 17 00:00:00 2001 From: sthag Date: Sun, 26 Oct 2025 15:29:12 +0100 Subject: [PATCH 02/12] feat: Replace default screen using liquid instead of nunjucks --- source/screens/demo/pages/default.liquid | 18 +++++++++ source/screens/demo/pages/default.njk | 21 ----------- source/screens/{ => demo/pages}/hello.md | 2 - source/templates/hippie/default.liquid | 37 +++++++++++++++++++ source/templates/hippie/partials/links.liquid | 3 ++ source/templates/hippie/partials/meta.liquid | 7 ++++ 6 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 source/screens/demo/pages/default.liquid delete mode 100644 source/screens/demo/pages/default.njk rename source/screens/{ => demo/pages}/hello.md (76%) create mode 100644 source/templates/hippie/default.liquid create mode 100644 source/templates/hippie/partials/links.liquid create mode 100644 source/templates/hippie/partials/meta.liquid diff --git a/source/screens/demo/pages/default.liquid b/source/screens/demo/pages/default.liquid new file mode 100644 index 0000000..026c6da --- /dev/null +++ b/source/screens/demo/pages/default.liquid @@ -0,0 +1,18 @@ +--- +title: "Default" +--- +{% assign pageBase = "../" -%} +{% assign pageId = page.fileSlug -%} +{% assign pageClass = "default" -%} +{% assign bodyClass = "default" -%} +{%- layout "hippie/default.liquid" %} + +{% block title %}{{ title }}{% endblock %} + +{% block script %} +{{ block.super -}} + +{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/pages/default.njk b/source/screens/demo/pages/default.njk deleted file mode 100644 index a898098..0000000 --- a/source/screens/demo/pages/default.njk +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Default ---- -{% set pageBase = "../" %} -{% set pageId = page.fileSlug %} - -{% extends "hippie/_default.njk" %} - -{% block title %}{{ title }}{% endblock %} - -{% block head %} -{{ super() }} -{% endblock %} - -{% block body %} - -{% endblock %} - -{% block script %} -{{ super() }} -{% endblock %} diff --git a/source/screens/hello.md b/source/screens/demo/pages/hello.md similarity index 76% rename from source/screens/hello.md rename to source/screens/demo/pages/hello.md index d6ff3be..09a9406 100644 --- a/source/screens/hello.md +++ b/source/screens/demo/pages/hello.md @@ -1,7 +1,5 @@ --- title: "Hello World" -tags: - - demoIndex layout: hippie/world.liquid --- diff --git a/source/templates/hippie/default.liquid b/source/templates/hippie/default.liquid new file mode 100644 index 0000000..cfd5417 --- /dev/null +++ b/source/templates/hippie/default.liquid @@ -0,0 +1,37 @@ + +{% if pageId %} +{%- capture idAttr %} id="{{ pageId }}"{% endcapture -%} +{% endif -%} +{% if pageClass %} + {%- capture classAttr %} class="{{ pageClass }}"{% endcapture -%} +{% endif -%} +{% if bodyClass %} + {%- capture bodyClassAttr %} class="{{ bodyClass }}"{% endcapture -%} +{% endif -%} + + + + {% block head %} + + {{- hippie.titlePrefix -}} + {% block title %}{% endblock -%} + {{ hippie.titlePostfix -}} + + {% block meta -%} + {% render "hippie/partials/meta.liquid" %} + {% endblock -%} + {% block links -%} + {% render "hippie/partials/links.liquid" %} + {% endblock -%} + {% endblock -%} + + + +{%- block body %}{% endblock -%} +{% block script -%} + +{% endblock -%} + + \ No newline at end of file diff --git a/source/templates/hippie/partials/links.liquid b/source/templates/hippie/partials/links.liquid new file mode 100644 index 0000000..c1a8845 --- /dev/null +++ b/source/templates/hippie/partials/links.liquid @@ -0,0 +1,3 @@ +{% comment %}{% endcomment %} + + diff --git a/source/templates/hippie/partials/meta.liquid b/source/templates/hippie/partials/meta.liquid new file mode 100644 index 0000000..fa0516e --- /dev/null +++ b/source/templates/hippie/partials/meta.liquid @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 46988576a943f471a897ae40a7281b2f01b4c4da Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 20:40:18 +0100 Subject: [PATCH 03/12] fix: Typo in css class --- source/screens/demo/components.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/screens/demo/components.njk b/source/screens/demo/components.njk index a6c1bfc..f327b4c 100644 --- a/source/screens/demo/components.njk +++ b/source/screens/demo/components.njk @@ -25,7 +25,7 @@ tags:

Telefone und größer

Nur Telefone

-

Nur Schreibtafeln hochkant

+

Nur Schreibtafeln hochkant

Schreibtafeln und größer

Schreibtafeln im Querformat

Schreibtafeln quer und größer

From 6b644ca9f38f10f027d05009809a91d2662e6536 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 20:41:38 +0100 Subject: [PATCH 04/12] feat: Add macro for frame status bar --- source/screens/demo/examples/ui/explorer.njk | 14 ++------------ source/templates/hippie/macros/_io.njk | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/source/screens/demo/examples/ui/explorer.njk b/source/screens/demo/examples/ui/explorer.njk index 72de77a..c54ea0a 100755 --- a/source/screens/demo/examples/ui/explorer.njk +++ b/source/screens/demo/examples/ui/explorer.njk @@ -12,7 +12,7 @@ tags:
-
- - -
+ {{ io.statusBar() }} {{ io.frameFooter('mode-bar') }} diff --git a/source/templates/hippie/macros/_io.njk b/source/templates/hippie/macros/_io.njk index 36a3b9e..f9a7300 100644 --- a/source/templates/hippie/macros/_io.njk +++ b/source/templates/hippie/macros/_io.njk @@ -32,4 +32,18 @@ +{% endmacro %} + +{% macro statusBar(title) %} +
+ + +
{% endmacro %} \ No newline at end of file From c77bcd8bdccdcd224247c96ac60b1d04ff56ac82 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 20:51:17 +0100 Subject: [PATCH 05/12] feat: Replace ui drag screen with liquid template - Recreate io macros as liquid partials - Add app template based on default - Drag screen uses app.liquid layout instead of _app_frame.njk --- source/screens/demo/examples/ui/drag.liquid | 48 ++++++++++++++++++ source/screens/demo/examples/ui/drag.njk | 50 ------------------- source/templates/hippie/app.liquid | 40 +++++++++++++++ .../hippie/partials/frame-header.liquid | 20 ++++++++ .../hippie/partials/frame-mode.liquid | 10 ++++ .../hippie/partials/frame-status.liquid | 11 ++++ 6 files changed, 129 insertions(+), 50 deletions(-) create mode 100755 source/screens/demo/examples/ui/drag.liquid delete mode 100755 source/screens/demo/examples/ui/drag.njk create mode 100644 source/templates/hippie/app.liquid create mode 100644 source/templates/hippie/partials/frame-header.liquid create mode 100644 source/templates/hippie/partials/frame-mode.liquid create mode 100644 source/templates/hippie/partials/frame-status.liquid diff --git a/source/screens/demo/examples/ui/drag.liquid b/source/screens/demo/examples/ui/drag.liquid new file mode 100755 index 0000000..aeceed7 --- /dev/null +++ b/source/screens/demo/examples/ui/drag.liquid @@ -0,0 +1,48 @@ +--- +title: Drag +tags: +- ui +--- +{% layout "hippie/app.liquid" %} + +{% block body %} +
+ +
+
+
+
+
+ {% render 'hippie/partials/frame-header.liquid' %} +
+ {% render 'hippie/partials/frame-mode.liquid' %} +
+
+
+{% endblock %} + +{%- block script %} + + +{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/examples/ui/drag.njk b/source/screens/demo/examples/ui/drag.njk deleted file mode 100755 index ecd3001..0000000 --- a/source/screens/demo/examples/ui/drag.njk +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Drag -tags: - - ui ---- -{% set pageId = page.fileSlug %} - -{% extends "hippie/_app_frame.njk" %} - -{% block body %} -
- -
-
-
-
-
- {{ io.frameHeader('title-bar') }} -
- {{ io.frameFooter('mode-bar') }} -
-
-
-{% endblock %} - -{%- block script %} - - -{% endblock %} \ No newline at end of file diff --git a/source/templates/hippie/app.liquid b/source/templates/hippie/app.liquid new file mode 100644 index 0000000..58ca863 --- /dev/null +++ b/source/templates/hippie/app.liquid @@ -0,0 +1,40 @@ +{% assign pageBase = "../../../" -%} +{% assign pageId = page.fileSlug -%} +{% assign pageClass = "html_ui" -%} +{%- layout "hippie/default.liquid" %} + +{% block title %}{{ title }}{% endblock %} + +{% block links %} +{{ block.super -}} + + +{% endblock %} + +{% block script %} +{{ block.super -}} + + + + + +{% endblock %} \ No newline at end of file diff --git a/source/templates/hippie/partials/frame-header.liquid b/source/templates/hippie/partials/frame-header.liquid new file mode 100644 index 0000000..14d04bc --- /dev/null +++ b/source/templates/hippie/partials/frame-header.liquid @@ -0,0 +1,20 @@ +
+ + +
\ No newline at end of file diff --git a/source/templates/hippie/partials/frame-mode.liquid b/source/templates/hippie/partials/frame-mode.liquid new file mode 100644 index 0000000..4e87985 --- /dev/null +++ b/source/templates/hippie/partials/frame-mode.liquid @@ -0,0 +1,10 @@ +
+ + +
\ No newline at end of file diff --git a/source/templates/hippie/partials/frame-status.liquid b/source/templates/hippie/partials/frame-status.liquid new file mode 100644 index 0000000..98c94f9 --- /dev/null +++ b/source/templates/hippie/partials/frame-status.liquid @@ -0,0 +1,11 @@ +
+ + +
\ No newline at end of file From ff5d4bd3eba5393e43fa9e79674817e944bf53a5 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 21:15:32 +0100 Subject: [PATCH 06/12] feat: Add jquery dependency - Add jquery version 3.7.1 - Remove external script resource from app template - Add eleventy passthrough to build/vendor --- .eleventy.js | 4 ++++ package-lock.json | 7 +++++++ package.json | 3 ++- source/templates/hippie/app.liquid | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.eleventy.js b/.eleventy.js index 3da1568..00dded1 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -40,6 +40,10 @@ module.exports = function (eleventyConfig) { eleventyConfig.addPassthroughCopy("vendor"); eleventyConfig.addPassthroughCopy({"node_modules/bootstrap-icons": "vendor/bootstrap-icons"}); + eleventyConfig.addPassthroughCopy({ + "node_modules/jquery/dist/jquery.min.js": "vendor", + "node_modules/jquery/dist/jquery.min.map": "vendor" + }); // eleventyConfig.addPassthroughCopy({"node_modules/normalize.css/normalize.css": "vendor/normalize.css"}); eleventyConfig.addWatchTarget("./source/style/"); diff --git a/package-lock.json b/package-lock.json index 73baa18..1fc8cd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@11ty/eleventy": "^2.0.1", "bootstrap-icons": "^1.13.1", + "jquery": "^3.7.1", "sass": "^1.93.0" }, "devDependencies": { @@ -1583,6 +1584,12 @@ "node": ">=10" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", diff --git a/package.json b/package.json index d2759a8..3dc6f91 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dependencies": { "@11ty/eleventy": "^2.0.1", "bootstrap-icons": "^1.13.1", + "jquery": "^3.7.1", "sass": "^1.93.0" } -} \ No newline at end of file +} diff --git a/source/templates/hippie/app.liquid b/source/templates/hippie/app.liquid index 58ca863..2456f20 100644 --- a/source/templates/hippie/app.liquid +++ b/source/templates/hippie/app.liquid @@ -13,7 +13,7 @@ {% block script %} {{ block.super -}} - + From e21b9d36b5b430890df6aea8ef833da43d84ce27 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 21:16:41 +0100 Subject: [PATCH 07/12] feat: Replace form screen with liquid version --- source/screens/demo/examples/ui/form.liquid | 56 +++++++++++++++++++++ source/screens/demo/examples/ui/form.njk | 55 -------------------- 2 files changed, 56 insertions(+), 55 deletions(-) create mode 100644 source/screens/demo/examples/ui/form.liquid delete mode 100644 source/screens/demo/examples/ui/form.njk diff --git a/source/screens/demo/examples/ui/form.liquid b/source/screens/demo/examples/ui/form.liquid new file mode 100644 index 0000000..492e191 --- /dev/null +++ b/source/screens/demo/examples/ui/form.liquid @@ -0,0 +1,56 @@ +--- +title: Form +tags: +- ui +--- +{% assign bodyClass = "body_frame" -%} +{% layout "hippie/app.liquid" %} + +{% block body %} +{% render 'hippie/partials/frame-header.liquid' %} +
+

Formulare

+ + +
+
+
+
+
a
+
b
+
c
+
+
+{% endblock %} + +{%- block script %} +{{ block.super -}} + +{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/examples/ui/form.njk b/source/screens/demo/examples/ui/form.njk deleted file mode 100644 index 2e6c088..0000000 --- a/source/screens/demo/examples/ui/form.njk +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Form -tags: - - ui ---- -{% extends "hippie/_app_frame.njk" %} - -{% block body %} - {{ io.frameHeader('title-bar') }} -
-

Formulare

- - -
-
-
-
-
a
-
b
-
c
-
-
-{% endblock %} - -{%- block script %} - {{ super() }} - -{% endblock %} \ No newline at end of file From 3c9c438b254eada678a98bc5b16a1f1679a5f4f8 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 21:23:26 +0100 Subject: [PATCH 08/12] feat: Add game and gallery screens --- source/screens/demo/examples/game.liquid | 25 ++++++ .../screens/demo/examples/ui/gallery.liquid | 77 +++++++++++++++++++ source/style/modules/ui/_gallery_module.scss | 18 +++++ source/style/modules/ui/_game_module.scss | 3 + 4 files changed, 123 insertions(+) create mode 100644 source/screens/demo/examples/game.liquid create mode 100755 source/screens/demo/examples/ui/gallery.liquid create mode 100644 source/style/modules/ui/_gallery_module.scss create mode 100644 source/style/modules/ui/_game_module.scss diff --git a/source/screens/demo/examples/game.liquid b/source/screens/demo/examples/game.liquid new file mode 100644 index 0000000..a57b17f --- /dev/null +++ b/source/screens/demo/examples/game.liquid @@ -0,0 +1,25 @@ +--- +title: Game - TFW +tags: +- demoExample +- gameExample +--- +{% assign bodyClass = "body_game" -%} +{% layout "hippie/app.liquid" %} + +{% block body %} +
+{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/examples/ui/gallery.liquid b/source/screens/demo/examples/ui/gallery.liquid new file mode 100755 index 0000000..f29cae5 --- /dev/null +++ b/source/screens/demo/examples/ui/gallery.liquid @@ -0,0 +1,77 @@ +--- +title: Gallery +tags: +- ui +--- +{% assign bodyClass = "body_frame" -%} +{% layout "hippie/app.liquid" %} + +{% block body %} +{% render 'hippie/partials/frame-header.liquid' %} +
+
+
+ + +
+ + {% render 'hippie/partials/frame-status.liquid' %} +
+
+{% render 'hippie/partials/frame-mode.liquid' %} +{% endblock %} + +{%- block script %} +{{ block.super -}} + +{% endblock %} \ No newline at end of file diff --git a/source/style/modules/ui/_gallery_module.scss b/source/style/modules/ui/_gallery_module.scss new file mode 100644 index 0000000..4f8a233 --- /dev/null +++ b/source/style/modules/ui/_gallery_module.scss @@ -0,0 +1,18 @@ +@use "../../hippie-style/hippie"; + +.gallery { + display: flex; + flex-wrap: wrap; + justify-content: left; + align-items: start; + gap: 10px; + background-color: hippie.$color_back_io; + + & > div { + background-color: hotpink; + aspect-ratio: 2 / 3; + width: 128px; + transition: width 0.3s ease; + } +} + diff --git a/source/style/modules/ui/_game_module.scss b/source/style/modules/ui/_game_module.scss new file mode 100644 index 0000000..7bb575e --- /dev/null +++ b/source/style/modules/ui/_game_module.scss @@ -0,0 +1,3 @@ +.body_game { + background-color: hotpink; +} \ No newline at end of file From e0cfcfac13552d2372d2f99233460e2f5b598a6e Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 21:33:38 +0100 Subject: [PATCH 09/12] feat: Add and rename screens - Add windows screen - Add windows.js - Different variants of classes for drag and edge snap behaviour - Rename js files to better distinguish usage --- source/code/{_ui.js => drag.js} | 0 source/code/{_intro.js => intro.js} | 0 source/code/windows.js | 282 ++++++++++++++++++ source/screens/demo/examples/intro.njk | 2 +- source/screens/demo/examples/ui/drag.liquid | 2 +- .../screens/demo/examples/ui/windows.liquid | 30 ++ source/style/modules/ui/_windows_module.scss | 36 +++ source/style/ui.scss | 1 + 8 files changed, 351 insertions(+), 2 deletions(-) rename source/code/{_ui.js => drag.js} (100%) rename source/code/{_intro.js => intro.js} (100%) create mode 100644 source/code/windows.js create mode 100644 source/screens/demo/examples/ui/windows.liquid create mode 100644 source/style/modules/ui/_windows_module.scss diff --git a/source/code/_ui.js b/source/code/drag.js similarity index 100% rename from source/code/_ui.js rename to source/code/drag.js diff --git a/source/code/_intro.js b/source/code/intro.js similarity index 100% rename from source/code/_intro.js rename to source/code/intro.js diff --git a/source/code/windows.js b/source/code/windows.js new file mode 100644 index 0000000..6c68eec --- /dev/null +++ b/source/code/windows.js @@ -0,0 +1,282 @@ +class Draggable { + constructor(element) { + this.element = element; + this.offsetX = 0; + this.offsetY = 0; + this.isDragging = false; + this.barSize = ''; + + this.init(); + } + + init() { + this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); + document.addEventListener('mousemove', this.onMouseMove.bind(this)); + document.addEventListener('mouseup', this.onMouseUp.bind(this)); + this.setPosition('bottom'); + } + + onMouseDown(event) { + this.isDragging = true; + this.offsetX = event.clientX - this.element.getBoundingClientRect().left; + this.offsetY = event.clientY - this.element.getBoundingClientRect().top; + + event.preventDefault(); + } + + onMouseMove(event) { + if (!this.isDragging) { + return; + } + + let x = event.clientX - this.offsetX; + let y = event.clientY - this.offsetY; + + // Update the position of the element + this.element.style.left = `${x}px`; + this.element.style.top = `${y}px`; + } + + onMouseUp() { + if (!this.isDragging) { + return; + } + this.isDragging = false; + + this.snapToEdges(); + } + + snapToEdges() { + const rect = this.element.getBoundingClientRect(); + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + // Determine the closest edge + const distances = { + left: rect.left, + right: windowWidth - rect.right, + top: rect.top, + bottom: windowHeight - rect.bottom + }; + + const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); + + this.setPosition(closestEdge, this.barSize); + } + + setPosition(side, barSize) { + switch (side) { + case 'left': + // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position + this.element.style.top = '0px'; + this.element.style.right = ''; + this.element.style.bottom = '0px'; + this.element.style.left = '0px'; + this.element.style.width = barSize; + this.element.style.height = ''; + break; + case 'right': + // this.element.style.left = `${windowWidth - rect.width}px`; + // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position + this.element.style.top = '0px'; + this.element.style.right = '0px'; + this.element.style.bottom = '0px'; + this.element.style.left = ''; + this.element.style.width = barSize; + this.element.style.height = ''; + break; + case 'top': + // this.element.style.top = '0px'; + // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position + this.element.style.top = '0px'; + this.element.style.right = '0px'; + this.element.style.bottom = ''; + this.element.style.left = '0px'; + this.element.style.width = ''; + this.element.style.height = barSize; + break; + case 'bottom': + // this.element.style.top = `${windowHeight - rect.height}px`; + // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position + this.element.style.top = ''; + this.element.style.right = '0px'; + this.element.style.bottom = '0px'; + this.element.style.left = '0px'; + this.element.style.width = ''; + this.element.style.height = barSize; + break; + } + } +} + +class DragAdv { + constructor(element, placeholder) { + this.element = element; + this.placeholder = placeholder; + this.offsetX = 0; + this.offsetY = 0; + this.isDragging = false; + this.barSize = ''; + + this.init(); + } + + init() { + this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); + document.addEventListener('mousemove', this.onMouseMove.bind(this)); + document.addEventListener('mouseup', this.onMouseUp.bind(this)); + this.setPosition('bottom'); + } + + onMouseDown(event) { + this.isDragging = true; + // this.offsetX = event.clientX - this.element.getBoundingClientRect().left; + // this.offsetY = event.clientY - this.element.getBoundingClientRect().top; + this.offsetX = 0; + this.offsetY = 0; + this.element.style.display = 'none'; + + this.showPlaceholder(); + event.preventDefault(); + } + + onMouseMove(event) { + if (!this.isDragging) return; + + let x = event.clientX - this.offsetX; + let y = event.clientY - this.offsetY; + + // Update the position of the element + // this.element.style.left = `${x}px`; + // this.element.style.top = `${y}px`; + // this.element.style.display = 'none'; + + // Update placeholder position + this.placeholder.style.left = `${x}px`; + this.placeholder.style.top = `${y}px`; + // this.placeholder.style.display = 'block'; + } + + onMouseUp() { + if (!this.isDragging) return; + this.isDragging = false; + + this.element.style.display = 'block'; + + this.snapToEdges(); + this.hidePlaceholder(); + } + + showPlaceholder() { + this.placeholder.style.display = 'block'; + } + + hidePlaceholder() { + this.placeholder.style.display = 'none'; + } + + snapToEdges() { + const rect = this.placeholder.getBoundingClientRect(); + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + const distances = { + left: rect.left, + right: windowWidth - rect.right, + top: rect.top, + bottom: windowHeight - rect.bottom + }; + + const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); + + console.log(rect); + console.log(closestEdge); + this.setPosition(closestEdge, this.barSize); + /*switch (closestEdge) { + case 'left': + this.element.style.left = '0px'; + this.element.style.top = `${rect.top}px`; + break; + case 'right': + this.element.style.left = `${windowWidth - rect.width}px`; + this.element.style.top = `${rect.top}px`; + break; + case 'top': + this.element.style.top = '0px'; + this.element.style.left = `${rect.left}px`; + break; + case 'bottom': + this.element.style.top = `${windowHeight - rect.height}px`; + this.element.style.left = `${rect.left}px`; + break; + }*/ + } + + setPosition(side, barSize) { + switch (side) { + case 'left': + // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position + this.element.style.top = '0px'; + this.element.style.right = ''; + this.element.style.bottom = '0px'; + this.element.style.left = '0px'; + this.element.style.width = barSize; + this.element.style.height = ''; + break; + case 'right': + // this.element.style.left = `${windowWidth - rect.width}px`; + // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position + this.element.style.top = '0px'; + this.element.style.right = '0px'; + this.element.style.bottom = '0px'; + this.element.style.left = ''; + this.element.style.width = barSize; + this.element.style.height = ''; + break; + case 'top': + // this.element.style.top = '0px'; + // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position + this.element.style.top = '0px'; + this.element.style.right = '0px'; + this.element.style.bottom = ''; + this.element.style.left = '0px'; + this.element.style.width = ''; + this.element.style.height = barSize; + break; + case 'bottom': + // this.element.style.top = `${windowHeight - rect.height}px`; + // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position + this.element.style.top = ''; + this.element.style.right = '0px'; + this.element.style.bottom = '0px'; + this.element.style.left = '0px'; + this.element.style.width = ''; + this.element.style.height = barSize; + break; + } + } +} + +class BestDrag { + #element; + + constructor(element) { + this.#setElement(element); + } + + #setElement(value) { + if (!value) { + throw new Error('No element found'); + } + this.#element = value; + this.#element.style.background = "hotpink"; + } + + get element() { + return this.#element; + } + + set element(value) { + this.#setElement(value); + } +} \ No newline at end of file diff --git a/source/screens/demo/examples/intro.njk b/source/screens/demo/examples/intro.njk index 1358739..548cc3f 100644 --- a/source/screens/demo/examples/intro.njk +++ b/source/screens/demo/examples/intro.njk @@ -49,7 +49,7 @@ tags: {%- block script %} {{ super() }} - + + + +{% endblock %} \ No newline at end of file diff --git a/source/style/modules/ui/_windows_module.scss b/source/style/modules/ui/_windows_module.scss new file mode 100644 index 0000000..0f46b78 --- /dev/null +++ b/source/style/modules/ui/_windows_module.scss @@ -0,0 +1,36 @@ +@use "sass:map"; + +@use "../../hippie-style/hippie"; + +#task-bar { + @extend %flex-inline; + z-index: map.get(hippie.$z-indexes, "content-top"); + align-items: stretch; + position: fixed; + //right: 0; + //bottom: 0; + //left: 0; + border: 1px solid transparent; + padding: hippie.$space_basic; + background-color: rgba(0, 0, 0, .1); + + button { + @extend .button_io; + overflow: hidden; + } +} + +#screen-space { + position: relative; + height: 100%; +} + +#placeholder { + display: none; + z-index: map.get(hippie.$z-indexes, "content-top"); + position: fixed; + width: 100px; + height: 100px; + border: 2px dashed deeppink; + background-color: hotpink; +} \ No newline at end of file diff --git a/source/style/ui.scss b/source/style/ui.scss index 4a1e6c8..da6ecf7 100644 --- a/source/style/ui.scss +++ b/source/style/ui.scss @@ -9,6 +9,7 @@ @use "modules/ui/form_module"; @use "modules/ui/game_module"; @use "modules/ui/gallery_module"; +@use "modules/ui/windows_module"; $color_gui_back: hippie.$color_dark; $space_gui_half: hippie.$space_half; From 0996ace34f31c8e3d2bf2b0ec8a925cf3fdaa606 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 21:53:57 +0100 Subject: [PATCH 10/12] fix: Task bar drag behaviour - Placeholder is centered to mouse cursor - Placeholder is positioned on mouse down not only on move --- source/code/windows.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/source/code/windows.js b/source/code/windows.js index 6c68eec..c6e42b8 100644 --- a/source/code/windows.js +++ b/source/code/windows.js @@ -125,18 +125,24 @@ class DragAdv { this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); document.addEventListener('mousemove', this.onMouseMove.bind(this)); document.addEventListener('mouseup', this.onMouseUp.bind(this)); - this.setPosition('bottom'); + this.setPosition('bottom', this.barSize); } onMouseDown(event) { this.isDragging = true; - // this.offsetX = event.clientX - this.element.getBoundingClientRect().left; - // this.offsetY = event.clientY - this.element.getBoundingClientRect().top; - this.offsetX = 0; - this.offsetY = 0; - this.element.style.display = 'none'; this.showPlaceholder(); + + this.offsetX = this.placeholder.getBoundingClientRect().width / 2; + this.offsetY = this.placeholder.getBoundingClientRect().height / 2; + this.element.style.display = 'none'; + + let x = event.clientX - this.offsetX; + let y = event.clientY - this.offsetY; + + this.placeholder.style.left = `${x}px`; + this.placeholder.style.top = `${y}px`; + event.preventDefault(); } @@ -146,15 +152,8 @@ class DragAdv { let x = event.clientX - this.offsetX; let y = event.clientY - this.offsetY; - // Update the position of the element - // this.element.style.left = `${x}px`; - // this.element.style.top = `${y}px`; - // this.element.style.display = 'none'; - - // Update placeholder position this.placeholder.style.left = `${x}px`; this.placeholder.style.top = `${y}px`; - // this.placeholder.style.display = 'block'; } onMouseUp() { From 1ada62f6eceae2a55a9c94466658e3ba384c2a40 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 23:24:02 +0100 Subject: [PATCH 11/12] feat: Optimize DragAdv class - Only use left mouse button - Handle element and placeholder together --- source/code/windows.js | 61 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/source/code/windows.js b/source/code/windows.js index c6e42b8..f282729 100644 --- a/source/code/windows.js +++ b/source/code/windows.js @@ -61,6 +61,24 @@ class Draggable { const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); + /*switch (closestEdge) { + case 'left': + this.element.style.left = '0px'; + this.element.style.top = `${rect.top}px`; + break; + case 'right': + this.element.style.left = `${windowWidth - rect.width}px`; + this.element.style.top = `${rect.top}px`; + break; + case 'top': + this.element.style.top = '0px'; + this.element.style.left = `${rect.left}px`; + break; + case 'bottom': + this.element.style.top = `${windowHeight - rect.height}px`; + this.element.style.left = `${rect.left}px`; + break; + }*/ this.setPosition(closestEdge, this.barSize); } @@ -129,19 +147,20 @@ class DragAdv { } onMouseDown(event) { - this.isDragging = true; + if (event.button === 0) { + this.isDragging = true; - this.showPlaceholder(); + this.showPlaceholder(); - this.offsetX = this.placeholder.getBoundingClientRect().width / 2; - this.offsetY = this.placeholder.getBoundingClientRect().height / 2; - this.element.style.display = 'none'; + this.offsetX = this.placeholder.getBoundingClientRect().width / 2; + this.offsetY = this.placeholder.getBoundingClientRect().height / 2; - let x = event.clientX - this.offsetX; - let y = event.clientY - this.offsetY; + let x = event.clientX - this.offsetX; + let y = event.clientY - this.offsetY; - this.placeholder.style.left = `${x}px`; - this.placeholder.style.top = `${y}px`; + this.placeholder.style.left = `${x}px`; + this.placeholder.style.top = `${y}px`; + } event.preventDefault(); } @@ -160,18 +179,18 @@ class DragAdv { if (!this.isDragging) return; this.isDragging = false; - this.element.style.display = 'block'; - this.snapToEdges(); this.hidePlaceholder(); } showPlaceholder() { + this.element.style.display = 'none'; this.placeholder.style.display = 'block'; } hidePlaceholder() { this.placeholder.style.display = 'none'; + this.element.style.display = ''; } snapToEdges() { @@ -188,27 +207,7 @@ class DragAdv { const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); - console.log(rect); - console.log(closestEdge); this.setPosition(closestEdge, this.barSize); - /*switch (closestEdge) { - case 'left': - this.element.style.left = '0px'; - this.element.style.top = `${rect.top}px`; - break; - case 'right': - this.element.style.left = `${windowWidth - rect.width}px`; - this.element.style.top = `${rect.top}px`; - break; - case 'top': - this.element.style.top = '0px'; - this.element.style.left = `${rect.left}px`; - break; - case 'bottom': - this.element.style.top = `${windowHeight - rect.height}px`; - this.element.style.left = `${rect.left}px`; - break; - }*/ } setPosition(side, barSize) { From 6098a1e62d2791e1c41e93cd3d855c80f12749f1 Mon Sep 17 00:00:00 2001 From: sthag Date: Mon, 27 Oct 2025 23:24:49 +0100 Subject: [PATCH 12/12] feat: Style and content for windows --- .../screens/demo/examples/ui/windows.liquid | 31 +++++++++- source/style/modules/ui/_windows_module.scss | 61 ++++++++++++++++++- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/source/screens/demo/examples/ui/windows.liquid b/source/screens/demo/examples/ui/windows.liquid index 9dc321b..daacb66 100644 --- a/source/screens/demo/examples/ui/windows.liquid +++ b/source/screens/demo/examples/ui/windows.liquid @@ -7,9 +7,34 @@ tags: {% layout "hippie/app.liquid" %} {% block body %} - +
+ + + +
+ + + +
+
{% endblock %} diff --git a/source/style/modules/ui/_windows_module.scss b/source/style/modules/ui/_windows_module.scss index 0f46b78..c7a9846 100644 --- a/source/style/modules/ui/_windows_module.scss +++ b/source/style/modules/ui/_windows_module.scss @@ -2,10 +2,21 @@ @use "../../hippie-style/hippie"; -#task-bar { - @extend %flex-inline; - z-index: map.get(hippie.$z-indexes, "content-top"); +$padding_half: calc(#{hippie.$space_half} - 3px) hippie.$space_half; + +%flex-bar { + display: flex; + flex-direction: row; + flex-wrap: wrap; align-items: stretch; + align-content: center; + justify-content: flex-start; + gap: hippie.$space_half hippie.$space_basic; +} + +#task-bar { + @extend %flex-bar; + z-index: map.get(hippie.$z-indexes, "content-top"); position: fixed; //right: 0; //bottom: 0; @@ -14,10 +25,54 @@ padding: hippie.$space_basic; background-color: rgba(0, 0, 0, .1); + nav, + & > div { + @extend %flex-bar; + + &:last-child { + margin-left: auto; + } + } + button { @extend .button_io; overflow: hidden; } + + nav.small { + //font-size: .8em; + + button { + border: none; + padding: $padding_half; + + &:hover { + background-color: transparent; + } + } + } + + nav.big { + font-size: 1.5em; + + button { + border: none; + padding: 0; + + &:hover { + background-color: transparent; + } + } + } + + .clock { + text-align: end; + + &, + & > * { + line-height: 1; + } + } } #screen-space {