Skip to content

Commit

Permalink
Better command palette
Browse files Browse the repository at this point in the history
  • Loading branch information
deepnight committed Dec 27, 2023
1 parent 4ce607a commit cfda518
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 30 deletions.
2 changes: 1 addition & 1 deletion app/assets/css/app.min.css

Large diffs are not rendered by default.

31 changes: 21 additions & 10 deletions app/assets/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5460,17 +5460,13 @@ canvas#webgl {
.wrapper {
position: absolute;
z-index: 1;
width: 100vw;
width: 70vw;
margin-left: 15vw;
top: 8px;

input[type=text],
.results {
display: block;
width: 70vw;
margin: auto;
input[type=text] {
width: 100%;
}
// input[type=text] {
// }
.results {
box-sizing: border-box;
margin-top: 8px;
Expand All @@ -5479,13 +5475,28 @@ canvas#webgl {
background-color: $bgDark;
border-radius: 3px;
.element {
display: flex;
padding: 4px 16px;
cursor: pointer;
&:hover {
gap: 8px;
align-items: center;

&.active {
color: black !important;
font-weight: bold;
background-color: $orange;
color: black;
}
}

.more {
position: absolute;
pointer-events: none;
width: 100%;
left: 0;
bottom: 8px;
height: 2em;
background: linear-gradient(0deg, rgba(30,34,41,1) 0%, rgba(30,34,41,0) 100%);
}
}
}
}
Expand Down
16 changes: 9 additions & 7 deletions app/assets/tpl/pages/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@
<div class="icon showDetailsOff off"></div>
</li>

<li class="autoLayerRender" title="**Render auto-layers** Enable or disable the rendering of tiles in all Auto-Layers. If disabled, only the underlying IntGrid values will be displayed." tip="right">
<li class="singleLayerMode" title="**Single layer mode** Enable this to fade all other layers, and focus on active layer only. NOTE: this will also affect the Selection tool (ALT+click)." keys="Shift+A" tip="right">
<div class="icon singleLayer"></div>
</li>

<li class="autoLayerRender" title="**Render auto-layers** Enable or disable the rendering of tiles in all Auto-Layers. If disabled, only the underlying IntGrid values will be displayed." keys="SHIFT+R" tip="right">
<div class="icon autoLayer on"></div>
<div class="icon autoLayer off"></div>
</li>
Expand All @@ -67,10 +71,6 @@

<div class="title editing">Editing</div>
<ul class="editing">
<li class="singleLayerMode" title="**Single layer mode** Enable this to fade all other layers, and focus on active layer only. NOTE: this will also affect the Selection tool (ALT+click)." keys="Shift+A" tip="right">
<div class="icon singleLayer"></div>
</li>

<li class="emptySpaceSelection" title="**Select empty spaces** If this option is enabled when you select a level area with ALT+SHIFT+click, the selection will also include EMPTY grid cells." keys="Shift+E" tip="right">
<div class="icon emptySpaceOn on"></div>
<div class="icon emptySpaceOff off"></div>
Expand Down Expand Up @@ -101,8 +101,10 @@
<xml class="commandPalette">
<div class="mask"></div>
<div class="wrapper">
<input type="text" placeholder="Search for anything"/>
<div class="results"></div>
<div class="content">
<input type="text" placeholder="Search for anything"/>
<div class="results"></div>
</div>
</div>
</xml>

Expand Down
6 changes: 4 additions & 2 deletions src/electron.renderer/page/Editor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1388,9 +1388,11 @@ class Editor extends Page {
ge.emit( ViewportChanged(true) );
saveLastProjectInfos();

if( fitView )
if( fitView ) {
setWorldMode(false);
camera.fit();

}

ui.Tip.clear();
LevelTimeline.garbageCollectTimelines();
}
Expand Down
117 changes: 107 additions & 10 deletions src/electron.renderer/ui/CommandPalette.hx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package ui;

typedef SearchElement = {
var id: String;
var cat: ElementCategory;
var desc: String;
var onPick: Void->Void;
var ?keywords: String;
}

enum ElementCategory {
SE_World;
SE_Level;
SE_Entity;
}

class CommandPalette {
public var editor(get,never) : Editor; inline function get_editor() return Editor.ME;
public var project(get,never) : data.Project; inline function get_project() return Editor.ME.project;
Expand All @@ -15,10 +23,13 @@ class CommandPalette {
var jInput: js.jquery.JQuery;
var jResults: js.jquery.JQuery;
var jMask: js.jquery.JQuery;
var jElements(get,never) : js.jquery.JQuery; function get_jElements() return jResults.children(".element");
var jCurElement(get,never) : js.jquery.JQuery; function get_jCurElement() return jElements.filter('[uid=$curUid]');

var cleanReg = ~/[^a-z0-9 _]+/gi;
var allElements : Array<SearchElement> = [];
var curElements : Array<SearchElement> = [];
var curUid : Null<String>;

public function new() {
var jXml = App.ME.jPage.find("xml.commandPalette");
Expand All @@ -35,60 +46,146 @@ class CommandPalette {
jInput.keydown( (ev:js.jquery.Event)->{
switch ev.key {
case "Escape": close();
case "ArrowUp": moveCurrent(-1);
case "ArrowDown": moveCurrent(1);
case "Enter":
if( curUid!=null )
jCurElement.click();
case _:
}
});
jInput.on("input", _->applySearch() );
jInput.blur( _->jInput.focus() );
jInput.focus();

// List all elements
for(w in project.worlds) {
// Worlds
allElements.push({
desc: "World: "+w.identifier,
id: w.iid,
cat: SE_World,
desc: w.identifier,
onPick: ()->editor.selectWorld(w,true),
});
for(l in w.levels) {
// Levels
allElements.push({
desc: "Level: "+l.identifier,
onPick: ()->{
editor.selectLevel(l, true);
editor.setWorldMode(false);
},
id: l.iid,
cat: SE_Level,
desc: l.identifier,
onPick: ()->editor.selectLevel(l, true),
});

for(li in l.layerInstances)
for(e in li.entityInstances) {
allElements.push({
id: e.iid,
cat: SE_Entity,
desc: e.def.identifier+"#"+e.defUid,
onPick: ()->{
editor.selectLevel(l, true);
}
});
}
}
}

// Init keywords
for(e in allElements) {
if( e.keywords==null )
e.keywords = e.desc.toLowerCase();
e.keywords = switch e.cat {
case SE_World: "world";
case SE_Level: "level";
case SE_Entity: "entity";
}
e.keywords += " "+e.desc.toLowerCase();
e.keywords = cleanupKeywords(e.keywords);
}

applySearch();
}


function cleanupKeywords(raw:String) {
return raw==null ? "" : cleanReg.replace(raw, " ").toLowerCase();
}


function applySearch() {
curElements = [];
var raw = cleanupKeywords( jInput.val() );
for(e in allElements) {

// List matches
for(e in allElements)
if( e.keywords.indexOf(raw)>=0 )
curElements.push(e);
}

// Fill results list
jResults.empty();
curUid = null;
var i = 0;
for(e in curElements) {
var jElement = new J('<div class="element">${e.desc}</div>');
var iconId = switch e.cat {
case SE_World: "world";
case SE_Level: "level";
case SE_Entity: "entity";
}
jElement.prepend('<span class="icon $iconId"></span>');
var col = switch e.cat {
case SE_World: "#ad8358";
case SE_Level: "#70a9ff";
case SE_Entity: "#ff9900";
}
jElement.css("color", col);
jElement.attr("uid", e.id);
jElement.click(_->{
close();
e.onPick();
});
jElement.mousemove( _->{
if( curUid!=e.id )
setCurrent(e);
});
jElement.appendTo(jResults);
if( curUid==null )
setCurrent(e);

if( i++>=15 ) {
jResults.append('<div class="more"></div>');
break;
}
}
}


function moveCurrent(delta:Int) {
var jCur = jElements.filter('[uid=$curUid]');
if( jCur.length==0 || curUid==null )
updateCurrent();
else {
if( delta<0 )
jCur = jCur.prev();
else
jCur = jCur.next();
if( jCur.length>0 ) {
curUid = jCur.attr("uid");
updateCurrent();
}
}
}


function setCurrent(?e:SearchElement) {
curUid = e==null ? null : e.id;
updateCurrent();
}

function updateCurrent() {
jElements.removeClass("active");
if( curUid!=null )
jElements.filter('[uid=$curUid]').addClass("active");
}

function close() {
jCmdPal.remove();
jCmdPal = null;
Expand Down

0 comments on commit cfda518

Please sign in to comment.