Skip to content

Commit

Permalink
Draggable acts (#309)
Browse files Browse the repository at this point in the history
* Draggable acts
* Open debug console in dev builds
  • Loading branch information
mkoskim authored Dec 18, 2024
1 parent eba3134 commit 12ec53f
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 28 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ In short, MaweJS is externally unstructured editor (like Notepad, Word or Google
In newer Ubuntus you may encounter errors due to changed permissions. First, you may need to run AppImage without sandboxing:

```
$ mawejs-0.7.0.Linux.amd.AppImage --no-sandbox
$ mawejs-A.B.C.Linux.amd.AppImage --no-sandbox
```

In newer Ubuntus, if you run the sources, you may need to set SUID bit on. You need to do this every time ElectronJS is updated. There is now npm run target to do that:
Expand Down Expand Up @@ -125,10 +125,20 @@ Get dependencies:

mawejs$ npm install

Running (development version). Open up two terminals (one for the dev server and one for the ElectronJS application):
## Running from Sources

**Linux:**

mawejs$ npm run dev
mawejs$ npm run dev:electron

**Windows:** If you use command prompt, it can't understand shell commands in `dev` target written for Bash shell. Open up two terminals (one for the dev server and one for the ElectronJS application). Run the latter command, when React dev server is up:

shell 1: mawejs$ npm run dev:react
shell 2: mawejs$ npm run dev:electron

`dev:react` React starts development server, and `dev:electron` starts Electron browser. The Electron browser is standard Chromium, but it has ElectronJS backend to allow local access.

## Updating

If you update the project with 'git pull', you may need to update the libraries, too:

Expand All @@ -139,6 +149,8 @@ If you update the project with 'git pull', you may need to update the libraries,

Instructions to get React DevTools working: https://github.com/mkoskim/mawejs/discussions/131

VS Code Electron debugging: https://github.com/Microsoft/vscode-recipes/tree/master/Electron

## Example files

You can test MaweJS with example files located in examples/
Expand Down
2 changes: 1 addition & 1 deletion public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ async function createWindow()
mainWindow.setMenu(null);
//console.log("Languages:", mainWindow.webContents.session.availableSpellCheckerLanguages)
//mainWindow.webContents.session.setSpellCheckerLanguages(['fi'])
//mainWindow.webContents.openDevTools();

if(isDev)
{
debug();
mainWindow.webContents.openDevTools();
mainWindow.loadURL('http://localhost:3000');
}
else{
Expand Down
2 changes: 1 addition & 1 deletion src/document/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export function elemHeading(elem) {

if(elem.children.length) {
const [first] = elem.children
if(nodeBreaks(first) === elem.type) return first
if(nodeIsBreak(first) && nodeBreaks(first) === elem.type) return first
}

return undefined
Expand Down
3 changes: 2 additions & 1 deletion src/gui/arc/arc.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,15 @@ export function StoryArc({doc, updateDoc}) {
//console.log(type, source, "-->", destination)

switch(type) {
case "act":
case "chapter":
case "scene": {
const {path: srcPath} = IDtoPath(draggableId)
const {path: dstPath} = IDtoPath(destination.droppableId)
//const srcEdit = getEditorBySectID(srcSectID)
//const dstEdit = getEditorBySectID(dstSectID)

const dropped = dndDrop(bodyeditor, srcPath, bodyeditor, dstPath, destination.index)
dndDrop(bodyeditor, srcPath, bodyeditor, dstPath ?? [], destination.index)
//setActive(nodeID(dstSectID, dropped))
break;
}
Expand Down
96 changes: 77 additions & 19 deletions src/gui/common/docIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,32 +109,76 @@ export function DocIndex({style, sectID, section, wcFormat, include, setActive,
// Single unnamed act -> don't show
//---------------------------------------------------------------------------

const skipActName = (section.acts.length === 1 && !elemName(section.acts[0]))
//const skipActName = (section.acts.length === 1 && !elemName(section.acts[0]))

//---------------------------------------------------------------------------
// Index
//---------------------------------------------------------------------------

return <VBox style={style} className="TOC">
{section.acts.map((elem, index) => <ActItem
key={index}
id={childID(sectID, index)}
elem={elem}
<ActDropZone
id={sectID}
acts={section.acts}
wcFormat={wcFormatFunction}
include={include}
onActivate={onActivate}
unfold={unfold}
atAct={at.act === index}
atChapter={at.act === index ? at.chapter : undefined}
atScene={at.act === index ? at.scene : undefined}
atAct={at.act}
atChapter={at.chapter}
atScene={at.scene}
refCurrent={refCurrent}
skipActName={skipActName}
/>
)}
</VBox>
//return useDeferredValue(index)
}

//*****************************************************************************
//
// Act drop zone
//
//*****************************************************************************

class ActDropZone extends React.PureComponent {

render() {
const {id} = this.props

//console.log("Index update:", activeID)

return <Droppable droppableId={id} type="act">
{this.DropZone.bind(this)}
</Droppable>
}

DropZone(provided, snapshot) {
const {acts, id, wcFormat, include, onActivate, unfold, atAct, atChapter, atScene, refCurrent} = this.props
const {innerRef, droppableProps, placeholder} = provided
const {isDraggingOver} = snapshot

return <div
className={addClass("VBox ActDropZone", isDraggingOver && "DragOver")}
ref={innerRef}
{...droppableProps}
>
{acts.map((elem, index) => !nodeIsCtrl(elem) && <ActItem
key={index}
id={childID(id, index)}
index={index}
elem={elem}
include={include}
wcFormat={wcFormat}
onActivate={onActivate}
unfold={unfold}
atAct={atAct === index}
atChapter={atAct === index ? atChapter : undefined}
atScene={atAct === index ? atScene : undefined}
refCurrent={refCurrent}
/>)}
{placeholder}
</div>
}
}

//*****************************************************************************
//
// Act items
Expand All @@ -144,7 +188,19 @@ export function DocIndex({style, sectID, section, wcFormat, include, setActive,
class ActItem extends React.PureComponent {

render() {
const {skipActName, elem, wcFormat, id, include, onActivate, unfold, atAct, atChapter, atScene, refCurrent} = this.props
const {id, index} = this.props
return <Draggable
draggableId={id}
index={index}
type="act"
>
{this.Draggable.bind(this)}
</Draggable>
}

Draggable(provided, snapshot) {
const {elem, wcFormat, id, index, include, onActivate, unfold, atAct, atChapter, atScene, refCurrent} = this.props
const {innerRef, draggableProps, dragHandleProps} = provided

const hasDropzone = (include.includes("chapter")) && (unfold || !elem.folded)
//const hasDropzone = (unfold || !elem.folded)
Expand All @@ -154,19 +210,23 @@ class ActItem extends React.PureComponent {
(!hasDropzone || atChapter === undefined || elem.children[atChapter].type === "hact")
)

return <div>
{!skipActName && <IndexItem
return <div
ref={innerRef}
{...draggableProps}
>
<IndexItem
id={id}
type={elem.type}
name={elemName(elem)}
name={elem.name}
words={elem.words}
folded={!unfold && elem.folded}
numbered={elemNumbered(elem)}
numbered={elem.numbered}
wcFormat={wcFormat}
onActivate={onActivate}
isCurrent={isCurrent}
refCurrent={refCurrent}
/>}
{...dragHandleProps}
/>
{hasDropzone && <ChapterDropZone
id={id}
folded={!unfold && elem.folded}
Expand All @@ -188,9 +248,7 @@ class ActItem extends React.PureComponent {
class ChapterDropZone extends React.PureComponent {

render() {
const {chapters, id} = this.props

if(!chapters) return null
const {id} = this.props

//console.log("Index update:", activeID)

Expand Down
18 changes: 18 additions & 0 deletions src/gui/common/styles/TOC.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,24 @@

/*-------------------------------------------------------------------------*/

div.ActDropZone {
min-height: 16pt;

&.DragOver {
margin-left: -4px;
margin-right: -4px;
border: 1px dashed grey;
padding: 3px;
/*
border-radius: 4px;
padding-top: 6px;
padding-bottom: 6px;
*/
}
}

/*-------------------------------------------------------------------------*/

div.ChapterDropZone {
min-height: 16pt;

Expand Down
7 changes: 4 additions & 3 deletions src/gui/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,14 +413,15 @@ export function SingleEditView({doc, updateDoc}) {
//console.log(type, source, "-->", destination)

switch(type) {
case "act":
case "chapter":
case "scene": {
const {sectID: srcSectID, path: srcPath} = IDtoPath(draggableId)
const {sectID: dstSectID, path: dstPath} = IDtoPath(destination.droppableId)
const srcEdit = getEditorBySectID(srcSectID)
const dstEdit = getEditorBySectID(dstSectID)

dndDrop(srcEdit, srcPath, dstEdit, dstPath, destination.index)
dndDrop(srcEdit, srcPath, dstEdit, dstPath ?? [], destination.index)
setActive(nodeID(dstSectID))
break;
}
Expand Down Expand Up @@ -675,10 +676,10 @@ function EditorBox({style, settings, mode="Condensed"}) {
{/* Editor toolbar */}

<ToolBox style={doc.ui.editor.toolbox.mid}>
<StyleButtons editor={editor} type={type} bold={bold} italic={italic}/>
<Separator/>
<FoldButtons editor={editor}/>
<Separator/>
<StyleButtons editor={editor} type={type} bold={bold} italic={italic}/>
<Separator/>
<Searching editor={editor} searchText={searchText} setSearchText={setSearchText} searchBoxRef={searchBoxRef}/>
<Separator/>
<Filler />
Expand Down

0 comments on commit 12ec53f

Please sign in to comment.