Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Template for new versions:

## New Features
- `advtools`: new ``advtools.fastcombat`` overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys
- `gui/journal`: now working in adventure mode

## Fixes
- `position`: support for adv mode look cursor
Expand Down
8 changes: 4 additions & 4 deletions docs/gui/journal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ gui/journal

.. dfhack-tool::
:summary: Fort journal with a multi-line text editor.
:tags: fort interface
:tags: adventure fort interface

The `gui/journal` interface makes it easy to take notes and document
important details for the fortresses.
important details for your fortresses and adventurers.

With this multi-line text editor,
you can keep track of your fortress's background story, goals, notable events,
and both short-term and long-term plans.
you can keep track of your fortress's/adventurer's background story, goals,
notable events, and both short-term and long-term plans.

This is particularly useful when you need to take a longer break from the game.
Having detailed notes makes it much easier to resume your game after
Expand Down
96 changes: 33 additions & 63 deletions gui/journal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,15 @@ local utils = require 'utils'
local json = require 'json'
local shifter = reqscript('internal/journal/shifter')
local table_of_contents = reqscript('internal/journal/table_of_contents')
local journal_context = reqscript('internal/journal/journal_context')

local RESIZE_MIN = {w=54, h=20}
local TOC_RESIZE_MIN = {w=24}

local JOURNAL_PERSIST_KEY = 'journal'

local JOURNAL_WELCOME_COPY = [=[
Welcome to gui/journal, the chronicler's tool for Dwarf Fortress!

Here, you can carve out notes, sketch your grand designs, or record the history of your fortress.
The text you write here is saved together with your fort.

For guidance on navigation and hotkeys, tap the ? button in the upper right corner.
Happy digging!
]=]

local TOC_WELCOME_COPY = [=[
Start a line with # symbols and a space to create a header. For example:

# My section heading

or

## My section subheading

Those headers will appear here, and you can click on them to jump to them in the text.]=]

journal_config = journal_config or json.open('dfhack-config/journal.json')

JOURNAL_CONTEXT_MODE = journal_context.JOURNAL_CONTEXT_MODE

JournalWindow = defclass(JournalWindow, widgets.Window)
JournalWindow.ATTRS {
frame_title='DF Journal',
Expand All @@ -47,6 +27,9 @@ JournalWindow.ATTRS {
save_layout=true,
show_tutorial=false,

toc_welcome_copy=DEFAULT_NIL,
journal_welcome_copy=DEFAULT_NIL,

on_text_change=DEFAULT_NIL,
on_cursor_change=DEFAULT_NIL,
on_layout_change=DEFAULT_NIL
Expand Down Expand Up @@ -76,7 +59,7 @@ function JournalWindow:init()
widgets.WrappedLabel{
view_id='table_of_contents_tutorial',
frame={l=0,t=0,r=0,b=3},
text_to_wrap=TOC_WELCOME_COPY,
text_to_wrap=self.toc_welcome_copy or '',
visible=false
}
}
Expand Down Expand Up @@ -143,7 +126,7 @@ function JournalWindow:init()
widgets.WrappedLabel{
view_id='journal_tutorial',
frame={l=0,t=1,r=0,b=0},
text_to_wrap=JOURNAL_WELCOME_COPY
text_to_wrap=self.journal_welcome_copy or ''
}
}
end
Expand Down Expand Up @@ -285,13 +268,17 @@ end
JournalScreen = defclass(JournalScreen, gui.ZScreen)
JournalScreen.ATTRS {
focus_path='journal',
save_on_change=true,
context_mode=DEFAULT_NIL,
save_layout=true,
save_prefix=''
}

function JournalScreen:init()
local context = self:loadContext()
self.journal_context = journal_context.journal_context_factory(
self.context_mode,
self.save_prefix
)
local content = self.journal_context:load_content()

self:addviews{
JournalWindow{
Expand All @@ -300,62 +287,45 @@ function JournalScreen:init()

save_layout=self.save_layout,

init_text=context.text[1],
init_cursor=context.cursor[1],
show_tutorial=context.show_tutorial or false,
init_text=content.text[1],
init_cursor=content.cursor[1],
show_tutorial=content.show_tutorial or false,

toc_welcome_copy=self.journal_context:tocWelcomeCopy(),
journal_welcome_copy=self.journal_context:welcomeCopy(),

on_text_change=self:callback('saveContext'),
on_cursor_change=self:callback('saveContext')
on_text_change=self:callback('onTextChange'),
on_cursor_change=self:callback('onTextChange')
},
}
end

function JournalScreen:loadContext()
local site_data = self.save_on_change and dfhack.persistent.getSiteData(
self.save_prefix .. JOURNAL_PERSIST_KEY
) or {}
function JournalScreen:onTextChange()
local text = self.subviews.journal_editor:getText()
local cursor = self.subviews.journal_editor:getCursor()

