Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
package texts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/inkyblackness/imgui-go/v3"
|
||||
|
||||
"github.com/inkyblackness/hacked/editor/external"
|
||||
"github.com/inkyblackness/hacked/ss1/content/audio"
|
||||
"github.com/inkyblackness/hacked/ss1/edit"
|
||||
"github.com/inkyblackness/hacked/ss1/edit/undoable"
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
"github.com/inkyblackness/hacked/ss1/world/ids"
|
||||
"github.com/inkyblackness/hacked/ui/gui"
|
||||
)
|
||||
|
||||
// View provides edit controls for texts.
|
||||
type View struct {
|
||||
textService undoable.AugmentedTextService
|
||||
|
||||
modalStateMachine gui.ModalStateMachine
|
||||
clipboard external.Clipboard
|
||||
guiScale float32
|
||||
|
||||
model viewModel
|
||||
}
|
||||
|
||||
// NewTextsView returns a new instance.
|
||||
func NewTextsView(textService undoable.AugmentedTextService,
|
||||
modalStateMachine gui.ModalStateMachine, clipboard external.Clipboard,
|
||||
guiScale float32) *View {
|
||||
view := &View{
|
||||
textService: textService,
|
||||
|
||||
modalStateMachine: modalStateMachine,
|
||||
clipboard: clipboard,
|
||||
guiScale: guiScale,
|
||||
|
||||
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: 400 * view.guiScale, Y: 300 * view.guiScale}, imgui.ConditionFirstUseEver)
|
||||
if imgui.BeginV("Texts", view.WindowOpen(), imgui.WindowFlagsNoCollapse) {
|
||||
view.renderContent()
|
||||
}
|
||||
imgui.End()
|
||||
}
|
||||
}
|
||||
|
||||
func (view *View) renderContent() {
|
||||
knownTexts := edit.KnownTexts()
|
||||
imgui.PushItemWidth(-100 * view.guiScale)
|
||||
if imgui.BeginCombo("Text Type", knownTexts.Title(view.model.currentKey.ID)) {
|
||||
for _, info := range knownTexts {
|
||||
if imgui.SelectableV(info.Title, info.ID == view.model.currentKey.ID, 0, imgui.Vec2{}) {
|
||||
view.model.currentKey.ID = info.ID
|
||||
view.model.currentKey.Index = 0
|
||||
}
|
||||
}
|
||||
imgui.EndCombo()
|
||||
}
|
||||
info, _ := ids.Info(view.model.currentKey.ID)
|
||||
gui.StepSliderInt("Index", &view.model.currentKey.Index, 0, info.MaxCount-1)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
if view.textIsWithAudio() {
|
||||
imgui.Separator()
|
||||
sound := view.currentSound()
|
||||
if !sound.Empty() {
|
||||
imgui.LabelText("Audio", fmt.Sprintf("%.2f sec", sound.Duration()))
|
||||
if imgui.Button("Export") {
|
||||
view.requestExportAudio(sound)
|
||||
}
|
||||
imgui.SameLine()
|
||||
} else {
|
||||
imgui.LabelText("Audio", "(no sound)")
|
||||
}
|
||||
if imgui.Button("Import") {
|
||||
view.requestImportAudio()
|
||||
}
|
||||
}
|
||||
imgui.Separator()
|
||||
|
||||
imgui.PopItemWidth()
|
||||
|
||||
currentText := view.currentText()
|
||||
imgui.BeginChildV("Text", imgui.Vec2{X: -100 * view.guiScale, Y: 0}, true, 0)
|
||||
imgui.PushTextWrapPos()
|
||||
if len(currentText) == 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(currentText)
|
||||
}
|
||||
imgui.PopTextWrapPos()
|
||||
imgui.EndChild()
|
||||
|
||||
imgui.SameLine()
|
||||
|
||||
imgui.BeginGroup()
|
||||
if imgui.ButtonV("-> Clip", imgui.Vec2{X: -1, Y: 0}) {
|
||||
view.copyTextToClipboard(currentText)
|
||||
}
|
||||
if imgui.ButtonV("<- Clip", imgui.Vec2{X: -1, Y: 0}) {
|
||||
view.setTextFromClipboard()
|
||||
}
|
||||
if imgui.ButtonV("Clear", imgui.Vec2{X: -1, Y: 0}) {
|
||||
view.clearText()
|
||||
}
|
||||
if imgui.ButtonV("Remove", imgui.Vec2{X: -1, Y: 0}) {
|
||||
view.removeText()
|
||||
}
|
||||
imgui.EndGroup()
|
||||
}
|
||||
|
||||
func (view View) currentText() string {
|
||||
return view.textService.Text(view.model.currentKey)
|
||||
}
|
||||
|
||||
func (view View) copyTextToClipboard(text string) {
|
||||
if len(text) > 0 {
|
||||
view.clipboard.SetString(text)
|
||||
}
|
||||
}
|
||||
|
||||
func (view *View) setTextFromClipboard() {
|
||||
value, err := view.clipboard.String()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
view.textService.RequestSetText(view.model.currentKey, value, view.restoreFunc())
|
||||
}
|
||||
|
||||
func (view *View) clearText() {
|
||||
view.textService.RequestClear(view.model.currentKey, view.restoreFunc())
|
||||
}
|
||||
|
||||
func (view *View) removeText() {
|
||||
view.textService.RequestRemove(view.model.currentKey, view.restoreFunc())
|
||||
}
|
||||
|
||||
func (view View) textIsWithAudio() bool {
|
||||
return view.textService.WithAudio(view.model.currentKey)
|
||||
}
|
||||
|
||||
func (view *View) currentSound() (sound audio.L8) {
|
||||
return view.textService.Sound(view.model.currentKey)
|
||||
}
|
||||
|
||||
func (view *View) requestExportAudio(sound audio.L8) {
|
||||
if !view.textIsWithAudio() {
|
||||
return
|
||||
}
|
||||
filename := fmt.Sprintf("%05d_%03d_%s.wav", view.model.currentKey.ID, view.model.currentKey.Index, view.model.currentKey.Lang.String())
|
||||
|
||||
external.ExportAudio(view.modalStateMachine, filename, sound)
|
||||
}
|
||||
|
||||
func (view *View) requestImportAudio() {
|
||||
external.ImportAudio(view.modalStateMachine, func(sound audio.L8) {
|
||||
view.textService.RequestSetSound(view.model.currentKey, sound, view.restoreFunc())
|
||||
})
|
||||
}
|
||||
|
||||
func (view *View) restoreFunc() func() {
|
||||
oldKey := view.model.currentKey
|
||||
|
||||
return func() {
|
||||
view.model.restoreFocus = true
|
||||
view.model.currentKey = oldKey
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package texts
|
||||
|
||||
import (
|
||||
"github.com/inkyblackness/hacked/ss1/edit"
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
)
|
||||
|
||||
type viewModel struct {
|
||||
windowOpen bool
|
||||
restoreFocus bool
|
||||
currentKey resource.Key
|
||||
}
|
||||
|
||||
func freshViewModel() viewModel {
|
||||
return viewModel{
|
||||
currentKey: resource.KeyOf(edit.KnownTexts()[0].ID, resource.LangDefault, 0),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user