Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package messages
|
||||
|
||||
import (
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
"github.com/inkyblackness/hacked/ss1/world"
|
||||
)
|
||||
|
||||
type messageDataEntry struct {
|
||||
oldData [][]byte
|
||||
newData [][]byte
|
||||
}
|
||||
|
||||
type setMessageDataCommand struct {
|
||||
model *viewModel
|
||||
|
||||
key resource.Key
|
||||
showVerboseText bool
|
||||
|
||||
textEntries map[resource.Language]messageDataEntry
|
||||
audioEntries map[resource.Language]messageDataEntry
|
||||
}
|
||||
|
||||
func (cmd setMessageDataCommand) Do(modder world.Modder) error {
|
||||
return cmd.perform(modder, func(entry messageDataEntry) [][]byte { return entry.newData })
|
||||
}
|
||||
|
||||
func (cmd setMessageDataCommand) Undo(modder world.Modder) error {
|
||||
return cmd.perform(modder, func(entry messageDataEntry) [][]byte { return entry.oldData })
|
||||
}
|
||||
|
||||
func (cmd setMessageDataCommand) perform(modder world.Modder, dataResolver func(messageDataEntry) [][]byte) error {
|
||||
cmd.saveEntries(modder, cmd.key.ID.Plus(cmd.key.Index), cmd.textEntries, dataResolver)
|
||||
cmd.saveEntries(modder, cmd.key.ID.Plus(cmd.key.Index).Plus(300), cmd.audioEntries, dataResolver)
|
||||
|
||||
cmd.model.restoreFocus = true
|
||||
cmd.model.currentKey = cmd.key
|
||||
cmd.model.showVerboseText = cmd.showVerboseText
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cmd setMessageDataCommand) saveEntries(modder world.Modder, id resource.ID,
|
||||
entries map[resource.Language]messageDataEntry,
|
||||
dataResolver func(messageDataEntry) [][]byte) {
|
||||
for lang, entry := range entries {
|
||||
data := dataResolver(entry)
|
||||
if len(data) > 0 {
|
||||
modder.SetResourceBlocks(lang, id, data)
|
||||
} else {
|
||||
modder.DelResource(lang, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
package messages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v3"
|
||||
|
||||
"github.com/inkyblackness/hacked/editor/external"
|
||||
"github.com/inkyblackness/hacked/editor/graphics"
|
||||
"github.com/inkyblackness/hacked/editor/render"
|
||||
"github.com/inkyblackness/hacked/editor/values"
|
||||
"github.com/inkyblackness/hacked/ss1/content/audio"
|
||||
"github.com/inkyblackness/hacked/ss1/content/movie"
|
||||
"github.com/inkyblackness/hacked/ss1/content/text"
|
||||
"github.com/inkyblackness/hacked/ss1/edit/undoable/cmd"
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
"github.com/inkyblackness/hacked/ss1/world"
|
||||
"github.com/inkyblackness/hacked/ss1/world/ids"
|
||||
"github.com/inkyblackness/hacked/ui/gui"
|
||||
)
|
||||
|
||||
type messageInfo struct {
|
||||
title string
|
||||
}
|
||||
|
||||
var knownMessageTypes = map[resource.ID]messageInfo{
|
||||
ids.MailsStart: {title: "Mails"},
|
||||
ids.LogsStart: {title: "Logs"},
|
||||
ids.FragmentsStart: {title: "Fragments"},
|
||||
}
|
||||
var knownMessageTypesOrder = []resource.ID{ids.MailsStart, ids.LogsStart, ids.FragmentsStart}
|
||||
|
||||
var knownMailTypes = []string{
|
||||
"Audio/Text",
|
||||
"VMail: 'Shield' (0)",
|
||||
"VMail: 'Grove' (1)",
|
||||
"VMail: 'Bridge' (2)",
|
||||
"VMail: 'Laser' (3, 4)",
|
||||
"VMail: 'Status' (11)",
|
||||
"VMail: 'Explode' (5..9)",
|
||||
}
|
||||
|
||||
const videoMailDisplayBase = 256
|
||||
|
||||
// View provides edit controls for messages.
|
||||
type View struct {
|
||||
mod *world.Mod
|
||||
messageCache *text.ElectronicMessageCache
|
||||
cp text.Codepage
|
||||
movieCache *movie.Cache
|
||||
imageCache *graphics.TextureCache
|
||||
|
||||
modalStateMachine gui.ModalStateMachine
|
||||
clipboard external.Clipboard
|
||||
guiScale float32
|
||||
commander cmd.Commander
|
||||
|
||||
model viewModel
|
||||
}
|
||||
|
||||
// NewMessagesView returns a new instance.
|
||||
func NewMessagesView(mod *world.Mod, messageCache *text.ElectronicMessageCache, cp text.Codepage,
|
||||
movieCache *movie.Cache, imageCache *graphics.TextureCache,
|
||||
modalStateMachine gui.ModalStateMachine, clipboard external.Clipboard,
|
||||
guiScale float32, commander cmd.Commander) *View {
|
||||
view := &View{
|
||||
mod: mod,
|
||||
messageCache: messageCache,
|
||||
cp: cp,
|
||||
movieCache: movieCache,
|
||||
imageCache: imageCache,
|
||||
|
||||
modalStateMachine: modalStateMachine,
|
||||
clipboard: clipboard,
|
||||
guiScale: guiScale,
|
||||
commander: commander,
|
||||
|
||||
model: freshViewModel(),
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
// WindowOpen returns the flag address, to be used with the main menu.
|
||||
func (view *View) WindowOpen() *bool {
|
||||
return &view.model.windowOpen
|
||||
}
|
||||
|
||||
// Render renders the view.
|
||||
func (view *View) Render() {
|
||||
if view.model.restoreFocus {
|
||||
imgui.SetNextWindowFocus()
|
||||
view.model.restoreFocus = false
|
||||
view.model.windowOpen = true
|
||||
}
|
||||
if view.model.windowOpen {
|
||||
imgui.SetNextWindowSizeV(imgui.Vec2{X: 640 * view.guiScale, Y: 480 * view.guiScale}, imgui.ConditionFirstUseEver)
|
||||
if imgui.BeginV("Messages", view.WindowOpen(), imgui.WindowFlagsNoCollapse) {
|
||||
view.renderContent()
|
||||
}
|
||||
imgui.End()
|
||||
}
|
||||
}
|
||||
|
||||
func (view *View) renderContent() {
|
||||
if imgui.BeginChildV("Properties", imgui.Vec2{X: 350 * view.guiScale, Y: -200 * view.guiScale}, false, 0) {
|
||||
imgui.PushItemWidth(-150 * view.guiScale)
|
||||
if imgui.BeginCombo("Message Type", knownMessageTypes[view.model.currentKey.ID].title) {
|
||||
for _, id := range knownMessageTypesOrder {
|
||||
if imgui.SelectableV(knownMessageTypes[id].title, id == view.model.currentKey.ID, 0, imgui.Vec2{}) {
|
||||
view.model.currentKey.ID = id
|
||||
view.model.currentKey.Index = 0
|
||||
}
|
||||
}
|
||||
imgui.EndCombo()
|
||||
}
|
||||
info, _ := ids.Info(view.model.currentKey.ID)
|
||||
index := view.model.currentKey.Index
|
||||
if gui.StepSliderInt("Index", &index, 0, info.MaxCount-1) {
|
||||
view.model.currentKey.Index = index
|
||||
}
|
||||
if imgui.BeginCombo("Language", view.model.currentKey.Lang.String()) {
|
||||
languages := resource.Languages()
|
||||
for _, lang := range languages {
|
||||
if imgui.SelectableV(lang.String(), lang == view.model.currentKey.Lang, 0, imgui.Vec2{}) {
|
||||
view.model.currentKey.Lang = lang
|
||||
}
|
||||
}
|
||||
imgui.EndCombo()
|
||||
}
|
||||
|
||||
message, msgReadOnly := view.currentMessage()
|
||||
availableDisplays := view.availableDisplays()
|
||||
|
||||
if imgui.ButtonV("Clear All", imgui.Vec2{}) {
|
||||
view.requestClearAll()
|
||||
}
|
||||
imgui.SameLine()
|
||||
if !msgReadOnly {
|
||||
if imgui.ButtonV("Remove All", imgui.Vec2{}) {
|
||||
view.requestRemoveAll()
|
||||
}
|
||||
} else {
|
||||
imgui.Text("(read-only)")
|
||||
}
|
||||
if view.hasAudio() {
|
||||
imgui.PushID("audio")
|
||||
imgui.Separator()
|
||||
sound, soundReadOnly := view.currentSound()
|
||||
if !sound.Empty() {
|
||||
imgui.LabelText("Audio", fmt.Sprintf("%.2f sec", sound.Duration()))
|
||||
if imgui.Button("Export") {
|
||||
view.requestExportAudio(sound)
|
||||
}
|
||||
if !soundReadOnly {
|
||||
imgui.SameLine()
|
||||
if imgui.Button("Remove") {
|
||||
view.requestRemoveAudio()
|
||||
}
|
||||
}
|
||||
imgui.SameLine()
|
||||
} else {
|
||||
imgui.LabelText("Audio", "(no sound)")
|
||||
}
|
||||
if imgui.Button("Import") {
|
||||
view.requestImportAudio()
|
||||
}
|
||||
imgui.SameLine()
|
||||
if imgui.Button("Clear") {
|
||||
view.requestClearAudio()
|
||||
}
|
||||
imgui.PopID()
|
||||
}
|
||||
imgui.Separator()
|
||||
|
||||
textModes := map[bool]string{true: "Verbose", false: "Terse"}
|
||||
if imgui.BeginCombo("Text Mode", textModes[view.model.showVerboseText]) {
|
||||
for _, setting := range []bool{true, false} {
|
||||
if imgui.SelectableV(textModes[setting], view.model.showVerboseText == setting, 0, imgui.Vec2{}) {
|
||||
view.model.showVerboseText = setting
|
||||
}
|
||||
}
|
||||
imgui.EndCombo()
|
||||
}
|
||||
view.renderText(false, "Title", message.Title, func(newValue string) {
|
||||
view.requestTextChange(func(msg *text.ElectronicMessage) { msg.Title = text.Blocked(newValue)[0] })
|
||||
})
|
||||
view.renderText(false, "Sender", message.Sender, func(newValue string) {
|
||||
view.requestTextChange(func(msg *text.ElectronicMessage) { msg.Sender = text.Blocked(newValue)[0] })
|
||||
})
|
||||
view.renderText(false, "Subject", message.Subject, func(newValue string) {
|
||||
view.requestTextChange(func(msg *text.ElectronicMessage) { msg.Subject = text.Blocked(newValue)[0] })
|
||||
})
|
||||
nextMessageIndex := values.NewUnifier()
|
||||
nextMessageIndex.Add(message.NextMessage)
|
||||
values.RenderUnifiedSliderInt(false, "Next Message Index", nextMessageIndex,
|
||||
func(u values.Unifier) int { return u.Unified().(int) },
|
||||
func(int) string { return "%d" },
|
||||
-1, 255,
|
||||
func(newValue int) {
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.NextMessage = newValue })
|
||||
})
|
||||
|
||||
isInterrupt := values.NewUnifier()
|
||||
isInterrupt.Add(message.IsInterrupt)
|
||||
values.RenderUnifiedCheckboxCombo(false, "Is Interrupt", isInterrupt,
|
||||
func(newValue bool) {
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.IsInterrupt = newValue })
|
||||
})
|
||||
|
||||
colorIndex := values.NewUnifier()
|
||||
colorIndex.Add(message.ColorIndex)
|
||||
values.RenderUnifiedSliderInt(false, "Color Index", colorIndex,
|
||||
func(u values.Unifier) int { return u.Unified().(int) },
|
||||
func(int) string { return "%d" },
|
||||
-1, 255,
|
||||
func(newValue int) {
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.ColorIndex = newValue })
|
||||
})
|
||||
|
||||
if view.model.currentKey.ID == ids.MailsStart {
|
||||
mailType := message.LeftDisplay - videoMailDisplayBase + 1
|
||||
selectedType := fmt.Sprintf("Unknown (0x%03X)", message.LeftDisplay)
|
||||
if mailType < 0 {
|
||||
mailType = 0
|
||||
}
|
||||
if mailType < len(knownMailTypes) {
|
||||
selectedType = knownMailTypes[mailType]
|
||||
}
|
||||
if msgReadOnly {
|
||||
imgui.LabelText("Mail Type", selectedType)
|
||||
} else if imgui.BeginCombo("Mail Type", selectedType) {
|
||||
for typeIndex, typeString := range knownMailTypes {
|
||||
if imgui.SelectableV(typeString, mailType == typeIndex, 0, imgui.Vec2{}) {
|
||||
newIndex := -1
|
||||
if typeIndex > 0 {
|
||||
newIndex = videoMailDisplayBase + (typeIndex - 1)
|
||||
}
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.LeftDisplay = newIndex })
|
||||
}
|
||||
}
|
||||
imgui.EndCombo()
|
||||
}
|
||||
}
|
||||
if message.LeftDisplay < videoMailDisplayBase {
|
||||
view.renderDisplayGallery(false, "Left Display", message.LeftDisplay, availableDisplays,
|
||||
func(newValue int) {
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.LeftDisplay = newValue })
|
||||
})
|
||||
view.renderDisplayGallery(false, "Right Display", message.RightDisplay, availableDisplays,
|
||||
func(newValue int) {
|
||||
view.requestPropertyChange(func(msg *text.ElectronicMessage) { msg.RightDisplay = newValue })
|
||||
})
|
||||
}
|
||||
|
||||
imgui.PopItemWidth()
|
||||
}
|
||||
imgui.EndChild()
|
||||
|
||||
view.renderMFDs()
|
||||
}
|
||||
|
||||
func (view *View) renderMFDs() {
|
||||
message, _ := view.currentMessage()
|
||||
|
||||
view.renderSideImage("LeftMFD", message.LeftDisplay)
|
||||
imgui.SameLineV(0, 0)
|
||||
textToDisplay := message.VerboseText
|
||||
if imgui.BeginChildV("Text", imgui.Vec2{X: -250 * view.guiScale, Y: 190 * view.guiScale}, true, 0) {
|
||||
if !view.model.showVerboseText {
|
||||
textToDisplay = message.TerseText
|
||||
}
|
||||
|
||||
imgui.PushTextWrapPos()
|
||||
if len(textToDisplay) == 0 {
|
||||
imgui.PushStyleColor(imgui.StyleColorText, imgui.Vec4{X: 1.0, Y: 1.0, Z: 1.0, W: 0.5})
|
||||
imgui.Text("(empty)")
|
||||
imgui.PopStyleColor()
|
||||
} else {
|
||||
imgui.Text(textToDisplay)
|
||||
}
|
||||
imgui.PopTextWrapPos()
|
||||
}
|
||||
imgui.EndChild()
|
||||
view.clipboardPopup(false, "Text", textToDisplay, func(newValue string) {
|
||||
view.requestTextChange(func(msg *text.ElectronicMessage) {
|
||||
if view.model.showVerboseText {
|
||||
msg.VerboseText = newValue
|
||||
} else {
|
||||
msg.TerseText = newValue
|
||||
}
|
||||
})
|
||||
})
|
||||
imgui.SameLineV(0, 0)
|
||||
view.renderSideImage("RightMFD", message.RightDisplay)
|
||||
}
|
||||
|
||||
func (view View) currentMessage() (msg text.ElectronicMessage, readOnly bool) {
|
||||
msg = view.messageOf(view.model.currentKey)
|
||||
readOnly = len(view.mod.ModifiedBlocks(view.model.currentKey.Lang, view.model.currentKey.ID.Plus(view.model.currentKey.Index))) == 0
|
||||
return
|
||||
}
|
||||
|
||||
func (view View) hasAudio() bool {
|
||||
return (view.model.currentKey.ID == ids.MailsStart) || (view.model.currentKey.ID == ids.LogsStart)
|
||||
}
|
||||
|
||||
func (view *View) currentSound() (audio.L8, bool) {
|
||||
if view.hasAudio() {
|
||||
key := view.model.currentKey
|
||||
key.ID = key.ID.Plus(300)
|
||||
sound, _ := view.movieCache.Audio(key)
|
||||
readOnly := len(view.mod.ModifiedBlocks(key.Lang, key.ID.Plus(view.model.currentKey.Index))) == 0
|
||||
return sound, readOnly
|
||||
}
|
||||
return audio.L8{}, true
|
||||
}
|
||||
|
||||
func (view View) messageOf(key resource.Key) text.ElectronicMessage {
|
||||
msg, cacheErr := view.messageCache.Message(key)
|
||||
if cacheErr != nil {
|
||||
msg = text.EmptyElectronicMessage()
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func (view *View) availableDisplays() int {
|
||||
selector := view.mod.LocalizedResources(view.model.currentKey.Lang)
|
||||
res, err := selector.Select(ids.MfdDataBitmaps)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return res.BlockCount()
|
||||
}
|
||||
|
||||
func (view *View) renderText(readOnly bool, label string, value string, changeCallback func(string)) {
|
||||
imgui.LabelText(label, value)
|
||||
view.clipboardPopup(readOnly, label, value, changeCallback)
|
||||
}
|
||||
|
||||
func (view *View) clipboardPopup(readOnly bool, label string, value string, changeCallback func(string)) {
|
||||
if imgui.BeginPopupContextItemV(label+"-Popup", 1) {
|
||||
if imgui.Selectable("Copy to Clipboard") {
|
||||
view.clipboard.SetString(value)
|
||||
}
|
||||
if !readOnly && imgui.Selectable("Copy from Clipboard") {
|
||||
newValue, err := view.clipboard.String()
|
||||
if err == nil {
|
||||
changeCallback(newValue)
|
||||
}
|
||||
}
|
||||
imgui.EndPopup()
|
||||
}
|
||||
}
|
||||
|
||||
func (view *View) renderDisplayGallery(readOnly bool, label string, index, availableDisplays int,
|
||||
changeCallback func(int)) {
|
||||
unifier := values.NewUnifier()
|
||||
unifier.Add(index)
|
||||
values.RenderUnifiedSliderInt(readOnly, label, unifier,
|
||||
func(u values.Unifier) int { return u.Unified().(int) },
|
||||
func(int) string { return "%d" },
|
||||
-1, availableDisplays-1,
|
||||
changeCallback)
|
||||
render.TextureSelector("###"+label+" Texture", -1, view.guiScale, availableDisplays,
|
||||
index, view.imageCache,
|
||||
func(index int) resource.Key {
|
||||
return resource.KeyOf(ids.MfdDataBitmaps, view.model.currentKey.Lang, index)
|
||||
},
|
||||
func(index int) string { return fmt.Sprintf("%d", index) },
|
||||
changeCallback)
|
||||
}
|
||||
|
||||
func (view *View) renderSideImage(label string, index int) {
|
||||
size := imgui.Vec2{X: 250 * view.guiScale, Y: 190 * view.guiScale}
|
||||
imgui.PushStyleVarVec2(imgui.StyleVarWindowPadding, imgui.Vec2{X: size.X, Y: -size.Y})
|
||||
if imgui.BeginChildV(label, size, false, 0) {
|
||||
if index >= 0 {
|
||||
key := resource.KeyOf(ids.MfdDataBitmaps, view.model.currentKey.Lang, index)
|
||||
render.TextureImage(label, view.imageCache, key, size)
|
||||
}
|
||||
}
|
||||
imgui.PopStyleVar()
|
||||
imgui.EndChild()
|
||||
}
|
||||
|
||||
func (view *View) requestExportAudio(sound audio.L8) {
|
||||
filename := fmt.Sprintf("%05d_%s.wav",
|
||||
view.model.currentKey.ID.Plus(view.model.currentKey.Index).Plus(300).Value(),
|
||||
view.model.currentKey.Lang.String())
|
||||
|
||||
external.ExportAudio(view.modalStateMachine, filename, sound)
|
||||
}
|
||||
|
||||
func (view *View) requestRemoveAudio() {
|
||||
view.requestAudioChange(nil)
|
||||
}
|
||||
|
||||
func (view *View) requestImportAudio() {
|
||||
external.ImportAudio(view.modalStateMachine, func(sound audio.L8) {
|
||||
movieData := movie.ContainSoundData(sound)
|
||||
view.requestAudioChange(movieData)
|
||||
})
|
||||
}
|
||||
|
||||
func (view *View) requestClearAudio() {
|
||||
view.requestAudioChange(view.silence())
|
||||
}
|
||||
|
||||
func (view View) silence() []byte {
|
||||
silence := audio.L8{SampleRate: 22050, Samples: []byte{0x80}}
|
||||
return movie.ContainSoundData(silence)
|
||||
}
|
||||
|
||||
func (view *View) requestClearAll() {
|
||||
view.requestWipe(text.EmptyElectronicMessage().Encode(view.cp), view.silence())
|
||||
}
|
||||
|
||||
func (view *View) requestRemoveAll() {
|
||||
view.requestWipe(nil, nil)
|
||||
}
|
||||
|
||||
func (view *View) requestWipe(newTextData [][]byte, newAudioData []byte) {
|
||||
textEntries := make(map[resource.Language]messageDataEntry)
|
||||
audioEntries := make(map[resource.Language]messageDataEntry)
|
||||
textID := view.model.currentKey.ID.Plus(view.model.currentKey.Index)
|
||||
for lang := resource.Language(0); lang < resource.LanguageCount; lang++ {
|
||||
textEntries[lang] = messageDataEntry{
|
||||
oldData: view.mod.ModifiedBlocks(lang, textID),
|
||||
newData: newTextData,
|
||||
}
|
||||
if view.hasAudio() {
|
||||
audioEntries[lang] = messageDataEntry{
|
||||
oldData: view.mod.ModifiedBlocks(lang, textID.Plus(300)),
|
||||
newData: [][]byte{newAudioData},
|
||||
}
|
||||
}
|
||||
}
|
||||
view.requestSetMessageData(textEntries, audioEntries)
|
||||
}
|
||||
|
||||
func (view *View) requestTextChange(modifier func(*text.ElectronicMessage)) {
|
||||
msg := view.messageOf(view.model.currentKey)
|
||||
entries := make(map[resource.Language]messageDataEntry)
|
||||
modifier(&msg)
|
||||
|
||||
entries[view.model.currentKey.Lang] = messageDataEntry{
|
||||
oldData: view.mod.ModifiedBlocks(view.model.currentKey.Lang, view.model.currentKey.ID.Plus(view.model.currentKey.Index)),
|
||||
newData: msg.Encode(view.cp),
|
||||
}
|
||||
view.requestSetMessageData(entries, nil)
|
||||
}
|
||||
|
||||
func (view *View) requestPropertyChange(modifier func(*text.ElectronicMessage)) {
|
||||
entries := make(map[resource.Language]messageDataEntry)
|
||||
for lang := resource.Language(0); lang < resource.LanguageCount; lang++ {
|
||||
key := view.model.currentKey
|
||||
key.Lang = lang
|
||||
msg := view.messageOf(key)
|
||||
modifier(&msg)
|
||||
|
||||
entries[lang] = messageDataEntry{
|
||||
oldData: view.mod.ModifiedBlocks(lang, key.ID.Plus(key.Index)),
|
||||
newData: msg.Encode(view.cp),
|
||||
}
|
||||
}
|
||||
view.requestSetMessageData(entries, nil)
|
||||
}
|
||||
|
||||
func (view *View) requestAudioChange(movieData []byte) {
|
||||
entries := make(map[resource.Language]messageDataEntry)
|
||||
|
||||
entries[view.model.currentKey.Lang] = messageDataEntry{
|
||||
oldData: view.mod.ModifiedBlocks(view.model.currentKey.Lang, view.model.currentKey.ID.Plus(view.model.currentKey.Index).Plus(300)),
|
||||
newData: [][]byte{movieData},
|
||||
}
|
||||
view.requestSetMessageData(nil, entries)
|
||||
}
|
||||
|
||||
func (view *View) requestSetMessageData(textEntries map[resource.Language]messageDataEntry, audioEntries map[resource.Language]messageDataEntry) {
|
||||
command := setMessageDataCommand{
|
||||
key: view.model.currentKey,
|
||||
showVerboseText: view.model.showVerboseText,
|
||||
model: &view.model,
|
||||
textEntries: textEntries,
|
||||
audioEntries: audioEntries,
|
||||
}
|
||||
view.commander.Queue(command)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package messages
|
||||
|
||||
import (
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
"github.com/inkyblackness/hacked/ss1/world/ids"
|
||||
)
|
||||
|
||||
type viewModel struct {
|
||||
windowOpen bool
|
||||
restoreFocus bool
|
||||
|
||||
currentKey resource.Key
|
||||
showVerboseText bool
|
||||
}
|
||||
|
||||
func freshViewModel() viewModel {
|
||||
return viewModel{
|
||||
currentKey: resource.KeyOf(ids.MailsStart, resource.LangDefault, 0),
|
||||
showVerboseText: true,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user