From fd256fcc6f4646b56064ace941bcaeaabcece741 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sat, 21 Jan 2017 23:39:41 +0300 Subject: [PATCH] the general functionality of the kb editor appears to be done and working (the changes are not yet saved)... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/keyboard.js | 124 +++++++++++++++++++++++-------- ui (gen4)/features/ui-widgets.js | 7 ++ ui (gen4)/lib/keyboard.js | 52 ++++++++++++- ui (gen4)/lib/util.js | 23 ++++-- ui (gen4)/lib/widget/browse.js | 61 +++++++-------- 5 files changed, 193 insertions(+), 74 deletions(-) diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index 9bda973b..ebc8b547 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -431,7 +431,13 @@ var KeyboardActions = actions.Actions({ var kb = this.__keyboard_object = this.__keyboard_object || keyboard.KeyboardWithCSSModes( - function(){ return that.__keyboard_config }, + function(data){ + if(data){ + that.__keyboard_config = data + } else { + return that.__keyboard_config + } + }, function(){ return that.ribbons.viewer }) return kb }, @@ -815,8 +821,7 @@ var KeyboardUIActions = actions.Actions({ widgets.makeUIDialog(function(path, options){ options = options || {} - var actions = this - var keybindings = this.keybindings + var that = this var kb = this.keyboard // get doc... @@ -832,6 +837,7 @@ var KeyboardUIActions = actions.Actions({ var dialog = browse.makeLister(null, function(path, make){ var keys = kb.keys('*') + var keybindings = that.keybindings Object.keys(keybindings) .forEach(function(mode){ @@ -867,7 +873,7 @@ var KeyboardUIActions = actions.Actions({ if(getKeyText){ var doc = '' - var text = getKeyText.call(actions, o) + var text = getKeyText.call(that, o) } else { var doc = o.doc @@ -880,7 +886,7 @@ var KeyboardUIActions = actions.Actions({ var hidden = !options.show_non_actions // hide all non-actions... - && !(o.action in actions + && !(o.action in that // except: functions represented by their doc... || keybindings[mode][action] == null && kb.handler(mode, keys[mode][action][0]) @@ -931,7 +937,7 @@ var KeyboardUIActions = actions.Actions({ ' special-action' : '') // aliases... - + (o.action in actions ? '' : ' non-action')) + + (o.action in that ? '' : ' non-action')) c++ }) @@ -1008,21 +1014,13 @@ var KeyboardUIActions = actions.Actions({ For more details see: .browseKeyboardBindings(..)`, widgets.uiDialog(function(path){ var that = this - var bindings = this.keybindings var sortModes = function(list){ - var ordered = {} - list.find('[mode]') - .map(function(){ return $(this).attr('mode')}) - .toArray() - .unique() - .forEach(function(mode){ - ordered[mode] = bindings[mode] - }) - // reorder only if we moved all the modes... - if(Object.keys(bindings).length == Object.keys(ordered).length){ - that.__keyboard_config = ordered - } + that.keyboard.sortModes( + list.find('[mode]') + .map(function(){ return $(this).attr('mode')}) + .toArray() + .unique()) } var dialog = this.browseKeyboardBindings( @@ -1131,11 +1129,12 @@ var KeyboardUIActions = actions.Actions({ }) return dialog })], - // XXX make fields editable... + // XXX add datalist... editKeyBinding: ['- Interface/Key mapping...', widgets.makeUIDialog(function(mode, code){ var that = this var abort = false + var orig_code = code // list the keys (cache)... var keys = that.keyboard.keys(code) @@ -1146,10 +1145,34 @@ var KeyboardUIActions = actions.Actions({ var dialog = browse.makeLister(null, function(path, make){ - // XXX make editable... + var cfg = { + start_on: 'open', + edit_text: 'last', + clear_on_edit: false, + reset_on_commit: false, + } + + // XXX make editable??? make(['Mode:', mode || '']) - // XXX make editable... - make(['Code:', code || '']) + + make.Editable(['Code:', code || ''], { + start_on: 'open', + edit_text: 'last', + clear_on_edit: false, + reset_on_commit: false, + buttons: [ + ['⋯', function(evt, elem){ + var dialog = that.listDialog(that.actions) + .on('open', function(evt, action){ + code = action + elem.find('.text').last().text(action) + dialog.close() + }) + }], + ], + }) + .on('edit-commit', + function(evt, text){ code = text }) make('---') @@ -1172,8 +1195,6 @@ var KeyboardUIActions = actions.Actions({ cls: 'metadata-view', }) // save the keys... - // XXX at this point this does not account for changes - // in mode or code... .on('close', function(){ if(abort){ return @@ -1186,28 +1207,45 @@ var KeyboardUIActions = actions.Actions({ that.keyHandler(mode, k, '') }) + keys = code == orig_code ? + keys.filter(function(k){ orig_keys.indexOf(k) < 0 }) + : keys + // add keys... keys - .filter(function(k){ return orig_keys.indexOf(k) < 0 }) .forEach(function(k){ - that.keyHandler(mode, k, code) - }) + that.keyHandler(mode, k, code) }) }) return dialog })], - // XXX make fields editable... editKeyboardMode: ['- Interface/Mode...', widgets.makeUIDialog(function(mode){ var that = this var abort = false + var doc = (that.keybindings[mode] || {}).doc + var pattern = (that.keybindings[mode] || {}).pattern || mode + + var orig_mode = mode var dialog = browse.makeLister(null, function(path, make){ - // XXX make these editable.... - make(['Mode:', mode || '']) - make(['Doc:', (that.keybindings[mode] || {}).doc || '']) - make(['Pattern:', (that.keybindings[mode] || {}).pattern || mode]) + var cfg = { + start_on: 'open', + edit_text: 'last', + clear_on_edit: false, + reset_on_commit: false, + } + + make.Editable(['Mode:', mode || ''], cfg) + .on('edit-commit', + function(evt, text){ mode = text }) + make.Editable(['Doc:', doc || ''], cfg) + .on('edit-commit', + function(evt, text){ doc = text }) + make.Editable(['Pattern:', pattern], cfg) + .on('edit-commit', + function(evt, text){ pattern = text }) make('---') @@ -1230,6 +1268,26 @@ var KeyboardUIActions = actions.Actions({ { cls: 'metadata-view', }) + .on('close', function(){ + if(abort){ + return + } + + that.keybindings[orig_mode].doc = doc + that.keybindings[orig_mode].pattern = pattern + + // update mode name if it changed... + if(mode != orig_mode){ + var order = Object.keys(that.keybindings) + order[order.indexOf(orig_mode)] = mode + + var data = that.keybindings[orig_mode] + delete that.keybindings[orig_mode] + that.keybindings[mode] = data + + that.keyboard.sortModes(order) + } + }) return dialog })], diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index 1ae07fd8..f3a95298 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -522,7 +522,14 @@ var DialogsActions = actions.Actions({ return panel })], + + listDialog: ['- Interface/', + makeUIDialog(function(list, options){ + + return browse.makeList(null, list, options) + })], + listDialogs: ['Interface/Dialog/Dialog list...', makeUIDialog(function(){ var actions = this diff --git a/ui (gen4)/lib/keyboard.js b/ui (gen4)/lib/keyboard.js index 4e6ccfe0..6850f57c 100755 --- a/ui (gen4)/lib/keyboard.js +++ b/ui (gen4)/lib/keyboard.js @@ -466,13 +466,21 @@ var KeyboardPrototype = { // - NEXT - force check next section, this has priority // over .drop // + // NOTE: if .__keyboard is set to a function, it will be used both as + // a getter and as a setter via the .keyboard prop, to overwrite + // write to .__keyboard directly... __keyboard: null, get keyboard(){ return this.__keyboard instanceof Function ? this.__keyboard() : this.__keyboard }, set keyboard(value){ - this.__keyboard = value }, + if(this.__keyboard instanceof Function){ + this.__keyboard(value) + } else { + this.__keyboard = value + } + }, // XXX is this needed??? //context: null, @@ -495,6 +503,48 @@ var KeyboardPrototype = { merge: function(){ }, + + // Sort modes... + // + // Sort via cmp function... + // .sortModes(func) + // -> this + // + // Sort to the same order as list... + // .sortModes(list) + // -> this + // + // + // NOTE: calling this with no arguments will have no effect. + // + // XXX should this update the kb in-place??? + sortModes: function(cmp){ + var ordered = {} + var bindings = this.keyboard + + if(cmp == null){ + return + } + + cmp = cmp instanceof Function ? + Object.keys(bindings).sort(cmp) + : cmp + .concat(Object.keys(bindings)) + .unique() + + cmp + .forEach(function(mode){ + ordered[mode] = bindings[mode] + }) + + // reorder only if we moved all the modes... + if(Object.keys(bindings).length == Object.keys(ordered).length){ + this.keyboard = ordered + } + + return this + }, + // Get keys for handler... // // List all handlers... diff --git a/ui (gen4)/lib/util.js b/ui (gen4)/lib/util.js index e9036135..ed4e8106 100755 --- a/ui (gen4)/lib/util.js +++ b/ui (gen4)/lib/util.js @@ -404,6 +404,17 @@ if(typeof(jQuery) != typeof(undefined)){ // 'edit-abort' - will reset field, this is passed the // original text before the edit. // + // These events get passed the relevant text, but the element is + // likely to be already reset to a different state, to get the + // element before any state change is started use one of the + // following variants: + // 'edit-committing' - triggered within 'edit-commit' but before + // anything is changed, gets passed the final + // text (same as 'edit-commit') + // 'edit-aborting' - triggered within 'edit-abort' but before + // anything is changed, gets passed the + // original text value (same as 'edit-abort') + // // // NOTE: removing tabindex will reset focus, so this will attempt to // focus the first [tabindex] element up the tree... @@ -476,7 +487,7 @@ if(typeof(jQuery) != typeof(undefined)){ that.trigger('edit-commit', that.text()) - // done -- multiline... + // done -- multi-line... } else if(n == 'Enter' && (event.ctrlKey || event.metaKey) && options.multiline){ @@ -500,14 +511,15 @@ if(typeof(jQuery) != typeof(undefined)){ .selectText() }) // user triggerable events... - .on('edit-abort', events['edit-abort'] = function(){ + .on('edit-abort', events['edit-abort'] = function(evt, text){ + that.trigger('edit-aborting', text) + options.clear_selection_on_abort !== false && window.getSelection().removeAllRanges() // reset original value... options.reset_on_abort !== false && that.text(original) - options.blur_on_abort !== false && this.blur() @@ -517,14 +529,15 @@ if(typeof(jQuery) != typeof(undefined)){ that.makeEditable(false) }) - .on('edit-commit', events['edit-commit'] = function(){ + .on('edit-commit', events['edit-commit'] = function(evt, text){ + that.trigger('edit-committing', text) + options.clear_selection_on_commit !== false && window.getSelection().removeAllRanges() // reset original value... options.reset_on_commit !== false && that.text(original) - options.blur_on_commit !== false && this.blur() diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index 956eb313..b814385b 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -204,35 +204,37 @@ Items.Editable = function(text, options){ options = options || {} var dialog = this.dialog - var editable var start_on = options.start_on || 'select' - var elem = (options.action ? this.Action : this).call(this, text, options) - .on(start_on, function(){ - editable = elem.find('.text') + var getEditable = function(){ + var editable = elem.find('.text') + // get the specific .text element... + // index... + return typeof(options.edit_text) == typeof(123) ? + editable.eq(options.edit_text) + // first/last... + : (options.edit_text == 'first' || options.edit_text == 'last') ? + editable[options.edit_text]() + // selecter... + : typeof(options.edit_text) == typeof('str') ? + editable.filter(options.edit_text) + // all... + : editable } - // get the specific .text element... - editable = - // index... - typeof(options.edit_text) == typeof(123) ? - editable.eq(options.edit_text) - // first/last... - : (options.edit_text == 'first' || options.edit_text == 'last') ? - editable[options.edit_text]() - // selecter... - : typeof(options.edit_text) == typeof('str') ? - editable.filter(options.edit_text) - // all... - : editable + var elem = (options.action ? this.Action : this).call(this, text, options) + .on(start_on, function(evt){ + event.preventDefault() // edit the element... - editable + var editable = getEditable() .makeEditable({ activate: true, - clear_on_edit: options.clear_on_edit, blur_on_abort: false, blur_on_commit: false, multiline: options.multiline, + clear_on_edit: options.clear_on_edit, + reset_on_commit: options.reset_on_commit, + reset_on_abort: options.reset_on_abort, }) // deselect on abort -- if we started with a select... @@ -248,24 +250,15 @@ function(text, options){ && editable.on('edit-commit', options.editdone) }) .on('deselect', function(){ - editable.trigger( - options.abort_on_deselect !== false ? 'edit-abort' : 'edit-commit') + //editable && editable.trigger( + getEditable() + .trigger( + options.abort_on_deselect !== false ? 'edit-abort' : 'edit-commit') }) return elem } -// XXX -Items.SelectableField = -function(text, options){ -} - -// XXX -Items.EditableField = -function(text, options){ - // XXX -} - // Make list of elements... // @@ -478,9 +471,7 @@ function(list, options){ clear_on_edit: true, }) // update list on edit done... - .on('edit-commit', function(evt, text){ - var txt = $(this).text() - + .on('edit-commit', function(evt, txt){ txt = options.normalize ? options.normalize(txt) : txt