if not site_data.text then
site_data.text={''}
site_data.show_tutorial = true
end
site_data.cursor = site_data.cursor or {#site_data.text[1] + 1}

return site_data
end

function JournalScreen:onTextChange(text)
self:saveContext(text)
end

function JournalScreen:saveContext()
if self.save_on_change and dfhack.isWorldLoaded() then
local text = self.subviews.journal_editor:getText()
local cursor = self.subviews.journal_editor:getCursor()

dfhack.persistent.saveSiteData(
self.save_prefix .. JOURNAL_PERSIST_KEY,
{text={text}, cursor={cursor}}
)
end
self.journal_context:save_content(text, cursor)
end

function JournalScreen:onDismiss()
view = nil
end

function main(options)
if not dfhack.isMapLoaded() or not dfhack.world.isFortressMode() then
qerror('journal requires a fortress map to be loaded')
if not dfhack.isMapLoaded() or (not dfhack.world.isFortressMode()
and not dfhack.world.isAdventureMode()) then
qerror('journal requires a fortress/adventure map to be loaded')
end

local save_layout = options and options.save_layout
local save_on_change = options and options.save_on_change
local overrided_context_mode = options and options.context_mode
local context_mode = overrided_context_mode == nil and
journal_context.detect_journal_context_mode() or overrided_context_mode

view = view and view:raise() or JournalScreen{
save_prefix=options and options.save_prefix or '',
save_layout=save_layout == nil and true or save_layout,
save_on_change=save_on_change == nil and true or save_on_change,
context_mode=context_mode,
}:show()
end

Expand Down
77 changes: 77 additions & 0 deletions internal/journal/contexts/adventure.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--@ module = true

local JOURNAL_WELCOME_COPY = [=[
Welcome to gui/journal, the adventurer's notebook for Dwarf Fortress!

Here, you can jot down your travels, keep track of important places, or note anything worth remembering.
The text you write here is saved together with your adventurer.

For guidance on navigation and hotkeys, tap the ? button in the upper right corner.
Safe travels!
]=]

local TOC_WELCOME_COPY = [=[
Start a line with # symbols and a space to create a header. For example:

# My section heading

or

## My section subheading

Those headers will appear here, and you can click on them to jump to them in the text.]=]


AdventurerJournalContext = defclass(AdventurerJournalContext)
AdventurerJournalContext.ATTRS{
save_prefix='',
adventurer_id=DEFAULT_NIL
}

function get_adventurer_context_key(prefix, adventurer_id)
return string.format(
'%sjournal:adventurer:%s',
prefix,
adventurer_id
)
end

function AdventurerJournalContext:save_content(text, cursor)
if dfhack.isWorldLoaded() then
dfhack.persistent.saveWorldData(
get_adventurer_context_key(self.save_prefix, self.adventurer_id),
{text={text}, cursor={cursor}}
)
end
end

function AdventurerJournalContext:load_content()
if dfhack.isWorldLoaded() then
local world_data = dfhack.persistent.getWorldData(
get_adventurer_context_key(self.save_prefix, self.adventurer_id)
) or {}

if not world_data.text then
world_data.text={''}
world_data.show_tutorial = true
end
world_data.cursor = world_data.cursor or {#world_data.text[1] + 1}
return world_data
end
end

function AdventurerJournalContext:delete_content()
if dfhack.isWorldLoaded() then
dfhack.persistent.deleteWorldData(
get_adventurer_context_key(self.save_prefix, self.adventurer_id)
)
end
end

function AdventurerJournalContext:welcomeCopy()
return JOURNAL_WELCOME_COPY
end

function AdventurerJournalContext:tocWelcomeCopy()
return TOC_WELCOME_COPY
end
23 changes: 23 additions & 0 deletions internal/journal/contexts/dummy.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--@ module = true

-- Dummy Context, no storage --

DummyJournalContext = defclass(DummyJournalContext)

function DummyJournalContext:save_content(text, cursor)
end

function DummyJournalContext:load_content()
return {text={''}, cursor={1}, show_tutorial=true}
end

function DummyJournalContext:delete_content()
end

function DummyJournalContext:welcomeCopy()
return ''
end

function DummyJournalContext:tocWelcomeCopy()
return ''
end
72 changes: 72 additions & 0 deletions internal/journal/contexts/fortress.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
--@ module = true

local JOURNAL_WELCOME_COPY = [=[
Welcome to gui/journal, the chronicler's tool for Dwarf Fortress!

Here, you can carve out notes, sketch your grand designs, or record the history of your fortress.
The text you write here is saved together with your fort.

For guidance on navigation and hotkeys, tap the ? button in the upper right corner.
Happy digging!
]=]

local TOC_WELCOME_COPY = [=[
Start a line with # symbols and a space to create a header. For example:

# My section heading

or

## My section subheading

Those headers will appear here, and you can click on them to jump to them in the text.]=]


FortressJournalContext = defclass(FortressJournalContext)
FortressJournalContext.ATTRS{
save_prefix=''
}

function get_fort_context_key(prefix)
return prefix .. 'journal'
end

function FortressJournalContext:save_content(text, cursor)
if dfhack.isWorldLoaded() then
dfhack.persistent.saveSiteData(
get_fort_context_key(self.save_prefix),
{text={text}, cursor={cursor}}
)
end
end

function FortressJournalContext:load_content()
if dfhack.isWorldLoaded() then
local site_data = dfhack.persistent.getSiteData(
get_fort_context_key(self.save_prefix)
) or {}

if not site_data.text then
site_data.text={''}
site_data.show_tutorial = true
end
site_data.cursor = site_data.cursor or {#site_data.text[1] + 1}
return site_data
end
end

function FortressJournalContext:delete_content()
if dfhack.isWorldLoaded() then
dfhack.persistent.deleteSiteData(
get_fort_context_key(self.save_prefix)
)
end
end

function FortressJournalContext:welcomeCopy()
return JOURNAL_WELCOME_COPY
end

function FortressJournalContext:tocWelcomeCopy()
return TOC_WELCOME_COPY
end
Loading
Loading