mirror of
https://github.com/viliusle/miniPaint.git
synced 2026-02-06 13:36:45 +00:00
#204 - global search
This commit is contained in:
parent
b7a8e5eb9a
commit
fa6d7b69c7
7
package-lock.json
generated
7
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "miniPaint",
|
||||
"version": "4.7.1",
|
||||
"version": "4.8.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -2937,6 +2937,11 @@
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"fuzzysort": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz",
|
||||
"integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ=="
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"blueimp-canvas-to-blob": "^3.28.0",
|
||||
"exif-js": "^2.3.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"fuzzysort": "^1.1.4",
|
||||
"gif.js.optimized": "^1.0.1",
|
||||
"hermite-resize": "git+https://github.com/viliusle/Hermite-resize.git",
|
||||
"jquery": "^3.5.1",
|
||||
|
||||
@ -709,3 +709,24 @@ button img{
|
||||
background-color: var(--background-color-active);
|
||||
color: var(--text-color-active);
|
||||
}
|
||||
|
||||
/* global search */
|
||||
#global_search_results{
|
||||
padding-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
#global_search_results .search-result {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
#global_search_results .search-result.active{
|
||||
background-color: var(--background-color-active);
|
||||
color: var(--text-color-active);
|
||||
border-radius: 2px;
|
||||
}
|
||||
#global_search_results b{
|
||||
color: var(--text-color-red);
|
||||
}
|
||||
|
||||
.popup.shortcuts table{
|
||||
line-height: 1;
|
||||
}
|
||||
@ -722,6 +722,12 @@ const menuDefinition = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Search',
|
||||
shortcut: 'F3',
|
||||
ellipsis: true,
|
||||
target: 'tools/search.search'
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
ellipsis: true,
|
||||
|
||||
166
src/js/core/base-search.js
Normal file
166
src/js/core/base-search.js
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* miniPaint - https://github.com/viliusle/miniPaint
|
||||
* author: Vilius L.
|
||||
*/
|
||||
|
||||
import config from './../config.js';
|
||||
import Dialog_class from './../libs/popup.js';
|
||||
import Base_gui_class from './base-gui.js';
|
||||
const fuzzysort = require('fuzzysort');
|
||||
|
||||
var instance = null;
|
||||
|
||||
class Base_search_class {
|
||||
|
||||
constructor() {
|
||||
//singleton
|
||||
if (instance) {
|
||||
return instance;
|
||||
}
|
||||
instance = this;
|
||||
|
||||
this.POP = new Dialog_class();
|
||||
this.Base_gui = new Base_gui_class();
|
||||
this.db = null;
|
||||
|
||||
this.events();
|
||||
}
|
||||
|
||||
events() {
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (this.POP.get_active_instances() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var code = event.key.toLowerCase();
|
||||
if (code == "f3") {
|
||||
//open
|
||||
this.search();
|
||||
event.preventDefault();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener('input', (event) => {
|
||||
if(document.querySelector('#pop_data_search') == null){
|
||||
return;
|
||||
}
|
||||
|
||||
var node = document.querySelector('#global_search_results');
|
||||
node.innerHTML = '';
|
||||
|
||||
var query = event.target.value;
|
||||
if(query == ''){
|
||||
return;
|
||||
}
|
||||
|
||||
let results = fuzzysort.go(query, this.db, {
|
||||
keys: ['title'],
|
||||
limit: 10,
|
||||
threshold: -50000,
|
||||
});
|
||||
|
||||
//show
|
||||
for(var i = 0; i < results.length; i++) {
|
||||
var item = results[i];
|
||||
|
||||
var className = "search-result n" + (i+1);
|
||||
if(i == 0){
|
||||
className += " active";
|
||||
}
|
||||
|
||||
node.innerHTML += "<div class='"+className+"' data-key='"+item.obj.key+"'>"
|
||||
+ fuzzysort.highlight(item[0]) + "</div>";
|
||||
}
|
||||
}, false);
|
||||
|
||||
//allow to select with arrow keys
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if(document.querySelector('#global_search_results') == null
|
||||
|| document.querySelector('.search-result') == null){
|
||||
return;
|
||||
}
|
||||
var k = e.key;
|
||||
|
||||
if (k == "ArrowUp") {
|
||||
var target = document.querySelector('.search-result.active');
|
||||
var index = Array.from(target.parentNode.children).indexOf(target);
|
||||
if(index > 0){
|
||||
index--;
|
||||
}
|
||||
target.classList.remove('active');
|
||||
var target2 =document.querySelector('#global_search_results').childNodes[index];
|
||||
target2.classList.add('active');
|
||||
e.preventDefault();
|
||||
}
|
||||
else if (k == "ArrowDown") {
|
||||
var target = document.querySelector('.search-result.active');
|
||||
var index = Array.from(target.parentNode.children).indexOf(target);
|
||||
var total = target.parentNode.childElementCount;
|
||||
if(index < total - 1){
|
||||
index++;
|
||||
}
|
||||
target.classList.remove('active');
|
||||
var target2 = document.querySelector('#global_search_results').childNodes[index];
|
||||
target2.classList.add('active');
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
||||
search() {
|
||||
var _this = this;
|
||||
|
||||
//init DB
|
||||
if(this.db === null) {
|
||||
this.db = Object.keys(this.Base_gui.modules);
|
||||
for(var i in this.db){
|
||||
this.db[i] = {
|
||||
key: this.db[i],
|
||||
title: this.db[i].replace(/_/i, ' '),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var settings = {
|
||||
title: 'Search',
|
||||
params: [
|
||||
{name: "search", title: "Search:", value: ""},
|
||||
],
|
||||
on_load: function (params, popup) {
|
||||
var node = document.createElement("div");
|
||||
node.id = 'global_search_results';
|
||||
node.innerHTML = '';
|
||||
popup.el.querySelector('.dialog_content').appendChild(node);
|
||||
},
|
||||
on_finish: function (params) {
|
||||
//execute
|
||||
var target = document.querySelector('.search-result.active');
|
||||
if(target){
|
||||
//execute
|
||||
var key = target.dataset.key;
|
||||
var class_object = this.Base_gui.modules[key];
|
||||
var function_name = _this.get_function_from_path(key);
|
||||
|
||||
_this.POP.hide();
|
||||
class_object[function_name]();
|
||||
}
|
||||
},
|
||||
};
|
||||
this.POP.show(settings);
|
||||
|
||||
//on input change
|
||||
document.getElementById("pop_data_search").select();
|
||||
}
|
||||
|
||||
get_function_from_path(path){
|
||||
var parts = path.split("/");
|
||||
var result = parts[parts.length - 1];
|
||||
result = result.replace(/-/, '_');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Base_search_class;
|
||||
@ -181,9 +181,7 @@ class Dialog_class {
|
||||
|
||||
if (code == "Escape") {
|
||||
//escape
|
||||
if (window.POP === this) {
|
||||
this.hide(false);
|
||||
}
|
||||
this.hide(false);
|
||||
}
|
||||
}, false);
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import Base_gui_class from './core/base-gui.js';
|
||||
import Base_layers_class from './core/base-layers.js';
|
||||
import Base_tools_class from './core/base-tools.js';
|
||||
import Base_state_class from './core/base-state.js';
|
||||
import Base_search_class from './core/base-search.js';
|
||||
import File_open_class from './modules/file/open.js';
|
||||
import File_save_class from './modules/file/save.js';
|
||||
import * as Actions from './actions/index.js';
|
||||
@ -31,6 +32,7 @@ window.addEventListener('load', function (e) {
|
||||
var Base_state = new Base_state_class();
|
||||
var File_open = new File_open_class();
|
||||
var File_save = new File_save_class();
|
||||
var Base_search = new Base_search_class();
|
||||
|
||||
// Register singletons in app module
|
||||
app.Actions = Actions;
|
||||
|
||||
@ -10,8 +10,10 @@ class Help_shortcuts_class {
|
||||
shortcuts() {
|
||||
var settings = {
|
||||
title: 'Keyboard Shortcuts',
|
||||
className: 'shortcuts',
|
||||
params: [
|
||||
{title: "F", value: 'Auto Adjust Colors'},
|
||||
{title: "F3", value: 'Search'},
|
||||
{title: "Ctrl + C", value: 'Copy to Clipboard'},
|
||||
{title: "D", value: 'Duplicate'},
|
||||
{title: "S", value: 'Export'},
|
||||
|
||||
15
src/js/modules/tools/search.js
Normal file
15
src/js/modules/tools/search.js
Normal file
@ -0,0 +1,15 @@
|
||||
import Base_search_class from './../../core/base-search.js';
|
||||
|
||||
class Tools_search_class {
|
||||
|
||||
constructor() {
|
||||
this.Base_search = new Base_search_class();
|
||||
}
|
||||
|
||||
search() {
|
||||
this.Base_search.search();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Tools_search_class;
|
||||
Loading…
Reference in New Issue
Block a user