Keyboard shortcuts menu #1331

Closed
matthewkastor opened this Issue Mar 28, 2013 · 5 comments

Comments

Projects
None yet
2 participants
Contributor

matthewkastor commented Mar 28, 2013

Keyboard Shortcuts Menu

I've got a function that generates an ugly keyboard shortcuts menu. I don't know where to integrate this code into Ace but, there should be some way for end users to discover the many keyboard shortcuts without digging through the console in their browser. I know that this generated help menu is ugly, it's a start though.

Should Ace have any help menus? Settings menu? I've got a settings menu that works well but it's just as ugly as this menu. I would need help integrating it into Ace if anyone is interested. Take a look at the working example, https://github.com/atropa/atropa-ide and let me know.

Usage

aceShowKeybordShortcuts (editor);

Code

// this function makes an ugly div to display the contentElement
var overlayPage = function (contentElement, top, right, bottom, left) {
    "use strict";
    var div = document.createElement('div');
    var contentContainer = document.createElement('div');
    contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' +
        'overflow: auto;';
    contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;';
    contentContainer.appendChild(contentElement);

    var cl = document.createElement('img');
    if (top) {
        top = 'top: ' + top + ';';
    } else {
        top = '';
    }
    if (right) {
        right = 'right: ' + right + ';';
    } else {
        right = '';
    }
    if (bottom) {
        bottom = 'bottom: ' + bottom + ';';
    } else {
        bottom = '';
    }
    if (left) {
        left = 'left: ' + left + ';';
    } else {
        left = '';
    }

    cl.src = '/BigRedX.png';
    cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' +
        'float: right; width: 25px; height: 25px; border: 1px solid black;';
    div.style.cssText = 'margin:0; padding:0; position: absolute;' +
        top + right + bottom + left +
        'z-index:9999; background-color:white; color:black; overflow: auto;';

    div.appendChild(cl);
    div.appendChild(contentContainer);
    document.body.appendChild(div);

    cl.addEventListener('click', function (e) {
        div.parentNode.removeChild(div);
        div = null;
    });
};

// this function grabs all of the editor commands that have keyboard shortcuts
// then it creates a dictionary list of commands and shortcuts.
function aceShowKeybordShortcuts (editor) {
    "use strict";
    var el = document.createElement('div');
    var commandName;
    el.innerHTML = '<h1>Keyboard Shortcuts</h1><dl>';
    for (commandName in editor.commands.byName) {
        if (editor.commands.byName[commandName].bindKey) {
            el.innerHTML += '<dt>' + commandName + '</dt>' +
            '<dd>Win: ' + editor.commands.byName[commandName].bindKey.win +
            '<br/>Mac: ' + editor.commands.byName[commandName].bindKey.mac + '</dd>';
        }
    }
    el.innerHTML += '</dl>';

    el.style.cssText = 'margin:0; padding:0; background-color:white; color:black; ' +
        'white-space: pre-wrap;';
    overlayPage(el, '0', '0', '0', null);
};
Member

nightwing commented Mar 28, 2013

Both keyboard shortcuts menu and options menu are useful. Would be good to have them in ext/options_panel.js and use it for option menus in ext/textarea and demo/kitchen-sink/.
This is a good start but very rough and requires lots of tweaking before adding into ace.
I think it will be better to display only keybindings for current platform.
Also it might be easier to display json document inside the editor, similar to what sublime does.

Contributor

matthewkastor commented Mar 28, 2013

I didn't see options_panel.js anywhere. I would need some help making it myself because I don't know how to write plugins for Ace.

The textarea demo has a nice looking menu so I thought there would be some stylesheets or built in framework for doing this sort of stuff. I'll be the first to admit how very ugly and hackish my menu looks. :D

The keybindings could easily be filtered for the current platform using editor.commands.platform.

I've refactored it a bit to give the keybindings for the current platform and display a JSON thing. I'm not sure what you meant exactly since I don't use sublime so I've got a function returning an array of objects that could be fed into any templating system like mustache or something. Then we could ditch my crappy overlay box and make it all shiny like. :D

Tell me what you think of aceGetKeyboardShortcuts

Usage

aceShowKeybordShortcuts (editor); // to show it on screen
aceGetKeybordShortcuts (editor); // to get an object suitable for template engines.

Code

// this function makes an ugly div to display the contentElement
var overlayPage = function (contentElement, top, right, bottom, left) {
    "use strict";
    var div = document.createElement('div');
    var contentContainer = document.createElement('div');
    contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' +
        'overflow: auto;';
    contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;';
    contentContainer.appendChild(contentElement);

    var cl = document.createElement('img');
    if (top) {
        top = 'top: ' + top + ';';
    } else {
        top = '';
    }
    if (right) {
        right = 'right: ' + right + ';';
    } else {
        right = '';
    }
    if (bottom) {
        bottom = 'bottom: ' + bottom + ';';
    } else {
        bottom = '';
    }
    if (left) {
        left = 'left: ' + left + ';';
    } else {
        left = '';
    }

    cl.src = '/BigRedX.png';
    cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' +
        'float: right; width: 25px; height: 25px; border: 1px solid black;';
    div.style.cssText = 'margin:0; padding:0; position: absolute;' +
        top + right + bottom + left +
        'z-index:9999; background-color:white; color:black; overflow: auto;';

    div.appendChild(cl);
    div.appendChild(contentContainer);
    document.body.appendChild(div);

    cl.addEventListener('click', function (e) {
        div.parentNode.removeChild(div);
        div = null;
    });
};

// this function grabs all of the editor commands that have keyboard shortcuts
function aceGetKeybordShortcuts (editor) {
    "use strict";
    var commands = editor.commands.byName;
    var commandName;
    var key;
    var platform = editor.commands.platform;
    var kb = [];
    for (commandName in commands) {
        try {
            key = commands[commandName].bindKey[platform];
            if (key) {
               kb.push({
                    'command' : commandName,
                    'key' : key
               });
            }
        } catch (e) {
            // errors on properties without bindKey we don't want them
            // so the errors don't need handling.
        }
    }
    return kb;
}

// this function takes the keyboard shortcuts array and 
// runs it through some template.
function aceShowKeyboardShortcuts(editor) {
    var kb = aceGetKeybordShortcuts(editor);
    var el = document.createElement('div');
    // untested. something like this could . . . 
    // var template = '<h1>Keyboard Shortcuts</h1><div>' +
    //     {{#kb}}
    //         {{{command}}} : {{{key}}}
    //     {{/kb}}
    //     '</div>';
    // mustache.render({'kb' : kb}, template);

    el.innerHTML = '<h1>Keyboard Shortcuts</h1><div>' +
        JSON.stringify(kb, null, '    ') +
        '</div>';
    el.style.cssText = 'margin:0; padding:0; ' +
        'background-color:white; color:black; ' +
        'white-space: pre-wrap;';
    overlayPage(el, '0', '0', '0', null);
}
Contributor

matthewkastor commented Mar 29, 2013

ok. I posted the settings menu generator stuff in #1335

Maybe I can figure out how to make a plugin soon.

Contributor

matthewkastor commented Mar 29, 2013

I tried making a plugin thing in the ext folder but no matter what I do I can't require it from the console. I rebuild ace, see the changes reflected in all the various build files but no. It just won't load. I stepped through the code while using the editor.html demo and noticed that during the module lookup none of the ace/ext/ modules were listed at all. https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/ace.js#L114 var module = _define.modules[moduleName];

How am I supposed to do this? I can't find anything in the docs.

Contributor

matthewkastor commented Mar 30, 2013

I figured it out and submitted a pull request. #1339

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment