mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-16 09:25:57 -05:00
518a667a84
Co-authored-by: M. Sz <mszeptuch@protonmail.com>
740 lines
21 KiB
Go
740 lines
21 KiB
Go
package d2player
|
|
|
|
import (
|
|
"image/color"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
|
)
|
|
|
|
const (
|
|
selectionBackgroundColor = 0x000000d0
|
|
defaultGameEvent = -1
|
|
|
|
keyBindingMenuWidth = 620
|
|
keyBindingMenuHeight = 375
|
|
keyBindingMenuX = 90
|
|
keyBindingMenuY = 75
|
|
|
|
keyBindingMenuPaddingX = 17
|
|
keyBindingSettingPaddingY = 19
|
|
|
|
keyBindingMenuHeaderHeight = 24
|
|
keyBindingMenuHeaderSpacer1 = 131
|
|
keyBindingMenuHeaderSpacer2 = 86
|
|
|
|
keyBindingMenuBindingSpacerBetween = 25
|
|
keyBindingMenuBindingSpacerLeft = 17
|
|
keyBindingMenuBindingDescWidth = 190
|
|
keyBindingMenuBindingDescHeight = 0
|
|
keyBindingMenuBindingPrimaryWidth = 190
|
|
keyBindingMenuBindingPrimaryHeight = 0
|
|
keyBindingMenuBindingSecondaryWidth = 90
|
|
keyBindingMenuBindingSecondaryHeight = 0
|
|
)
|
|
|
|
type bindingChange struct {
|
|
target *KeyBinding
|
|
primary d2enum.Key
|
|
secondary d2enum.Key
|
|
}
|
|
|
|
// NewKeyBindingMenu generates a new instance of the "Configure Keys"
|
|
// menu found in the options
|
|
func NewKeyBindingMenu(
|
|
asset *d2asset.AssetManager,
|
|
renderer d2interface.Renderer,
|
|
ui *d2ui.UIManager,
|
|
guiManager *d2gui.GuiManager,
|
|
keyMap *KeyMap,
|
|
l d2util.LogLevel,
|
|
escapeMenu *EscapeMenu,
|
|
) *KeyBindingMenu {
|
|
mainLayout := d2gui.CreateLayout(renderer, d2gui.PositionTypeAbsolute, asset)
|
|
contentLayout := mainLayout.AddLayout(d2gui.PositionTypeAbsolute)
|
|
|
|
ret := &KeyBindingMenu{
|
|
keyMap: keyMap,
|
|
asset: asset,
|
|
ui: ui,
|
|
guiManager: guiManager,
|
|
renderer: renderer,
|
|
mainLayout: mainLayout,
|
|
contentLayout: contentLayout,
|
|
bindingLayouts: []*bindingLayout{},
|
|
changesToBeSaved: make(map[d2enum.GameEvent]*bindingChange),
|
|
escapeMenu: escapeMenu,
|
|
}
|
|
|
|
ret.Logger = d2util.NewLogger()
|
|
ret.Logger.SetLevel(l)
|
|
ret.Logger.SetPrefix(logPrefix)
|
|
|
|
ret.Box = d2gui.NewBox(
|
|
asset, renderer, ui, ret.mainLayout,
|
|
keyBindingMenuWidth, keyBindingMenuHeight,
|
|
keyBindingMenuX, keyBindingMenuY, l, "",
|
|
)
|
|
|
|
ret.Box.SetPadding(keyBindingMenuPaddingX, keyBindingSettingPaddingY)
|
|
|
|
ret.Box.SetOptions([]*d2gui.LabelButton{
|
|
d2gui.NewLabelButton(0, 0, "Cancel", d2util.Color(d2gui.ColorRed), d2util.LogLevelDefault, func() {
|
|
if err := ret.onCancelClicked(); err != nil {
|
|
ret.Errorf("error while clicking option Cancel: %v", err.Error())
|
|
}
|
|
}),
|
|
d2gui.NewLabelButton(0, 0, "Default", d2util.Color(d2gui.ColorBlue), d2util.LogLevelDefault, func() {
|
|
if err := ret.onDefaultClicked(); err != nil {
|
|
ret.Errorf("error while clicking option Default: %v", err)
|
|
}
|
|
}),
|
|
d2gui.NewLabelButton(0, 0, "Accept", d2util.Color(d2gui.ColorGreen), d2util.LogLevelDefault, func() {
|
|
if err := ret.onAcceptClicked(); err != nil {
|
|
ret.Errorf("error while clicking option Accept: %v", err)
|
|
}
|
|
}),
|
|
})
|
|
|
|
return ret
|
|
}
|
|
|
|
// KeyBindingMenu represents the menu to view/edit the
|
|
// key bindings
|
|
type KeyBindingMenu struct {
|
|
*d2gui.Box
|
|
|
|
asset *d2asset.AssetManager
|
|
renderer d2interface.Renderer
|
|
ui *d2ui.UIManager
|
|
guiManager *d2gui.GuiManager
|
|
keyMap *KeyMap
|
|
escapeMenu *EscapeMenu
|
|
|
|
mainLayout *d2gui.Layout
|
|
contentLayout *d2gui.Layout
|
|
scrollbar *d2gui.LayoutScrollbar
|
|
bindingLayouts []*bindingLayout
|
|
changesToBeSaved map[d2enum.GameEvent]*bindingChange
|
|
|
|
isAwaitingKeyDown bool
|
|
currentBindingModifierType KeyBindingType
|
|
currentBindingModifier d2enum.GameEvent
|
|
currentBindingLayout *bindingLayout
|
|
lastBindingLayout *bindingLayout
|
|
|
|
*d2util.Logger
|
|
}
|
|
|
|
// Close will disable the render of the menu and clear
|
|
// the current selection
|
|
func (menu *KeyBindingMenu) Close() error {
|
|
menu.Box.Close()
|
|
|
|
if err := menu.clearSelection(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Load will setup the layouts of the menu
|
|
func (menu *KeyBindingMenu) Load() error {
|
|
if err := menu.Box.Load(); err != nil {
|
|
return err
|
|
}
|
|
|
|
mainLayoutW, mainLayoutH := menu.mainLayout.GetSize()
|
|
|
|
headerLayout := menu.contentLayout.AddLayout(d2gui.PositionTypeHorizontal)
|
|
headerLayout.SetSize(mainLayoutW, keyBindingMenuHeaderHeight)
|
|
|
|
if _, err := headerLayout.AddLabelWithColor(
|
|
menu.asset.TranslateString("CfgFunction"),
|
|
d2gui.FontStyleFormal11Units,
|
|
d2util.Color(d2gui.ColorBrown),
|
|
); err != nil {
|
|
return err
|
|
}
|
|
|
|
headerLayout.AddSpacerStatic(keyBindingMenuHeaderSpacer1, keyBindingMenuHeaderHeight)
|
|
|
|
if _, err := headerLayout.AddLabelWithColor(
|
|
menu.asset.TranslateString("CfgPrimaryKey"),
|
|
d2gui.FontStyleFormal11Units,
|
|
d2util.Color(d2gui.ColorBrown),
|
|
); err != nil {
|
|
return err
|
|
}
|
|
|
|
headerLayout.AddSpacerStatic(keyBindingMenuHeaderSpacer2, 1)
|
|
|
|
if _, err := headerLayout.AddLabelWithColor(
|
|
menu.asset.TranslateString("CfgSecondaryKey"),
|
|
d2gui.FontStyleFormal11Units,
|
|
d2util.Color(d2gui.ColorBrown),
|
|
); err != nil {
|
|
return err
|
|
}
|
|
|
|
headerLayout.SetVerticalAlign(d2gui.VerticalAlignMiddle)
|
|
|
|
bindingWrapper := menu.contentLayout.AddLayout(d2gui.PositionTypeAbsolute)
|
|
bindingWrapper.SetPosition(0, keyBindingMenuHeaderHeight)
|
|
bindingWrapper.SetSize(mainLayoutW, mainLayoutH-keyBindingMenuHeaderHeight)
|
|
|
|
bindingLayout := menu.generateLayout()
|
|
|
|
menu.Box.GetLayout().AdjustEntryPlacement()
|
|
menu.mainLayout.AdjustEntryPlacement()
|
|
menu.contentLayout.AdjustEntryPlacement()
|
|
|
|
menu.scrollbar = d2gui.NewLayoutScrollbar(bindingWrapper, bindingLayout)
|
|
|
|
if err := menu.scrollbar.Load(menu.ui); err != nil {
|
|
return err
|
|
}
|
|
|
|
bindingWrapper.AddLayoutFromSource(bindingLayout)
|
|
bindingWrapper.AdjustEntryPlacement()
|
|
|
|
return nil
|
|
}
|
|
|
|
type keyBindingSetting struct {
|
|
label string
|
|
gameEvent d2enum.GameEvent
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) getBindingGroups() [][]keyBindingSetting {
|
|
return [][]keyBindingSetting{
|
|
{
|
|
{menu.asset.TranslateString("CfgCharacter"), d2enum.ToggleCharacterPanel},
|
|
{menu.asset.TranslateString("CfgInventory"), d2enum.ToggleInventoryPanel},
|
|
{menu.asset.TranslateString("CfgParty"), d2enum.TogglePartyPanel},
|
|
{menu.asset.TranslateString("Cfghireling"), d2enum.ToggleHirelingPanel},
|
|
{menu.asset.TranslateString("CfgMessageLog"), d2enum.ToggleMessageLog},
|
|
{menu.asset.TranslateString("CfgQuestLog"), d2enum.ToggleQuestLog},
|
|
{menu.asset.TranslateString("CfgHelp"), d2enum.ToggleHelpScreen},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgSkillTree"), d2enum.ToggleSkillTreePanel},
|
|
{menu.asset.TranslateString("CfgSkillPick"), d2enum.ToggleRightSkillSelector},
|
|
{menu.asset.TranslateString("CfgSkill1"), d2enum.UseSkill1},
|
|
{menu.asset.TranslateString("CfgSkill2"), d2enum.UseSkill2},
|
|
{menu.asset.TranslateString("CfgSkill3"), d2enum.UseSkill3},
|
|
{menu.asset.TranslateString("CfgSkill4"), d2enum.UseSkill4},
|
|
{menu.asset.TranslateString("CfgSkill5"), d2enum.UseSkill5},
|
|
{menu.asset.TranslateString("CfgSkill6"), d2enum.UseSkill6},
|
|
{menu.asset.TranslateString("CfgSkill7"), d2enum.UseSkill7},
|
|
{menu.asset.TranslateString("CfgSkill8"), d2enum.UseSkill8},
|
|
{menu.asset.TranslateString("CfgSkill9"), d2enum.UseSkill9},
|
|
{menu.asset.TranslateString("CfgSkill10"), d2enum.UseSkill10},
|
|
{menu.asset.TranslateString("CfgSkill11"), d2enum.UseSkill11},
|
|
{menu.asset.TranslateString("CfgSkill12"), d2enum.UseSkill12},
|
|
{menu.asset.TranslateString("CfgSkill13"), d2enum.UseSkill13},
|
|
{menu.asset.TranslateString("CfgSkill14"), d2enum.UseSkill14},
|
|
{menu.asset.TranslateString("CfgSkill15"), d2enum.UseSkill15},
|
|
{menu.asset.TranslateString("CfgSkill16"), d2enum.UseSkill16},
|
|
{menu.asset.TranslateString("Cfgskillup"), d2enum.SelectPreviousSkill},
|
|
{menu.asset.TranslateString("Cfgskilldown"), d2enum.SelectNextSkill},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgBeltShow"), d2enum.ToggleBelts},
|
|
{menu.asset.TranslateString("CfgBelt1"), d2enum.UseBeltSlot1},
|
|
{menu.asset.TranslateString("CfgBelt2"), d2enum.UseBeltSlot2},
|
|
{menu.asset.TranslateString("CfgBelt3"), d2enum.UseBeltSlot3},
|
|
{menu.asset.TranslateString("CfgBelt4"), d2enum.UseBeltSlot4},
|
|
{menu.asset.TranslateString("Cfgswapweapons"), d2enum.SwapWeapons},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgChat"), d2enum.ToggleChatBox},
|
|
{menu.asset.TranslateString("CfgRun"), d2enum.HoldRun},
|
|
{menu.asset.TranslateString("CfgRunLock"), d2enum.ToggleRunWalk},
|
|
{menu.asset.TranslateString("CfgStandStill"), d2enum.HoldStandStill},
|
|
{menu.asset.TranslateString("CfgShowItems"), d2enum.HoldShowGroundItems},
|
|
{menu.asset.TranslateString("CfgTogglePortraits"), d2enum.HoldShowPortraits},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgAutoMap"), d2enum.ToggleAutomap},
|
|
{menu.asset.TranslateString("CfgAutoMapCenter"), d2enum.CenterAutomap},
|
|
{menu.asset.TranslateString("CfgAutoMapParty"), d2enum.TogglePartyOnAutomap},
|
|
{menu.asset.TranslateString("CfgAutoMapNames"), d2enum.ToggleNamesOnAutomap},
|
|
{menu.asset.TranslateString("CfgToggleminimap"), d2enum.ToggleMiniMap},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgSay0"), d2enum.SayHelp},
|
|
{menu.asset.TranslateString("CfgSay1"), d2enum.SayFollowMe},
|
|
{menu.asset.TranslateString("CfgSay2"), d2enum.SayThisIsForYou},
|
|
{menu.asset.TranslateString("CfgSay3"), d2enum.SayThanks},
|
|
{menu.asset.TranslateString("CfgSay4"), d2enum.SaySorry},
|
|
{menu.asset.TranslateString("CfgSay5"), d2enum.SayBye},
|
|
{menu.asset.TranslateString("CfgSay6"), d2enum.SayNowYouDie},
|
|
{menu.asset.TranslateString("CfgSay7"), d2enum.SayNowYouDie},
|
|
},
|
|
{
|
|
{menu.asset.TranslateString("CfgSnapshot"), d2enum.TakeScreenShot},
|
|
{menu.asset.TranslateString("CfgClearScreen"), d2enum.ClearScreen},
|
|
{menu.asset.TranslateString("Cfgcleartextmsg"), d2enum.ClearMessages},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) generateLayout() *d2gui.Layout {
|
|
groups := menu.getBindingGroups()
|
|
|
|
wrapper := d2gui.CreateLayout(menu.renderer, d2gui.PositionTypeAbsolute, menu.asset)
|
|
layout := wrapper.AddLayout(d2gui.PositionTypeVertical)
|
|
|
|
for i, settingsGroup := range groups {
|
|
groupLayout := layout.AddLayout(d2gui.PositionTypeVertical)
|
|
|
|
for _, setting := range settingsGroup {
|
|
bl := bindingLayout{}
|
|
|
|
settingLayout := groupLayout.AddLayout(d2gui.PositionTypeHorizontal)
|
|
settingLayout.AddSpacerStatic(keyBindingMenuBindingSpacerLeft, 0)
|
|
descLabelWrapper := settingLayout.AddLayout(d2gui.PositionTypeAbsolute)
|
|
descLabelWrapper.SetSize(keyBindingMenuBindingDescWidth, keyBindingMenuBindingDescHeight)
|
|
|
|
descLabel, _ := descLabelWrapper.AddLabel(setting.label, d2gui.FontStyleFormal11Units)
|
|
descLabel.SetHoverColor(d2util.Color(d2gui.ColorBlue))
|
|
|
|
bl.wrapperLayout = settingLayout
|
|
bl.descLabel = descLabel
|
|
bl.descLayout = descLabelWrapper
|
|
|
|
if binding := menu.keyMap.GetKeysForGameEvent(setting.gameEvent); binding != nil {
|
|
primaryStr := menu.keyMap.KeyToString(binding.Primary)
|
|
secondaryStr := menu.keyMap.KeyToString(binding.Secondary)
|
|
primaryCol := menu.getKeyColor(binding.Primary)
|
|
secondaryCol := menu.getKeyColor(binding.Secondary)
|
|
|
|
if binding.IsEmpty() {
|
|
primaryCol = d2util.Color(d2gui.ColorRed)
|
|
secondaryCol = d2util.Color(d2gui.ColorRed)
|
|
}
|
|
|
|
primaryKeyLabelWrapper := settingLayout.AddLayout(d2gui.PositionTypeAbsolute)
|
|
primaryKeyLabelWrapper.SetSize(keyBindingMenuBindingPrimaryWidth, keyBindingMenuBindingPrimaryHeight)
|
|
primaryLabel, _ := primaryKeyLabelWrapper.AddLabelWithColor(primaryStr, d2gui.FontStyleFormal11Units, primaryCol)
|
|
primaryLabel.SetHoverColor(d2util.Color(d2gui.ColorBlue))
|
|
|
|
bl.primaryLabel = primaryLabel
|
|
bl.primaryLayout = primaryKeyLabelWrapper
|
|
bl.gameEvent = setting.gameEvent
|
|
|
|
secondaryKeyLabelWrapper := settingLayout.AddLayout(d2gui.PositionTypeAbsolute)
|
|
secondaryKeyLabelWrapper.SetSize(keyBindingMenuBindingSecondaryWidth, keyBindingMenuBindingSecondaryHeight)
|
|
secondaryLabel, _ := secondaryKeyLabelWrapper.AddLabelWithColor(secondaryStr, d2gui.FontStyleFormal11Units, secondaryCol)
|
|
secondaryLabel.SetHoverColor(d2util.Color(d2gui.ColorBlue))
|
|
|
|
bl.secondaryLabel = secondaryLabel
|
|
bl.secondaryLayout = secondaryKeyLabelWrapper
|
|
bl.binding = binding
|
|
}
|
|
|
|
menu.bindingLayouts = append(menu.bindingLayouts, &bl)
|
|
}
|
|
|
|
if i < len(groups)-1 {
|
|
layout.AddSpacerStatic(0, keyBindingMenuBindingSpacerBetween)
|
|
}
|
|
}
|
|
|
|
return wrapper
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) getKeyColor(key d2enum.Key) color.RGBA {
|
|
switch key {
|
|
case -1:
|
|
return d2util.Color(d2gui.ColorGrey)
|
|
default:
|
|
return d2util.Color(d2gui.ColorBrown)
|
|
}
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) setSelection(bl *bindingLayout, bindingType KeyBindingType, gameEvent d2enum.GameEvent) error {
|
|
if menu.currentBindingLayout != nil {
|
|
menu.lastBindingLayout = menu.currentBindingLayout
|
|
if err := menu.currentBindingLayout.Reset(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
menu.currentBindingModifier = gameEvent
|
|
menu.currentBindingLayout = bl
|
|
|
|
if bindingType == KeyBindingTypePrimary {
|
|
menu.currentBindingLayout.primaryLabel.SetIsBlinking(true)
|
|
} else if bindingType == KeyBindingTypeSecondary {
|
|
menu.currentBindingLayout.secondaryLabel.SetIsBlinking(true)
|
|
}
|
|
|
|
menu.currentBindingModifierType = bindingType
|
|
menu.isAwaitingKeyDown = true
|
|
|
|
if err := bl.descLabel.SetIsHovered(true); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := bl.primaryLabel.SetIsHovered(true); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := bl.secondaryLabel.SetIsHovered(true); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onMouseButtonDown(event d2interface.MouseEvent) error {
|
|
if !menu.IsOpen() {
|
|
return nil
|
|
}
|
|
|
|
menu.Box.OnMouseButtonDown(event)
|
|
|
|
if menu.scrollbar != nil {
|
|
if menu.scrollbar.IsInSliderRect(event.X(), event.Y()) {
|
|
menu.scrollbar.SetSliderClicked(true)
|
|
menu.scrollbar.OnSliderMouseClick(event)
|
|
|
|
return nil
|
|
}
|
|
|
|
if menu.scrollbar.IsInArrowUpRect(event.X(), event.Y()) {
|
|
if !menu.scrollbar.IsArrowUpClicked() {
|
|
menu.scrollbar.SetArrowUpClicked(true)
|
|
}
|
|
|
|
menu.scrollbar.OnArrowUpClick()
|
|
|
|
return nil
|
|
}
|
|
|
|
if menu.scrollbar.IsInArrowDownRect(event.X(), event.Y()) {
|
|
if !menu.scrollbar.IsArrowDownClicked() {
|
|
menu.scrollbar.SetArrowDownClicked(true)
|
|
}
|
|
|
|
menu.scrollbar.OnArrowDownClick()
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
for _, bl := range menu.bindingLayouts {
|
|
gameEvent, typ := bl.GetPointedLayoutAndLabel(event.X(), event.Y())
|
|
|
|
if gameEvent != -1 {
|
|
if err := menu.setSelection(bl, typ, gameEvent); err != nil {
|
|
return err
|
|
}
|
|
|
|
break
|
|
} else if menu.currentBindingLayout != nil {
|
|
if err := menu.clearSelection(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onMouseMove(event d2interface.MouseMoveEvent) {
|
|
if !menu.IsOpen() {
|
|
return
|
|
}
|
|
|
|
if menu.scrollbar != nil && menu.scrollbar.IsSliderClicked() {
|
|
menu.scrollbar.OnMouseMove(event)
|
|
}
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onMouseButtonUp() {
|
|
if !menu.IsOpen() {
|
|
return
|
|
}
|
|
|
|
if menu.scrollbar != nil {
|
|
menu.scrollbar.SetSliderClicked(false)
|
|
menu.scrollbar.SetArrowDownClicked(false)
|
|
menu.scrollbar.SetArrowUpClicked(false)
|
|
}
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) getPendingChangeByKey(key d2enum.Key) (*bindingChange, *KeyBinding, d2enum.GameEvent, KeyBindingType) {
|
|
var (
|
|
existingBinding *KeyBinding
|
|
gameEvent d2enum.GameEvent
|
|
bindingType KeyBindingType
|
|
)
|
|
|
|
for ge, existingChange := range menu.changesToBeSaved {
|
|
if existingChange.primary == key {
|
|
bindingType = KeyBindingTypePrimary
|
|
} else if existingChange.secondary == key {
|
|
bindingType = KeyBindingTypeSecondary
|
|
}
|
|
|
|
if bindingType != -1 {
|
|
existingBinding = existingChange.target
|
|
gameEvent = ge
|
|
|
|
return existingChange, existingBinding, gameEvent, bindingType
|
|
}
|
|
}
|
|
|
|
return nil, nil, -1, KeyBindingTypeNone
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) saveKeyChange(key d2enum.Key) error {
|
|
changeExisting, existingBinding, gameEvent, bindingType := menu.getPendingChangeByKey(key)
|
|
|
|
if changeExisting == nil {
|
|
existingBinding, gameEvent, bindingType = menu.keyMap.GetBindingByKey(key)
|
|
}
|
|
|
|
if existingBinding != nil && changeExisting == nil {
|
|
changeExisting = &bindingChange{
|
|
target: existingBinding,
|
|
primary: existingBinding.Primary,
|
|
secondary: existingBinding.Secondary,
|
|
}
|
|
|
|
menu.changesToBeSaved[gameEvent] = changeExisting
|
|
}
|
|
|
|
changeCurrent := menu.changesToBeSaved[menu.currentBindingLayout.gameEvent]
|
|
if changeCurrent == nil {
|
|
changeCurrent = &bindingChange{
|
|
target: menu.currentBindingLayout.binding,
|
|
primary: menu.currentBindingLayout.binding.Primary,
|
|
secondary: menu.currentBindingLayout.binding.Secondary,
|
|
}
|
|
|
|
menu.changesToBeSaved[menu.currentBindingLayout.gameEvent] = changeCurrent
|
|
}
|
|
|
|
switch menu.currentBindingModifierType {
|
|
case KeyBindingTypePrimary:
|
|
changeCurrent.primary = key
|
|
case KeyBindingTypeSecondary:
|
|
changeCurrent.secondary = key
|
|
}
|
|
|
|
if changeExisting != nil {
|
|
if bindingType == KeyBindingTypePrimary {
|
|
changeExisting.primary = -1
|
|
}
|
|
|
|
if bindingType == KeyBindingTypeSecondary {
|
|
changeExisting.secondary = -1
|
|
}
|
|
}
|
|
|
|
if err := menu.setBindingLabels(
|
|
changeCurrent.primary,
|
|
changeCurrent.secondary,
|
|
menu.currentBindingLayout,
|
|
); err != nil {
|
|
return err
|
|
}
|
|
|
|
if changeExisting != nil {
|
|
for _, bindingLayout := range menu.bindingLayouts {
|
|
if bindingLayout.binding == changeExisting.target {
|
|
if err := menu.setBindingLabels(changeExisting.primary, changeExisting.secondary, bindingLayout); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) setBindingLabels(primary, secondary d2enum.Key, bl *bindingLayout) error {
|
|
noneStr := menu.keyMap.KeyToString(-1)
|
|
|
|
if primary != -1 {
|
|
if err := bl.SetPrimaryBindingTextAndColor(menu.keyMap.KeyToString(primary), d2util.Color(d2gui.ColorBrown)); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if err := bl.SetPrimaryBindingTextAndColor(noneStr, d2util.Color(d2gui.ColorGrey)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if secondary != -1 {
|
|
if err := bl.SetSecondaryBindingTextAndColor(menu.keyMap.KeyToString(secondary), d2util.Color(d2gui.ColorBrown)); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if err := bl.SetSecondaryBindingTextAndColor(noneStr, d2util.Color(d2gui.ColorGrey)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if primary == -1 && secondary == -1 {
|
|
if err := bl.primaryLabel.SetColor(d2util.Color(d2gui.ColorRed)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := bl.secondaryLabel.SetColor(d2util.Color(d2gui.ColorRed)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onCancelClicked() error {
|
|
for gameEvent := range menu.changesToBeSaved {
|
|
for _, bindingLayout := range menu.bindingLayouts {
|
|
if bindingLayout.gameEvent == gameEvent {
|
|
if err := menu.setBindingLabels(bindingLayout.binding.Primary, bindingLayout.binding.Secondary, bindingLayout); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
menu.changesToBeSaved = make(map[d2enum.GameEvent]*bindingChange)
|
|
if menu.currentBindingLayout != nil {
|
|
if err := menu.clearSelection(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := menu.Close(); err != nil {
|
|
return err
|
|
}
|
|
|
|
menu.escapeMenu.showLayout(optionsLayoutID)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) reload() error {
|
|
for _, bl := range menu.bindingLayouts {
|
|
if bl.binding != nil {
|
|
if err := menu.setBindingLabels(bl.binding.Primary, bl.binding.Secondary, bl); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) clearSelection() error {
|
|
if menu.currentBindingLayout != nil {
|
|
if err := menu.currentBindingLayout.Reset(); err != nil {
|
|
return err
|
|
}
|
|
|
|
menu.lastBindingLayout = menu.currentBindingLayout
|
|
menu.currentBindingLayout = nil
|
|
menu.currentBindingModifier = -1
|
|
menu.currentBindingModifierType = -1
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onDefaultClicked() error {
|
|
menu.keyMap.ResetToDefault()
|
|
|
|
if err := menu.reload(); err != nil {
|
|
return err
|
|
}
|
|
|
|
menu.changesToBeSaved = make(map[d2enum.GameEvent]*bindingChange)
|
|
|
|
return menu.clearSelection()
|
|
}
|
|
|
|
func (menu *KeyBindingMenu) onAcceptClicked() error {
|
|
for gameEvent, change := range menu.changesToBeSaved {
|
|
menu.keyMap.SetPrimaryBinding(gameEvent, change.primary)
|
|
menu.keyMap.SetSecondaryBinding(gameEvent, change.primary)
|
|
}
|
|
|
|
menu.changesToBeSaved = make(map[d2enum.GameEvent]*bindingChange)
|
|
|
|
return menu.clearSelection()
|
|
}
|
|
|
|
// OnKeyDown will assign the new key to the selected binding if any
|
|
func (menu *KeyBindingMenu) OnKeyDown(event d2interface.KeyEvent) error {
|
|
if menu.isAwaitingKeyDown {
|
|
key := event.Key()
|
|
|
|
if key == d2enum.KeyEscape {
|
|
if menu.currentBindingLayout != nil {
|
|
menu.lastBindingLayout = menu.currentBindingLayout
|
|
|
|
if err := menu.currentBindingLayout.Reset(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := menu.clearSelection(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else {
|
|
if err := menu.saveKeyChange(key); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
menu.isAwaitingKeyDown = false
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Advance computes the state of the elements of the menu overtime
|
|
func (menu *KeyBindingMenu) Advance(elapsed float64) error {
|
|
if menu.scrollbar != nil {
|
|
if err := menu.scrollbar.Advance(elapsed); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Render draws the different element of the menu on the target surface
|
|
func (menu *KeyBindingMenu) Render(target d2interface.Surface) error {
|
|
if menu.IsOpen() {
|
|
if err := menu.Box.Render(target); err != nil {
|
|
return err
|
|
}
|
|
|
|
if menu.scrollbar != nil {
|
|
menu.scrollbar.Render(target)
|
|
}
|
|
|
|
if menu.currentBindingLayout != nil {
|
|
x, y := menu.currentBindingLayout.wrapperLayout.Sx, menu.currentBindingLayout.wrapperLayout.Sy
|
|
w, h := menu.currentBindingLayout.wrapperLayout.GetSize()
|
|
|
|
target.PushTranslation(x, y)
|
|
target.DrawRect(w, h, d2util.Color(selectionBackgroundColor))
|
|
target.Pop()
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|