Suggest popular background colors, add transparency support

Making the UI more user-friendly by suggesting some commonly used colors in the Settings menu
This commit is contained in:
MassiveBox 2025-05-05 19:17:59 +02:00
parent 1ad26d1e23
commit fa3eba219e
Signed by: massivebox
GPG key ID: 9B74D3A59181947D
4 changed files with 52 additions and 21 deletions

View file

@ -8,13 +8,25 @@
"drawing": "Drawing",
"settings": {
"name": "js-draw Plugin Settings",
"suggestedColors":{
"white": "White",
"black": "Black",
"transparent": "Transparent",
"custom": "Custom",
"darkBlue": "Dark Blue",
"darkGray": "Dark Gray"
},
"grid": {
"title": "Enable grid by default",
"description": "Enable to automatically turn on the grid on new drawings."
},
"backgroundDropdown":{
"title": "Background color",
"description": "Default background color for new drawings."
},
"background": {
"title": "Default background Color",
"description": "Default background color for new drawings, in hexadecimal."
"title": "Custom background",
"description": "Hexadecimal code of the custom background color for new drawings.<br /><b>This setting is only applied if \"Background Color\" is set to \"Custom\"!</b>"
},
"dialogOnDesktop": {
"title": "Open editor as dialog on desktop",

View file

@ -2,7 +2,6 @@ import {PluginFile} from "@/file";
import {CONFIG_FILENAME, JSON_MIME, STORAGE_PATH} from "@/const";
import {Plugin, showMessage} from "siyuan";
import {SettingUtils} from "@/libs/setting-utils";
import {validateColor} from "@/helper";
type Options = {
grid: boolean
@ -48,7 +47,7 @@ export class PluginConfig {
private loadDefaultConfig() {
this.options = {
grid: true,
background: "#000000",
background: "#00000000",
dialogOnDesktop: false,
analytics: true,
};
@ -61,10 +60,16 @@ export class PluginConfig {
}
setConfig(config: Options) {
this.options = config;
}
static validateColor(hex: string) {
hex = hex.replace('#', '');
return typeof hex === 'string'
&& (hex.length === 6 || hex.length === 8)
&& !isNaN(Number('0x' + hex))
}
}
export class PluginConfigViewer {
@ -72,23 +77,34 @@ export class PluginConfigViewer {
config: PluginConfig;
settingUtils: SettingUtils;
plugin: Plugin;
private readonly backgroundDropdownOptions;
constructor(config: PluginConfig, plugin: Plugin) {
this.config = config;
this.plugin = plugin;
this.backgroundDropdownOptions = {
'#00000000': plugin.i18n.settings.suggestedColors.transparent,
'CUSTOM': plugin.i18n.settings.suggestedColors.custom,
'#ffffff': plugin.i18n.settings.suggestedColors.white,
'#1e2227': plugin.i18n.settings.suggestedColors.darkBlue,
'#1e1e1e': plugin.i18n.settings.suggestedColors.darkGray,
'#000000': plugin.i18n.settings.suggestedColors.black,
}
this.populateSettingMenu();
}
async configSaveCallback(data) {
if(!validateColor(data.background)) {
let color = data.backgroundDropdown === "CUSTOM" ? data.background : data.backgroundDropdown;
if(!PluginConfig.validateColor(color)) {
showMessage(this.plugin.i18n.errInvalidBackgroundColor, 0, 'error');
data.background = this.config.options.background;
this.settingUtils.set('background', data.background);
}
this.config.setConfig({
grid: data.grid,
background: data.background,
background: color,
dialogOnDesktop: data.dialogOnDesktop,
analytics: data.analytics,
});
@ -100,7 +116,7 @@ export class PluginConfigViewer {
this.settingUtils = new SettingUtils({
plugin: this.plugin,
name: this.plugin.i18n.settings.name,
name: 'optionsUI',
callback: async (data) => {
await this.configSaveCallback(data);
}
@ -114,12 +130,22 @@ export class PluginConfigViewer {
type: 'checkbox'
});
this.settingUtils.addItem({
key: 'backgroundDropdown',
title: this.plugin.i18n.settings.backgroundDropdown.title,
description: this.plugin.i18n.settings.backgroundDropdown.description,
type: 'select',
value: this.config.options.background in this.backgroundDropdownOptions ?
this.config.options.background : 'CUSTOM',
options: this.backgroundDropdownOptions,
});
this.settingUtils.addItem({
key: "background",
title: this.plugin.i18n.settings.background.title,
description: this.plugin.i18n.settings.background.description,
value: this.config.options.background,
type: 'textarea',
type: 'textinput',
});
this.settingUtils.addItem({

View file

@ -80,6 +80,11 @@ export class PluginEditor {
const toolbar = this.editor.addToolbar();
// save button
const saveButton = toolbar.addSaveButton(async () => {
await this.saveCallback(saveButton);
});
// restore toolbarFile state
this.toolbarFile = new PluginFile(STORAGE_PATH, TOOLBAR_FILENAME, JSON_MIME);
await this.toolbarFile.loadFromSiYuanFS();
@ -87,11 +92,6 @@ export class PluginEditor {
toolbar.deserializeState(this.toolbarFile.getContent());
}
// save button
const saveButton = toolbar.addSaveButton(async () => {
await this.saveCallback(saveButton);
});
// save toolbar config on tool change (toolbar state is not saved in SVGs!)
this.editor.notifier.on(EditorEventType.ToolUpdated, () => {
this.toolbarFile.setContent(toolbar.serializeState());

View file

@ -105,11 +105,4 @@ export function imgSrcToIDs(imgSrc: string | null): { fileID: string; syncID: st
return assetPathToIDs(imgSrc);
}
export function validateColor(hex: string) {
hex = hex.replace('#', '');
return typeof hex === 'string'
&& hex.length === 6
&& !isNaN(Number('0x' + hex))
}