keyboard shortcuts for ribbon tabs

This commit is contained in:
zadam 2021-06-27 12:53:05 +02:00
parent 9e1c9782ff
commit 0351d7eff1
17 changed files with 195 additions and 38 deletions

3
TODO
View File

@ -1,7 +1,4 @@
- all ribbon tabs should have assignable shortcut - all ribbon tabs should have assignable shortcut
- new icon - new icon
- green theme
- polish becca entities API - polish becca entities API
- separate private and public APIs in becca entities - separate private and public APIs in becca entities
- handle FIXMEs
- fix Steel Blue example

View File

@ -3,3 +3,8 @@
- isDeleted = 0 by default - isDeleted = 0 by default
- rename openTabs to openNoteContexts - rename openTabs to openNoteContexts
- migrate black theme to dark theme - migrate black theme to dark theme
- unify readOnly handling to a single attribute:
* readOnly - like now
* readOnly=auto - like without readOnly (used to override inherited readOnly)
* readOnly=never - like autoReadOnlyDisabled
- remove focusOnAttributesKeyboardShortcut

View File

@ -161,6 +161,11 @@ export default class RibbonContainer extends NoteContextAwareWidget {
this.$tabContainer.on('click', '.ribbon-tab-title', e => { this.$tabContainer.on('click', '.ribbon-tab-title', e => {
const $ribbonTitle = $(e.target).closest('.ribbon-tab-title'); const $ribbonTitle = $(e.target).closest('.ribbon-tab-title');
this.toggleRibbonTab($ribbonTitle);
});
}
toggleRibbonTab($ribbonTitle) {
const activate = !$ribbonTitle.hasClass("active"); const activate = !$ribbonTitle.hasClass("active");
this.$tabContainer.find('.ribbon-tab-title').removeClass("active"); this.$tabContainer.find('.ribbon-tab-title').removeClass("active");
@ -179,11 +184,9 @@ export default class RibbonContainer extends NoteContextAwareWidget {
if (activeChild) { if (activeChild) {
activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath}); activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath});
} }
} } else {
else {
this.lastActiveComponentId = null; this.lastActiveComponentId = null;
} }
});
} }
async refreshWithNote(note, noExplicitActivation = false) { async refreshWithNote(note, noExplicitActivation = false) {
@ -202,6 +205,7 @@ export default class RibbonContainer extends NoteContextAwareWidget {
const $ribbonTitle = $('<div class="ribbon-tab-title">') const $ribbonTitle = $('<div class="ribbon-tab-title">')
.attr('data-ribbon-component-id', ribbonWidget.componentId) .attr('data-ribbon-component-id', ribbonWidget.componentId)
.attr('data-ribbon-component-name', ribbonWidget.name)
.append($('<span class="ribbon-tab-title-icon">') .append($('<span class="ribbon-tab-title-icon">')
.addClass(ret.icon) .addClass(ret.icon)
.attr("title", ret.title)) .attr("title", ret.title))
@ -234,10 +238,56 @@ export default class RibbonContainer extends NoteContextAwareWidget {
} }
} }
isRibbonTabActive(name) {
const $ribbonComponent = this.$widget.find(`.ribbon-tab-title[data-ribbon-component-name='${name}']`);
return $ribbonComponent.hasClass("active");
}
refreshRibbonContainerCommand() { refreshRibbonContainerCommand() {
this.refreshWithNote(this.note, true); this.refreshWithNote(this.note, true);
} }
ensureOwnedAttributesAreOpen(ntxId) {
if (this.isNoteContext(ntxId) && !this.isRibbonTabActive('ownedAttributes')) {
this.toggleRibbonTabWithName('ownedAttributes', ntxId);
}
}
addNewLabelEvent({ntxId}) {
this.ensureOwnedAttributesAreOpen(ntxId);
}
addNewRelationEvent({ntxId}) {
this.ensureOwnedAttributesAreOpen(ntxId);
}
toggleRibbonTabWithName(name, ntxId) {
if (!this.isNoteContext(ntxId)) {
return false;
}
const $ribbonComponent = this.$widget.find(`.ribbon-tab-title[data-ribbon-component-name='${name}']`);
if ($ribbonComponent) {
this.toggleRibbonTab($ribbonComponent);
}
}
handleEvent(name, data) {
const PREFIX = "toggleRibbonTab";
if (name.startsWith(PREFIX)) {
let componentName = name.substr(PREFIX.length);
componentName = componentName[0].toLowerCase() + componentName.substr(1);
this.toggleRibbonTabWithName(componentName, data.ntxId);
}
else {
return super.handleEvent(name, data);
}
}
async handleEventInChildren(name, data) { async handleEventInChildren(name, data) {
if (['activeContextChanged', 'setNoteContext'].includes(name)) { if (['activeContextChanged', 'setNoteContext'].includes(name)) {
// won't trigger .refresh(); // won't trigger .refresh();

View File

@ -46,6 +46,10 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
this.child(this.noteTypeWidget, this.protectedNoteSwitchWidget, this.editabilitySelectWidget); this.child(this.noteTypeWidget, this.protectedNoteSwitchWidget, this.editabilitySelectWidget);
} }
get name() {
return "basicProperties";
}
isEnabled() { isEnabled() {
return this.note && (this.note.type === 'text' || this.note.type === 'code'); return this.note && (this.note.type === 'text' || this.note.type === 'code');
} }

View File

@ -42,6 +42,10 @@ const TPL = `
</div> </div>
`; `;
export default class BookPropertiesWidget extends NoteContextAwareWidget { export default class BookPropertiesWidget extends NoteContextAwareWidget {
get name() {
return "bookProperties";
}
isEnabled() { isEnabled() {
return this.note && this.note.type === 'book'; return this.note && this.note.type === 'book';
} }

View File

@ -55,6 +55,10 @@ const TPL = `
</div>`; </div>`;
export default class FilePropertiesWidget extends NoteContextAwareWidget { export default class FilePropertiesWidget extends NoteContextAwareWidget {
get name() {
return "fileProperties";
}
isEnabled() { isEnabled() {
return this.note && this.note.type === 'file'; return this.note && this.note.type === 'file';
} }

View File

@ -37,6 +37,10 @@ const TPL = `
</div>`; </div>`;
export default class ImagePropertiesWidget extends NoteContextAwareWidget { export default class ImagePropertiesWidget extends NoteContextAwareWidget {
get name() {
return "imageProperties";
}
isEnabled() { isEnabled() {
return this.note && this.note.type === 'image'; return this.note && this.note.type === 'image';
} }

View File

@ -21,6 +21,10 @@ const TPL = `
</div>`; </div>`;
export default class InheritedAttributesWidget extends NoteContextAwareWidget { export default class InheritedAttributesWidget extends NoteContextAwareWidget {
get name() {
return "inheritedAttributes";
}
constructor() { constructor() {
super(); super();

View File

@ -38,6 +38,10 @@ const TPL = `
</div>`; </div>`;
export default class LinkMapWidget extends NoteContextAwareWidget { export default class LinkMapWidget extends NoteContextAwareWidget {
get name() {
return "linkMap";
}
isEnabled() { isEnabled() {
return this.note; return this.note;
} }

View File

@ -62,6 +62,10 @@ const TPL = `
</div> </div>
`; `;
export default class NoteInfoWidget extends NoteContextAwareWidget { export default class NoteInfoWidget extends NoteContextAwareWidget {
get name() {
return "noteInfo";
}
isEnabled() { isEnabled() {
return this.note; return this.note;
} }

View File

@ -36,6 +36,10 @@ const TPL = `
</div>`; </div>`;
export default class NotePathsWidget extends NoteContextAwareWidget { export default class NotePathsWidget extends NoteContextAwareWidget {
get name() {
return "notePaths";
}
isEnabled() { isEnabled() {
return this.note; return this.note;
} }

View File

@ -14,6 +14,9 @@ const TPL = `
</div> </div>
</div>`; </div>`;
/**
* TODO: figure out better name or conceptualize better.
*/
export default class NotePropertiesWidget extends NoteContextAwareWidget { export default class NotePropertiesWidget extends NoteContextAwareWidget {
isEnabled() { isEnabled() {
return this.note && !!this.note.getLabelValue('pageUrl'); return this.note && !!this.note.getLabelValue('pageUrl');

View File

@ -22,6 +22,10 @@ const TPL = `
`; `;
export default class OwnedAttributeListWidget extends NoteContextAwareWidget { export default class OwnedAttributeListWidget extends NoteContextAwareWidget {
get name() {
return "ownedAttributes";
}
constructor() { constructor() {
super(); super();

View File

@ -35,6 +35,10 @@ const TPL = `
`; `;
export default class PromotedAttributesWidget extends NoteContextAwareWidget { export default class PromotedAttributesWidget extends NoteContextAwareWidget {
get name() {
return "promotedAttributes";
}
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.contentSized(); this.contentSized();

View File

@ -23,7 +23,6 @@ import Limit from "../search_options/limit.js";
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js"; import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
import Debug from "../search_options/debug.js"; import Debug from "../search_options/debug.js";
import appContext from "../../services/app_context.js"; import appContext from "../../services/app_context.js";
import toast from "../../services/toast.js";
const TPL = ` const TPL = `
<div class="search-definition-widget"> <div class="search-definition-widget">

View File

@ -31,6 +31,10 @@ const TPL = `
`; `;
export default class SimilarNotesWidget extends NoteContextAwareWidget { export default class SimilarNotesWidget extends NoteContextAwareWidget {
get name() {
return "similarNotes";
}
isEnabled() { isEnabled() {
return super.isEnabled() return super.isEnabled()
&& this.note.type !== 'search' && this.note.type !== 'search'

View File

@ -236,12 +236,6 @@ const DEFAULT_KEYBOARD_ACTIONS = [
description: "Shows Note Source dialog", description: "Shows Note Source dialog",
scope: "window" scope: "window"
}, },
{
actionName: "showLinkMap",
defaultShortcuts: [],
description: "Shows Link Map dialog",
scope: "window"
},
{ {
actionName: "showOptions", actionName: "showOptions",
defaultShortcuts: [], defaultShortcuts: [],
@ -324,12 +318,6 @@ const DEFAULT_KEYBOARD_ACTIONS = [
separator: "Attributes (labels & relations)" separator: "Attributes (labels & relations)"
}, },
{
actionName: "focusOnAttributes",
defaultShortcuts: ["Alt+A"],
description: "Put focus into attribute editor",
scope: "window"
},
{ {
actionName: "addNewLabel", actionName: "addNewLabel",
defaultShortcuts: ["Alt+L"], defaultShortcuts: ["Alt+L"],
@ -343,6 +331,77 @@ const DEFAULT_KEYBOARD_ACTIONS = [
scope: "window" scope: "window"
}, },
{
separator: "Ribbon tabs"
},
{
actionName: "toggleRibbonTabBasicProperties",
defaultShortcuts: [],
description: "Toggle Basic Properties",
scope: "window"
},
{
actionName: "toggleRibbonTabBookProperties",
defaultShortcuts: [],
description: "Toggle Book Properties",
scope: "window"
},
{
actionName: "toggleRibbonTabFileProperties",
defaultShortcuts: [],
description: "Toggle File Properties",
scope: "window"
},
{
actionName: "toggleRibbonTabImageProperties",
defaultShortcuts: [],
description: "Toggle Image Properties",
scope: "window"
},
{
actionName: "toggleRibbonTabOwnedAttributes",
defaultShortcuts: ["Alt+A"],
description: "Toggle Owned Attributes",
scope: "window"
},
{
actionName: "toggleRibbonTabInheritedAttributes",
defaultShortcuts: [],
description: "Toggle Inherited Attributes",
scope: "window"
},
{
actionName: "toggleRibbonTabPromotedAttributes",
defaultShortcuts: [],
description: "Toggle Promoted Attributes",
scope: "window"
},
{
actionName: "toggleRibbonTabLinkMap",
defaultShortcuts: [],
description: "Toggle Link Map",
scope: "window"
},
{
actionName: "toggleRibbonTabNoteInfo",
defaultShortcuts: [],
description: "Toggle Note Info",
scope: "window"
},
{
actionName: "toggleRibbonTabNotePaths",
defaultShortcuts: [],
description: "Toggle Note Paths",
scope: "window"
},
{
actionName: "toggleRibbonTabSimilarNotes",
defaultShortcuts: [],
description: "Toggle Similar Notes",
scope: "window"
},
{ {
separator: "Other" separator: "Other"
}, },