work on menus
This commit is contained in:
parent
740e728827
commit
7f3fc1a4f3
|
|
@ -7,6 +7,7 @@
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"core:default",
|
"core:default",
|
||||||
|
"core:window:allow-close",
|
||||||
"shell:allow-open",
|
"shell:allow-open",
|
||||||
"fs:default",
|
"fs:default",
|
||||||
{
|
{
|
||||||
|
|
|
||||||
306
src/main.js
306
src/main.js
|
|
@ -591,9 +591,10 @@ function redo() {
|
||||||
|
|
||||||
|
|
||||||
class Frame {
|
class Frame {
|
||||||
constructor(uuid) {
|
constructor(frameType="normal", uuid=undefined) {
|
||||||
this.keys = {}
|
this.keys = {}
|
||||||
this.shapes = []
|
this.shapes = []
|
||||||
|
this.frameType = frameType
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
this.idx = uuidv4()
|
this.idx = uuidv4()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -608,7 +609,7 @@ class Frame {
|
||||||
|
|
||||||
class Layer {
|
class Layer {
|
||||||
constructor(uuid) {
|
constructor(uuid) {
|
||||||
this.frames = [new Frame()]
|
this.frames = [new Frame("keyframe")]
|
||||||
this.children = []
|
this.children = []
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
this.idx = uuidv4()
|
this.idx = uuidv4()
|
||||||
|
|
@ -955,7 +956,21 @@ class GraphicsObject {
|
||||||
return this.layers[this.currentLayer].children
|
return this.layers[this.currentLayer].children
|
||||||
}
|
}
|
||||||
get currentFrame() {
|
get currentFrame() {
|
||||||
return this.layers[this.currentLayer].frames[this.currentFrameNum]
|
if (this.layers[this.currentLayer].frames[this.currentFrameNum]) {
|
||||||
|
if (this.layers[this.currentLayer].frames[this.currentFrameNum].frameType == "keyframe") {
|
||||||
|
return this.layers[this.currentLayer].frames[this.currentFrameNum]
|
||||||
|
} else if (this.layers[this.currentLayer].frames[this.currentFrameNum].frameType == "motion") {
|
||||||
|
|
||||||
|
} else if (this.layers[this.currentLayer].frames[this.currentFrameNum].frameType == "shape") {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (let i=this.currentFrameNum; i>=0; i--) {
|
||||||
|
if (this.layers[this.currentLayer].frames[i].frameType == "keyframe") {
|
||||||
|
return this.layers[this.currentLayer].frames[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
get maxFrame() {
|
get maxFrame() {
|
||||||
let maxFrames = []
|
let maxFrames = []
|
||||||
|
|
@ -1134,7 +1149,7 @@ window.addEventListener("resize", () => {
|
||||||
updateAll()
|
updateAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener("keypress", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
// let shortcuts = {}
|
// let shortcuts = {}
|
||||||
// for (let shortcut of config.shortcuts) {
|
// for (let shortcut of config.shortcuts) {
|
||||||
// shortcut = shortcut.split("+")
|
// shortcut = shortcut.split("+")
|
||||||
|
|
@ -1158,8 +1173,28 @@ window.addEventListener("keypress", (e) => {
|
||||||
} else if (e.key == config.shortcuts.quit && e.ctrlKey == true) {
|
} else if (e.key == config.shortcuts.quit && e.ctrlKey == true) {
|
||||||
quit()
|
quit()
|
||||||
}
|
}
|
||||||
|
else if (e.key == "ArrowRight") {
|
||||||
|
advanceFrame()
|
||||||
|
}
|
||||||
|
else if (e.key == "ArrowLeft") {
|
||||||
|
decrementFrame()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function advanceFrame() {
|
||||||
|
context.activeObject.currentFrameNum += 1
|
||||||
|
updateLayers()
|
||||||
|
updateMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrementFrame() {
|
||||||
|
if (context.activeObject.currentFrameNum > 0) {
|
||||||
|
context.activeObject.currentFrameNum -= 1
|
||||||
|
updateLayers()
|
||||||
|
updateMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function _newFile(width, height) {
|
function _newFile(width, height) {
|
||||||
root = new GraphicsObject("root");
|
root = new GraphicsObject("root");
|
||||||
context.activeObject = root
|
context.activeObject = root
|
||||||
|
|
@ -1727,106 +1762,6 @@ function infopanel() {
|
||||||
return panel
|
return panel
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setupMenu() {
|
|
||||||
const fileSubmenu = await Submenu.new({
|
|
||||||
text: 'File',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: 'New file...',
|
|
||||||
enabled: true,
|
|
||||||
action: newFile,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Save',
|
|
||||||
enabled: true,
|
|
||||||
action: save,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Save As...',
|
|
||||||
enabled: true,
|
|
||||||
action: saveAs,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Open File...',
|
|
||||||
enabled: true,
|
|
||||||
action: open,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Quit',
|
|
||||||
enabled: true,
|
|
||||||
action: quit,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const editSubmenu = await Submenu.new({
|
|
||||||
text: "Edit",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: "Undo",
|
|
||||||
enabled: true,
|
|
||||||
action: undo
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Redo",
|
|
||||||
enabled: true,
|
|
||||||
action: redo
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Cut",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Copy",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Paste",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const viewSubmenu = await Submenu.new({
|
|
||||||
text: "View",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: "Zoom In",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Zoom Out",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const helpSubmenu = await Submenu.new({
|
|
||||||
text: "Help",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
text: "About...",
|
|
||||||
enabled: true,
|
|
||||||
action: () => {
|
|
||||||
messageDialog(`Lightningbeam version ${appVersion}\nDeveloped by Skyler Lehmkuhl`,
|
|
||||||
{title: 'About', kind: "info"}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const menu = await Menu.new({
|
|
||||||
items: [fileSubmenu, editSubmenu, viewSubmenu, helpSubmenu],
|
|
||||||
})
|
|
||||||
await (macOS ? menu.setAsAppMenu() : menu.setAsWindowMenu())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the menu when the app starts
|
|
||||||
setupMenu();
|
|
||||||
|
|
||||||
createNewFileDialog(_newFile);
|
createNewFileDialog(_newFile);
|
||||||
showNewFileDialog()
|
showNewFileDialog()
|
||||||
|
|
@ -1947,12 +1882,173 @@ function updateLayers() {
|
||||||
let layerTrack = document.createElement("div")
|
let layerTrack = document.createElement("div")
|
||||||
layerTrack.className = "layer-track"
|
layerTrack.className = "layer-track"
|
||||||
framescontainer.appendChild(layerTrack)
|
framescontainer.appendChild(layerTrack)
|
||||||
for (let frame of layer.frames) {
|
let highlightedFrame = false
|
||||||
|
layer.frames.forEach((frame, i) => {
|
||||||
// for (let j=0; j<5-i; j++) {
|
// for (let j=0; j<5-i; j++) {
|
||||||
let frameEl = document.createElement("div")
|
let frameEl = document.createElement("div")
|
||||||
frameEl.className = "frame"
|
frameEl.className = "frame"
|
||||||
|
if (i == context.activeObject.currentFrameNum) {
|
||||||
|
frameEl.classList.add("active")
|
||||||
|
highlightedFrame = true
|
||||||
|
}
|
||||||
|
console.log(frame.frameType)
|
||||||
|
if (frame.frameType == "keyframe") {
|
||||||
|
frameEl.classList.add("keyframe")
|
||||||
|
}
|
||||||
layerTrack.appendChild(frameEl)
|
layerTrack.appendChild(frameEl)
|
||||||
|
})
|
||||||
|
if (!highlightedFrame) {
|
||||||
|
let highlightObj = document.createElement("div")
|
||||||
|
let frameCount = layer.frames.length
|
||||||
|
highlightObj.className = "frame-highlight"
|
||||||
|
highlightObj.style.left = `${(context.activeObject.currentFrameNum - frameCount) * 25}px`;
|
||||||
|
layerTrack.appendChild(highlightObj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateMenu() {
|
||||||
|
let activeFrame;
|
||||||
|
let newFrameMenuItem;
|
||||||
|
let newKeyframeMenuItem;
|
||||||
|
let deleteFrameMenuItem;
|
||||||
|
|
||||||
|
|
||||||
|
if (context.activeObject.activeLayer.frames[context.activeObject.currentFrameNum]) {
|
||||||
|
activeFrame = true
|
||||||
|
} else {
|
||||||
|
activeFrame = false
|
||||||
|
}
|
||||||
|
const fileSubmenu = await Submenu.new({
|
||||||
|
text: 'File',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: 'New file...',
|
||||||
|
enabled: true,
|
||||||
|
action: newFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Save',
|
||||||
|
enabled: true,
|
||||||
|
action: save,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Save As...',
|
||||||
|
enabled: true,
|
||||||
|
action: saveAs,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Open File...',
|
||||||
|
enabled: true,
|
||||||
|
action: open,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Quit',
|
||||||
|
enabled: true,
|
||||||
|
action: quit,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const editSubmenu = await Submenu.new({
|
||||||
|
text: "Edit",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "Undo",
|
||||||
|
enabled: true,
|
||||||
|
action: undo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Redo",
|
||||||
|
enabled: true,
|
||||||
|
action: redo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Cut",
|
||||||
|
enabled: true,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Copy",
|
||||||
|
enabled: true,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Paste",
|
||||||
|
enabled: true,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
newFrameMenuItem = {
|
||||||
|
text: "New Frame",
|
||||||
|
enabled: !activeFrame,
|
||||||
|
action: () => {}
|
||||||
|
}
|
||||||
|
newKeyframeMenuItem = {
|
||||||
|
text: "New Keyframe",
|
||||||
|
enabled: !activeFrame,
|
||||||
|
action: () => {}
|
||||||
|
}
|
||||||
|
deleteFrameMenuItem = {
|
||||||
|
text: "Delete Frame",
|
||||||
|
enabled: activeFrame,
|
||||||
|
action: () => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timelineSubmenu = await Submenu.new({
|
||||||
|
text: "Timeline",
|
||||||
|
items: [
|
||||||
|
newFrameMenuItem,
|
||||||
|
newKeyframeMenuItem,
|
||||||
|
deleteFrameMenuItem,
|
||||||
|
{
|
||||||
|
text: "Return to start",
|
||||||
|
enabled: false,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Play",
|
||||||
|
enabled: false,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const viewSubmenu = await Submenu.new({
|
||||||
|
text: "View",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "Zoom In",
|
||||||
|
enabled: false,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Zoom Out",
|
||||||
|
enabled: false,
|
||||||
|
action: () => {}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const helpSubmenu = await Submenu.new({
|
||||||
|
text: "Help",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "About...",
|
||||||
|
enabled: true,
|
||||||
|
action: () => {
|
||||||
|
messageDialog(`Lightningbeam version ${appVersion}\nDeveloped by Skyler Lehmkuhl`,
|
||||||
|
{title: 'About', kind: "info"}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const menu = await Menu.new({
|
||||||
|
items: [fileSubmenu, editSubmenu, timelineSubmenu, viewSubmenu, helpSubmenu],
|
||||||
|
})
|
||||||
|
await (macOS ? menu.setAsAppMenu() : menu.setAsWindowMenu())
|
||||||
|
}
|
||||||
|
updateMenu()
|
||||||
|
|
@ -286,7 +286,31 @@ button {
|
||||||
.frame:hover {
|
.frame:hover {
|
||||||
background-color: #555555;
|
background-color: #555555;
|
||||||
}
|
}
|
||||||
|
.frame.active {
|
||||||
|
background-color: #666666;
|
||||||
|
}
|
||||||
|
.frame.keyframe {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.frame.keyframe::before {
|
||||||
|
content: ''; /* Creates a pseudo-element */
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0; /* Position the circle at the bottom of the div */
|
||||||
|
left: 50%; /* Center the circle horizontally */
|
||||||
|
transform: translateX(-50%); /* Adjust for perfect centering */
|
||||||
|
width: 50%; /* Set the width of the circle to half of the div's width */
|
||||||
|
height: 0; /* Initially set to 0 */
|
||||||
|
padding-bottom: 50%; /* Set padding-bottom to 50% of the div's width to create a circle */
|
||||||
|
border-radius: 50%; /* Make the shape a circle */
|
||||||
|
background-color: #222; /* Set the color of the circle (black in this case) */
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.frame-highlight {
|
||||||
|
background-color: red;
|
||||||
|
width: 25px;
|
||||||
|
height: calc( 2 * var(--lineheight) - 2px);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue