245 lines
7.4 KiB
TypeScript
245 lines
7.4 KiB
TypeScript
import { App, Editor, MarkdownView, Modal, Notice, ColorComponent, TextComponent, SliderComponent, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
|
|
|
interface PaperSettings {
|
|
paperType: 'grid' | 'lined' | 'bullet';
|
|
transparency: number;
|
|
colour: string; // Universal colour setting
|
|
}
|
|
|
|
interface GridSettings {
|
|
gridSize: number;
|
|
}
|
|
|
|
interface LinedSettings {
|
|
lineHeight: number;
|
|
}
|
|
|
|
interface BulletSettings {
|
|
dotSize: number;
|
|
dotSpacing: number;
|
|
}
|
|
|
|
interface PluginSettings {
|
|
paper: PaperSettings;
|
|
grid: GridSettings;
|
|
lined: LinedSettings;
|
|
bullet: BulletSettings;
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: PluginSettings = {
|
|
paper: {
|
|
paperType: 'grid',
|
|
transparency: 0.05,
|
|
colour: 'rgba(255, 255, 255, 1)',
|
|
},
|
|
grid: {
|
|
gridSize: 50,
|
|
},
|
|
lined: {
|
|
lineHeight: 20,
|
|
},
|
|
bullet: {
|
|
dotSize: 5,
|
|
dotSpacing: 20,
|
|
},
|
|
};
|
|
|
|
export default class GridBackgroundPlugin extends Plugin {
|
|
settings: PluginSettings;
|
|
|
|
async onload() {
|
|
await this.loadSettings();
|
|
this.injectCSS();
|
|
this.addSettingTab(new GridBackgroundSettingTab(this.app, this));
|
|
}
|
|
|
|
onunload() {
|
|
const style = document.getElementById('paper-background-style');
|
|
style?.remove();
|
|
}
|
|
|
|
injectCSS() {
|
|
const style = document.createElement('style');
|
|
style.id = 'paper-background-style';
|
|
|
|
let cssContent = '';
|
|
const { paperType, transparency, colour } = this.settings.paper;
|
|
|
|
// Ensure colour is valid and fallback to default if undefined or invalid
|
|
const validColour = colour && colour.match(/\d+, \d+, \d+/) ? colour : 'rgba(255, 255, 255, 1)';
|
|
|
|
if (paperType === 'grid') {
|
|
const { gridSize } = this.settings.grid;
|
|
cssContent = `
|
|
.markdown-source-view,
|
|
.markdown-preview-view {
|
|
background-image:
|
|
linear-gradient(to right, transparent ${gridSize - 1}px, rgba(${validColour.match(/\d+, \d+, \d+/)?.[0]}, ${transparency}) 1px),
|
|
linear-gradient(to bottom, transparent ${gridSize - 1}px, rgba(${validColour.match(/\d+, \d+, \d+/)?.[0]}, ${transparency}) 1px);
|
|
background-size: ${gridSize}px ${gridSize}px;
|
|
}
|
|
`;
|
|
} else if (paperType === 'lined') {
|
|
const { lineHeight } = this.settings.lined;
|
|
cssContent = `
|
|
.markdown-source-view,
|
|
.markdown-preview-view {
|
|
background-image: repeating-linear-gradient(
|
|
to bottom,
|
|
rgba(${validColour.match(/\d+, \d+, \d+/)?.[0]}, ${transparency}) 0px,
|
|
rgba(${validColour.match(/\d+, \d+, \d+/)?.[0]}, ${transparency}) 1px,
|
|
transparent 1px,
|
|
transparent ${lineHeight}px
|
|
);
|
|
}
|
|
`;
|
|
} else if (paperType === 'bullet') {
|
|
const { dotSize, dotSpacing } = this.settings.bullet;
|
|
cssContent = `
|
|
.markdown-source-view,
|
|
.markdown-preview-view {
|
|
background-image: radial-gradient(circle, rgba(${validColour.match(/\d+, \d+, \d+/)?.[0]}, ${transparency}) ${dotSize}px, transparent ${dotSize}px);
|
|
background-size: ${dotSpacing}px ${dotSpacing}px;
|
|
}
|
|
`;
|
|
}
|
|
|
|
style.textContent = cssContent;
|
|
document.head.appendChild(style);
|
|
}
|
|
|
|
async loadSettings() {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
}
|
|
|
|
async saveSettings() {
|
|
await this.saveData(this.settings);
|
|
this.onunload();
|
|
this.injectCSS();
|
|
}
|
|
}
|
|
|
|
class GridBackgroundSettingTab extends PluginSettingTab {
|
|
plugin: GridBackgroundPlugin;
|
|
sliderGridSize: SliderComponent;
|
|
|
|
|
|
constructor(app: App, plugin: GridBackgroundPlugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
display(): void {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
containerEl.createEl('h2', { text: 'Paper Background Settings' });
|
|
|
|
let pageColour: ColorComponent;
|
|
|
|
// Paper Type Selection
|
|
new Setting(containerEl)
|
|
.setName('Paper Type')
|
|
.setDesc('Select the type of paper background')
|
|
.addDropdown(dropdown => {
|
|
dropdown
|
|
.addOption('grid', 'Grid')
|
|
.addOption('lined', 'Lined')
|
|
.addOption('bullet', 'Bullet Journal')
|
|
.setValue(this.plugin.settings.paper.paperType)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.paper.paperType = value as 'grid' | 'lined' | 'bullet';
|
|
await this.plugin.saveSettings();
|
|
this.display();
|
|
});
|
|
});
|
|
|
|
// Universal Transparency Setting
|
|
new Setting(containerEl)
|
|
.setName('Transparency')
|
|
.setDesc('Set the transparency level (0 to 1)')
|
|
.addSlider(slider => {
|
|
slider
|
|
.setLimits(0, 1, 0.01)
|
|
.setValue(this.plugin.settings.paper.transparency)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.paper.transparency = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
|
|
// Universal Colour Setting
|
|
new Setting(containerEl)
|
|
.setName('Universal Colour')
|
|
.setDesc('Set the colour for the lines/dots/grids)')
|
|
.addColorPicker(colour => {
|
|
pageColour = colour;
|
|
colour
|
|
.setValue(this.plugin.settings.paper.colour)
|
|
.onChange(async (value) => {
|
|
let rgbValue: { r: number; g: number; b: number } = colour.getValueRgb();
|
|
|
|
const colourValue = `rgba(${rgbValue.r}, ${rgbValue.g}, ${rgbValue.b}, ${this.plugin.settings.paper.transparency})`;
|
|
console.log(colourValue)
|
|
this.plugin.settings.paper.colour = colourValue;
|
|
|
|
await this.plugin.saveSettings();
|
|
})
|
|
});
|
|
|
|
// Specific Settings Based on Paper Type
|
|
if (this.plugin.settings.paper.paperType === 'grid') {
|
|
new Setting(containerEl)
|
|
.setName('Grid Size')
|
|
.setDesc('Set the size of the grid (in px)')
|
|
.addSlider(slider => {
|
|
slider
|
|
.setLimits(20, 100, 1)
|
|
.setValue(this.plugin.settings.grid.gridSize)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.grid.gridSize = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
} else if (this.plugin.settings.paper.paperType === 'lined') {
|
|
new Setting(containerEl)
|
|
.setName('Line Height')
|
|
.setDesc('Set the height between lines (in px)')
|
|
.addSlider(slider => {
|
|
slider
|
|
.setLimits(10, 50, 1)
|
|
.setValue(this.plugin.settings.lined.lineHeight)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.lined.lineHeight = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
} else if (this.plugin.settings.paper.paperType === 'bullet') {
|
|
new Setting(containerEl)
|
|
.setName('Dot Size')
|
|
.setDesc('Set the size of the dots (in px)')
|
|
.addSlider(slider => {
|
|
slider
|
|
.setLimits(2, 10, 1)
|
|
.setValue(this.plugin.settings.bullet.dotSize)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.bullet.dotSize = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
|
|
new Setting(containerEl)
|
|
.setName('Dot Spacing')
|
|
.setDesc('Set the spacing between dots (in px)')
|
|
.addSlider(slider => {
|
|
slider
|
|
.setLimits(10, 50, 1)
|
|
.setValue(this.plugin.settings.bullet.dotSpacing)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.bullet.dotSpacing = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|