diff --git a/css/icons.css b/css/icons.css
index a3b8ca9..e808b3b 100644
--- a/css/icons.css
+++ b/css/icons.css
@@ -1,3 +1,34 @@
+.ui.inline-icon {
+ position: relative;
+
+ display: flex;
+}
+
+.ui.inline-icon::after {
+ content: "";
+ display: block;
+
+ position: absolute;
+
+ box-sizing: border-box;
+
+ margin: auto;
+ top: 15%;
+ bottom: 15%;
+
+ mask-size: contain;
+ mask-repeat: no-repeat;
+
+ max-height: 70%;
+ aspect-ratio: 1;
+
+ left: 0;
+ right: 0;
+
+ background-color: var(--c-text);
+}
+
+.ui.inline-icon.icon-eye-off::after,
.ui.icon > .icon-eye-off {
-webkit-mask-image: url("../res/icons/eye-off.svg");
mask-image: url("../res/icons/eye-off.svg");
@@ -42,3 +73,57 @@
-webkit-mask-image: url("../res/icons/settings.svg");
mask-image: url("../res/icons/settings.svg");
}
+
+.ui.inline-icon.icon-grid::after,
+.ui.icon > .icon-grid {
+ -webkit-mask-image: url("../res/icons/grid.svg");
+ mask-image: url("../res/icons/grid.svg");
+}
+
+.ui.inline-icon.icon-venetian-mask::after,
+.ui.icon > .icon-venetian-mask {
+ -webkit-mask-image: url("../res/icons/venetian-mask.svg");
+ mask-image: url("../res/icons/venetian-mask.svg");
+}
+
+.ui.inline-icon.icon-brush::after,
+.ui.icon > .icon-brush {
+ -webkit-mask-image: url("../res/icons/brush.svg");
+ mask-image: url("../res/icons/brush.svg");
+}
+
+.ui.inline-icon.icon-paintbrush::after,
+.ui.icon > .icon-paintbrush {
+ -webkit-mask-image: url("../res/icons/paintbrush.svg");
+ mask-image: url("../res/icons/paintbrush.svg");
+}
+
+.ui.inline-icon.icon-expand::after,
+.ui.icon > .icon-expand {
+ -webkit-mask-image: url("../res/icons/expand.svg");
+ mask-image: url("../res/icons/expand.svg");
+}
+
+.ui.inline-icon.icon-pin::after,
+.ui.icon > .icon-pin {
+ -webkit-mask-image: url("../res/icons/pin.svg");
+ mask-image: url("../res/icons/pin.svg");
+}
+
+.ui.inline-icon.icon-box-select::after,
+.ui.icon > .icon-box-select {
+ -webkit-mask-image: url("../res/icons/box-select.svg");
+ mask-image: url("../res/icons/box-select.svg");
+}
+
+.ui.inline-icon.icon-maximize::after,
+.ui.icon > .icon-maximize {
+ -webkit-mask-image: url("../res/icons/maximize.svg");
+ mask-image: url("../res/icons/maximize.svg");
+}
+
+.ui.inline-icon.icon-clipboard-list::after,
+.ui.icon > .icon-clipboard-list {
+ -webkit-mask-image: url("../res/icons/clipboard-list.svg");
+ mask-image: url("../res/icons/clipboard-list.svg");
+}
diff --git a/css/ui/generic.css b/css/ui/generic.css
index 93caf35..801e2ba 100644
--- a/css/ui/generic.css
+++ b/css/ui/generic.css
@@ -37,6 +37,8 @@
/* Slider Input */
div.slider-wrapper {
margin: 5px;
+ margin-left: 0;
+ margin-right: 0;
}
div.slider-wrapper {
@@ -100,6 +102,83 @@ div.slider-wrapper > input.text {
background-color: transparent;
}
+/* Checkbox Input */
+div.checkbox-array {
+ display: flex;
+
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+input.oo-checkbox[type="checkbox"] {
+ /* Hide original checkbox */
+ -webkit-appearance: none;
+ appearance: none;
+
+ flex: 1;
+
+ margin: 0;
+
+ min-width: 28px;
+ height: 28px;
+
+ background-color: var(--c-primary);
+
+ cursor: pointer;
+}
+
+input.oo-checkbox[type="checkbox"]:disabled {
+ background-color: #666 !important;
+ cursor: default !important;
+}
+
+input.oo-checkbox[type="checkbox"]:disabled:hover {
+ filter: none !important;
+}
+
+input.oo-checkbox[type="checkbox"]:checked::after {
+ background-color: #66f;
+}
+
+input.oo-checkbox[type="checkbox"]:hover {
+ background-color: var(--c-hover);
+}
+
+input.oo-checkbox[type="checkbox"]:active {
+ filter: brightness(120%);
+}
+
+input.oo-checkbox[type="checkbox"]:first-child {
+ border-top-left-radius: 5px;
+ border-bottom-left-radius: 5px;
+}
+
+input.oo-checkbox[type="checkbox"]:last-child {
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+}
+
+/* Mask Inversion Checkbox */
+input.oo-checkbox[type="checkbox"].invert-mask-checkbox::after {
+ background-color: var(--c-text);
+}
+
+input.oo-checkbox[type="checkbox"].invert-mask-checkbox:hover {
+ filter: brightness(120%);
+}
+
+input.oo-checkbox[type="checkbox"].invert-mask-checkbox:active {
+ filter: brightness(140%);
+}
+
+input.oo-checkbox[type="checkbox"].invert-mask-checkbox {
+ background-color: #922;
+}
+
+input.oo-checkbox[type="checkbox"].invert-mask-checkbox:checked {
+ background-color: #229;
+}
+
/* Bare Select */
.bareselector {
diff --git a/js/lib/toolbar.js b/js/lib/toolbar.js
index 232b0fe..10e48f8 100644
--- a/js/lib/toolbar.js
+++ b/js/lib/toolbar.js
@@ -145,17 +145,24 @@ const toolbar = {
* Premade inputs for populating the context menus
*/
const _toolbar_input = {
- checkbox: (state, dataKey, text, cb = null) => {
+ checkbox: (state, dataKey, text, classes, cb = null) => {
if (state[dataKey] === undefined) state[dataKey] = false;
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
+ checkbox.classList.add("oo-checkbox", "ui", "inline-icon");
+
+ if (typeof classes === "string") classes = [classes];
+
+ if (classes) checkbox.classList.add(...classes);
checkbox.checked = state[dataKey];
checkbox.onchange = () => {
state[dataKey] = checkbox.checked;
cb && cb();
};
+ checkbox.title = text;
+
const label = document.createElement("label");
label.appendChild(checkbox);
label.appendChild(new Text(text));
diff --git a/js/ui/tool/colorbrush.js b/js/ui/tool/colorbrush.js
index 5786307..dc1d190 100644
--- a/js/ui/tool/colorbrush.js
+++ b/js/ui/tool/colorbrush.js
@@ -349,13 +349,16 @@ const colorBrushTool = () =>
state.ctxmenu = {};
// Affects Mask Checkbox
+ const array = document.createElement("div");
const affectMaskCheckbox = _toolbar_input.checkbox(
state,
"affectMask",
- "Affect Mask"
- ).label;
+ "Affect Mask",
+ "icon-venetian-mask"
+ ).checkbox;
+ array.appendChild(affectMaskCheckbox);
- state.ctxmenu.affectMaskCheckbox = affectMaskCheckbox;
+ state.ctxmenu.affectMaskCheckbox = array;
// Brush size slider
const brushSizeSlider = _toolbar_input.slider(
diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js
index f0e1fab..49dd376 100644
--- a/js/ui/tool/dream.js
+++ b/js/ui/tool/dream.js
@@ -1469,24 +1469,27 @@ const dreamTool = () =>
state.ctxmenu.snapToGridLabel = _toolbar_input.checkbox(
state,
"snapToGrid",
- "Snap To Grid"
- ).label;
+ "Snap To Grid",
+ "icon-grid"
+ ).checkbox;
// Invert Mask Checkbox
state.ctxmenu.invertMaskLabel = _toolbar_input.checkbox(
state,
"invertMask",
"Invert Mask",
+ ["icon-venetian-mask", "invert-mask-checkbox"],
() => {
setMask(state.invertMask ? "hold" : "clear");
}
- ).label;
+ ).checkbox;
// Keep Masked Content Checkbox
state.ctxmenu.keepUnmaskedLabel = _toolbar_input.checkbox(
state,
"keepUnmasked",
"Keep Unmasked",
+ "icon-pin",
() => {
if (state.keepUnmasked) {
state.ctxmenu.keepUnmaskedBlurSlider.classList.remove(
@@ -1496,7 +1499,7 @@ const dreamTool = () =>
state.ctxmenu.keepUnmaskedBlurSlider.classList.add("invisible");
}
}
- ).label;
+ ).checkbox;
// Keep Masked Content Blur Slider
state.ctxmenu.keepUnmaskedBlurSlider = _toolbar_input.slider(
@@ -1515,8 +1518,9 @@ const dreamTool = () =>
state.ctxmenu.preserveMasksLabel = _toolbar_input.checkbox(
state,
"preserveMasks",
- "Preserve Brushed Masks"
- ).label;
+ "Preserve Brushed Masks",
+ "icon-paintbrush"
+ ).checkbox;
// Overmasking Slider
state.ctxmenu.overMaskPxLabel = _toolbar_input.slider(
@@ -1546,14 +1550,16 @@ const dreamTool = () =>
}
menu.appendChild(state.ctxmenu.cursorSizeSlider);
- menu.appendChild(state.ctxmenu.snapToGridLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.invertMaskLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.keepUnmaskedLabel);
+ const array = document.createElement("div");
+ array.classList.add("checkbox-array");
+ array.appendChild(state.ctxmenu.snapToGridLabel);
+ //menu.appendChild(document.createElement("br"));
+ array.appendChild(state.ctxmenu.invertMaskLabel);
+ array.appendChild(state.ctxmenu.preserveMasksLabel);
+ //menu.appendChild(document.createElement("br"));
+ array.appendChild(state.ctxmenu.keepUnmaskedLabel);
+ menu.appendChild(array);
menu.appendChild(state.ctxmenu.keepUnmaskedBlurSlider);
- menu.appendChild(state.ctxmenu.preserveMasksLabel);
- menu.appendChild(document.createElement("br"));
menu.appendChild(state.ctxmenu.overMaskPxLabel);
menu.appendChild(state.ctxmenu.eagerGenerateCountLabel);
},
@@ -1974,24 +1980,27 @@ const img2imgTool = () =>
state.ctxmenu.snapToGridLabel = _toolbar_input.checkbox(
state,
"snapToGrid",
- "Snap To Grid"
- ).label;
+ "Snap To Grid",
+ "icon-grid"
+ ).checkbox;
// Invert Mask Checkbox
state.ctxmenu.invertMaskLabel = _toolbar_input.checkbox(
state,
"invertMask",
"Invert Mask",
+ ["icon-venetian-mask", "invert-mask-checkbox"],
() => {
setMask(state.invertMask ? "hold" : "clear");
}
- ).label;
+ ).checkbox;
// Keep Masked Content Checkbox
state.ctxmenu.keepUnmaskedLabel = _toolbar_input.checkbox(
state,
"keepUnmasked",
"Keep Unmasked",
+ "icon-pin",
() => {
if (state.keepUnmasked) {
state.ctxmenu.keepUnmaskedBlurSlider.classList.remove(
@@ -2007,7 +2016,7 @@ const img2imgTool = () =>
);
}
}
- ).label;
+ ).checkbox;
// Keep Masked Content Blur Slider
state.ctxmenu.keepUnmaskedBlurSlider = _toolbar_input.slider(
@@ -2032,15 +2041,17 @@ const img2imgTool = () =>
state.ctxmenu.preserveMasksLabel = _toolbar_input.checkbox(
state,
"preserveMasks",
- "Preserve Brushed Masks"
- ).label;
+ "Preserve Brushed Masks",
+ "icon-paintbrush"
+ ).checkbox;
// Inpaint Full Resolution Checkbox
state.ctxmenu.fullResolutionLabel = _toolbar_input.checkbox(
state,
"fullResolution",
- "Inpaint Full Resolution"
- ).label;
+ "Inpaint Full Resolution",
+ "icon-expand"
+ ).checkbox;
// Denoising Strength Slider
state.ctxmenu.denoisingStrengthSlider = _toolbar_input.slider(
@@ -2059,8 +2070,9 @@ const img2imgTool = () =>
state.ctxmenu.borderMaskGradientCheckbox = _toolbar_input.checkbox(
state,
"gradient",
- "Border Mask Gradient"
- ).label;
+ "Border Mask Gradient",
+ "icon-box-select"
+ ).checkbox;
// Border Mask Size Slider
state.ctxmenu.borderMaskSlider = _toolbar_input.slider(
@@ -2107,20 +2119,22 @@ const img2imgTool = () =>
}
menu.appendChild(state.ctxmenu.cursorSizeSlider);
- menu.appendChild(state.ctxmenu.snapToGridLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.invertMaskLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.keepUnmaskedLabel);
+ const array = document.createElement("div");
+ array.classList.add("checkbox-array");
+ array.appendChild(state.ctxmenu.snapToGridLabel);
+ array.appendChild(state.ctxmenu.invertMaskLabel);
+ array.appendChild(state.ctxmenu.preserveMasksLabel);
+ array.appendChild(state.ctxmenu.keepUnmaskedLabel);
+ menu.appendChild(array);
menu.appendChild(state.ctxmenu.keepUnmaskedBlurSlider);
menu.appendChild(state.ctxmenu.keepUnmaskedBlurSliderLinebreak);
- menu.appendChild(state.ctxmenu.preserveMasksLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.fullResolutionLabel);
- menu.appendChild(document.createElement("br"));
menu.appendChild(state.ctxmenu.inpaintTypeSelect);
menu.appendChild(state.ctxmenu.denoisingStrengthSlider);
- menu.appendChild(state.ctxmenu.borderMaskGradientCheckbox);
+ const btnArray2 = document.createElement("div");
+ btnArray2.classList.add("checkbox-array");
+ btnArray2.appendChild(state.ctxmenu.fullResolutionLabel);
+ btnArray2.appendChild(state.ctxmenu.borderMaskGradientCheckbox);
+ menu.appendChild(btnArray2);
menu.appendChild(state.ctxmenu.borderMaskSlider);
menu.appendChild(state.ctxmenu.eagerGenerateCountLabel);
},
diff --git a/js/ui/tool/select.js b/js/ui/tool/select.js
index c62cf14..11eb700 100644
--- a/js/ui/tool/select.js
+++ b/js/ui/tool/select.js
@@ -633,23 +633,26 @@ const selectTransformTool = () =>
state.ctxmenu.snapToGridLabel = _toolbar_input.checkbox(
state,
"snapToGrid",
- "Snap To Grid"
- ).label;
+ "Snap To Grid",
+ "icon-grid"
+ ).checkbox;
// Keep Aspect Ratio
state.ctxmenu.keepAspectRatioLabel = _toolbar_input.checkbox(
state,
"keepAspectRatio",
- "Keep Aspect Ratio"
- ).label;
+ "Keep Aspect Ratio",
+ "icon-maximize"
+ ).checkbox;
// Use Clipboard
const clipboardCheckbox = _toolbar_input.checkbox(
state,
"useClipboard",
- "Use clipboard"
+ "Use clipboard",
+ "icon-clipboard-list"
);
- state.ctxmenu.useClipboardLabel = clipboardCheckbox.label;
+ state.ctxmenu.useClipboardLabel = clipboardCheckbox.checkbox;
if (!(navigator.clipboard && navigator.clipboard.write))
clipboardCheckbox.checkbox.disabled = true; // Disable if not available
@@ -760,11 +763,12 @@ const selectTransformTool = () =>
state.ctxmenu.actionArray = actionArray;
state.ctxmenu.visibleActionArray = visibleActionArray;
}
- menu.appendChild(state.ctxmenu.snapToGridLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.keepAspectRatioLabel);
- menu.appendChild(document.createElement("br"));
- menu.appendChild(state.ctxmenu.useClipboardLabel);
+ const array = document.createElement("div");
+ array.classList.add("checkbox-array");
+ array.appendChild(state.ctxmenu.snapToGridLabel);
+ array.appendChild(state.ctxmenu.keepAspectRatioLabel);
+ array.appendChild(state.ctxmenu.useClipboardLabel);
+ menu.appendChild(array);
menu.appendChild(state.ctxmenu.selectionPeekOpacitySlider);
menu.appendChild(state.ctxmenu.actionArray);
menu.appendChild(state.ctxmenu.visibleActionArray);
diff --git a/js/ui/tool/stamp.js b/js/ui/tool/stamp.js
index 74be4ad..fc1cb89 100644
--- a/js/ui/tool/stamp.js
+++ b/js/ui/tool/stamp.js
@@ -368,11 +368,17 @@ const stampTool = () =>
if (!state.ctxmenu) {
state.ctxmenu = {};
// Snap To Grid Checkbox
- state.ctxmenu.snapToGridLabel = _toolbar_input.checkbox(
- state,
- "snapToGrid",
- "Snap To Grid"
- ).label;
+ const array = document.createElement("div");
+ array.classList.add("checkbox-array");
+ array.appendChild(
+ _toolbar_input.checkbox(
+ state,
+ "snapToGrid",
+ "Snap To Grid",
+ "icon-grid"
+ ).checkbox
+ );
+ state.ctxmenu.snapToGridLabel = array;
// Create resource list
const uploadButtonId = `upload-btn-${guid()}`;
diff --git a/res/icons/clipboard-list.svg b/res/icons/clipboard-list.svg
new file mode 100644
index 0000000..45bbcf5
--- /dev/null
+++ b/res/icons/clipboard-list.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/res/icons/equal.svg b/res/icons/equal.svg
new file mode 100644
index 0000000..6b5c5c8
--- /dev/null
+++ b/res/icons/equal.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/res/icons/expand.svg b/res/icons/expand.svg
new file mode 100644
index 0000000..6f5864a
--- /dev/null
+++ b/res/icons/expand.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/res/icons/grid.svg b/res/icons/grid.svg
new file mode 100644
index 0000000..a7daf6d
--- /dev/null
+++ b/res/icons/grid.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/res/icons/maximize.svg b/res/icons/maximize.svg
new file mode 100644
index 0000000..5c8a6e3
--- /dev/null
+++ b/res/icons/maximize.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/res/icons/pin.svg b/res/icons/pin.svg
new file mode 100644
index 0000000..aa858be
--- /dev/null
+++ b/res/icons/pin.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/res/icons/square.svg b/res/icons/square.svg
new file mode 100644
index 0000000..ba8d095
--- /dev/null
+++ b/res/icons/square.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/res/icons/venetian-mask.svg b/res/icons/venetian-mask.svg
new file mode 100644
index 0000000..6cd8962
--- /dev/null
+++ b/res/icons/venetian-mask.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file