处理动画

This commit is contained in:
2026-02-09 04:07:32 +08:00
parent 85ed0946c8
commit 9822cf901d
5 changed files with 383 additions and 56 deletions

72
main.go
View File

@@ -1,8 +1,10 @@
package main package main
import ( import (
"fmt"
"log" "log"
"razer/utils" "razer/utils"
"time"
"github.com/karalabe/hid" "github.com/karalabe/hid"
"github.com/progrium/darwinkit/macos/appkit" "github.com/progrium/darwinkit/macos/appkit"
@@ -19,6 +21,76 @@ func main() {
app.SetActivationPolicy(appkit.ApplicationActivationPolicyAccessory) app.SetActivationPolicy(appkit.ApplicationActivationPolicyAccessory)
utils.SetupStatusBar(app) utils.SetupStatusBar(app)
// 【新增】在主线程提前初始化色盘单例
// 这样后面协程调用它时,它已经存在了,不会触发线程检查崩溃
_ = appkit.ColorPanel_SharedColorPanel()
// 2. 启动颜色监听协程
go func() {
var lastColor string
for {
time.Sleep(100 * time.Millisecond)
// 关键:切换回主线程来获取色盘和颜色
// 在 DarwinKit 中,通常我们可以直接在菜单点击时先初始化它,
// 或者使用 dispatch 保证安全。
var r, g, b int
var isVisible bool
var colorFound bool
// 使用 WithAutoreleasePool 并在主线程执行
objc.WithAutoreleasePool(func() {
// 注意:有些 DarwinKit 版本需要 dispatch 包
// 如果没有 dispatch 包,最简单的办法是在 main 启动前
// 先在主线程调用一次 ColorPanel_SharedColorPanel()
cp := appkit.ColorPanel_SharedColorPanel()
if cp.IsVisible() {
isVisible = true
c := cp.Color().ColorUsingColorSpace(appkit.ColorSpace_DeviceRGBColorSpace())
if !c.IsNil() {
r = int(c.RedComponent() * 255)
g = int(c.GreenComponent() * 255)
b = int(c.BlueComponent() * 255)
colorFound = true
}
}
})
if isVisible && colorFound {
curr := fmt.Sprintf("%d-%d-%d", r, g, b)
if curr != lastColor {
lastColor = curr
//fmt.Printf("颜色更新: R:%d G:%d B:%d\n", r, g, b)
//fmt.Printf("内容: R:%#v ", utils.Temp)
// 这里写 HID 设备,这里已经是 Go 协程了,不会阻塞 UI
// 1. 转换并更新你的缓存
// 这里的 BreathingState 结构体可能需要增加 R, G, B 字段
// 设置颜色
utils.Temp.TempState.SetColor([]byte{byte(r), byte(g), byte(b)})
for _, dev := range utils.Devs {
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
if utils.Temp.TempKey != key {
continue
}
switch utils.Temp.TempState.GetEffect() {
// 处理静态
case utils.KBD_EFFECT_STATIC:
dev.SetStaticColor(utils.Temp.TempState.GetColor())
// 处理呼吸
case utils.KBD_EFFECT_BREATHING:
dev.SetBreathingColor(byte(utils.Temp.TempState.GetModel()), utils.Temp.TempState.GetColor(), []byte{}, byte(utils.Temp.TempState.GetSpeed()))
}
}
utils.DeviceStateCache[utils.Temp.TempKey] = utils.Temp.TempState
//fmt.Printf("内容: R:%#v ", utils.DeviceStateCache[utils.Temp.TempKey])
// 2. 立即发送到硬件
// 这里的具体的转换逻辑需要匹配你的 HID 库
//payload := []byte{byte(r), byte(g), byte(b)}
//fmt.Printf("发送字节流到硬件: %v\n", payload)
}
}
}
}()
app.ActivateIgnoringOtherApps(true) app.ActivateIgnoringOtherApps(true)
app.Run() app.Run()

View File

@@ -14,10 +14,55 @@ var PRESET_COLORS = []struct {
{"黄色", 0xFF, 0xFF, 0x00}, {"黄色", 0xFF, 0xFF, 0x00},
{"橙色", 0xFF, 0xA5, 0x00}, {"橙色", 0xFF, 0xA5, 0x00},
{"紫色", 0x80, 0x00, 0x80}, {"紫色", 0x80, 0x00, 0x80},
{"自定义", 0x00, 0x00, 0x00},
//{"熄灭", 0x00, 0x00, 0x00}, //{"熄灭", 0x00, 0x00, 0x00},
} }
// PRESET_MULTI_COLORS 预设颜色
var PRESET_MULTI_COLORS = []struct {
Name string
Color1 []byte
Color2 []byte
}{
// 霓虹紫蓝 (非常电竞范)
{"霓虹紫蓝",
[]byte{0xFF, 0x00, 0xFF}, // 紫色 (Magenta)
[]byte{0x00, 0xFF, 0xFF}, // 青蓝色 (Cyan)
},
// 冰火 (经典红蓝对比)
{"冰火",
[]byte{0xFF, 0x00, 0x00}, // 纯红
[]byte{0x00, 0x00, 0xFF}, // 纯蓝
},
// 赛博朋克 (经典配色)
{"赛博粉黄",
[]byte{0xFF, 0x00, 0x7F}, // 玫粉色
[]byte{0xFF, 0xD7, 0x00}, // 金黄色
},
// 森林气息 (柔和过渡)
{"森翠",
[]byte{0x00, 0xFF, 0x00}, // 绿色
[]byte{0x00, 0xFF, 0x7F}, // 春绿
},
// 晚霞 (暖色调)
{"晚霞",
[]byte{0xFF, 0x45, 0x00}, // 橙红
[]byte{0xFF, 0x14, 0x93}, // 深粉
},
// 黑客帝国 (极简)
{"矩阵",
[]byte{0x00, 0xFF, 0x00}, // 翠绿
[]byte{0x00, 0x33, 0x00}, // 暗绿 (深邃感)
},
//{"熄灭", 0x00, 0x00, 0x00},
}
// 雷蛇绿 (标志性的 Razer Green) // 雷蛇绿 (标志性的 Razer Green)
//razerGreen := []byte{0x00, 0xFF, 0x00} // 或者稍微深一点的 0x44, 0xFF, 0x00 //razerGreen := []byte{0x00, 0xFF, 0x00} // 或者稍微深一点的 0x44, 0xFF, 0x00
@@ -85,16 +130,18 @@ func (rd *RazerDevice) SetOffLightsColor(color []byte) {
} }
// SetBreathingColor 设置双色呼吸 // SetBreathingColor 设置双色呼吸
func (rd *RazerDevice) SetBreathingColor() { func (rd *RazerDevice) SetBreathingColor(subMode byte, rgb1 []byte, rgb2 []byte, speed byte) {
// 1. 定义呼吸子模式 // 1. 定义呼吸子模式
subMode := byte(0x02) // 0x02 为双色切换呼吸 //subMode := byte(0x02) // 0x02 为双色切换呼吸
rgb1 := []byte{0xFF, 0x00, 0x00} // 颜色1: 红色 //rgb1 := []byte{0xFF, 0x00, 0x00} // 颜色1: 红色
rgb2 := []byte{0x00, 0x00, 0xFF} // 颜色2: 蓝色 //rgb2 := []byte{0x00, 0x00, 0xFF} // 颜色2: 蓝色
speed := byte(0x01) // 速度: 1(快) - 3(慢), 200可能过大建议先用1测试 //speed := byte(0x01) // 速度: 1(快) - 3(慢), 200可能过大建议先用1测试
//fmt.Println(subMode)
// 2. 构造参数包 (总长 8 字节) // 2. 构造参数包 (总长 8 字节)
// 结构: [SubMode, R1, G1, B1, R2, G2, B2, Speed] // 结构: [SubMode, R1, G1, B1, R2, G2, B2, Speed]
breathingParams := append([]byte{subMode}, append(rgb1, append(rgb2, speed)...)...) breathingParams := append([]byte{subMode}, append(rgb1, append(rgb2, speed)...)...)
fmt.Println(breathingParams)
// 3. 调用新版 buildArguments (内部不再强制加 0x01) // 3. 调用新版 buildArguments (内部不再强制加 0x01)
args := buildArguments(KBD_EFFECT_BREATHING, KBD_BACKLIGHT_LED, breathingParams) args := buildArguments(KBD_EFFECT_BREATHING, KBD_BACKLIGHT_LED, breathingParams)

View File

@@ -1,5 +1,11 @@
package utils package utils
import (
"fmt"
"github.com/progrium/darwinkit/macos/appkit"
)
// --- 硬件识别常量 --- // --- 硬件识别常量 ---
// RAZER_VID (Vendor ID) 是雷蛇在 USB 协会注册的厂商唯一识别码 // RAZER_VID (Vendor ID) 是雷蛇在 USB 协会注册的厂商唯一识别码
@@ -60,3 +66,32 @@ const KBD_BACKLIGHT_LED = 0x05 // 键盘背光灯光控制索引
const KBD_CMD_CLASS = 0x0F // 键盘指令分类 (Command Class) const KBD_CMD_CLASS = 0x0F // 键盘指令分类 (Command Class)
const KBD_CMD_ID = 0x02 // 键盘指令标识 (Command ID) const KBD_CMD_ID = 0x02 // 键盘指令标识 (Command ID)
const KBD_DATA_SIZE = 9 // 键盘数据包的有效负载长度 const KBD_DATA_SIZE = 9 // 键盘数据包的有效负载长度
// 全局变量,追踪当前色盘控制的设备
var (
activeDeviceKey string
colorPanel appkit.ColorPanel
)
func initColorPanel() {
// 修复unsafe.Pointer 与 nil 比较
if colorPanel.Ptr() == nil {
colorPanel = appkit.ColorPanel_SharedColorPanel()
colorPanel.SetContinuous(true)
}
}
func openColorPicker() {
// 1. 获取共享的色盘实例(推荐做法)
colorPanel := appkit.ColorPanel_SharedColorPanel()
// 2. 配置 Target/Action (可选)
// 注意:在 Go 中处理 Selector 回调比较复杂,通常需要注册一个特定的 Class
// 3. 激活应用并显示色盘
// 如果你的程序不是 GUI 模式,色盘可能会隐藏在其他窗口后面
appkit.Application_SharedApplication().ActivateIgnoringOtherApps(true)
colorPanel.MakeKeyAndOrderFront(nil)
fmt.Println("Color Picker 已经尝试打开")
}

View File

@@ -7,13 +7,105 @@ import (
"github.com/progrium/darwinkit/objc" "github.com/progrium/darwinkit/objc"
) )
var deviceStateCache = make(map[string]State) var Devs map[string]*RazerDevice = make(map[string]*RazerDevice)
type State struct { var Temp = TempData{}
Effect int
Color string type TempData struct {
TempKey string
TempState State
} }
var DeviceStateCache = make(map[string]State)
type State interface {
GetEffect() int
GetColorKey() string
GetMultiColorKey() string
GetModel() int
SetColor([]byte)
GetColor() []byte
GetColor1() []byte
GetColor2() []byte
GetSpeed() int
}
// StaticState 常亮模式
type StaticState struct {
Effect int
ColorKey string
Color []byte
}
func (s *StaticState) GetEffect() int {
return s.Effect
}
func (s *StaticState) GetModel() int {
return 0
}
func (s *StaticState) GetColorKey() string {
return s.ColorKey
}
func (s *StaticState) GetMultiColorKey() string {
return ""
}
func (s *StaticState) SetColor(color []byte) {
s.Color = color
}
func (s *StaticState) GetColor() []byte {
return s.Color
}
func (s *StaticState) GetColor1() []byte {
return []byte{}
}
func (s *StaticState) GetColor2() []byte {
return []byte{}
}
func (s *StaticState) GetSpeed() int {
return 0
}
// BreathingState 呼吸模式
type BreathingState struct {
Effect int
Model int // 单色呼吸 双色呼吸 随机颜色
Speed int // 快 中 慢
Color []byte
ColorKey string
Color1 []byte // 多色
Color2 []byte // 多色
MultiColorKey string // 多色
}
func (b *BreathingState) GetEffect() int {
return b.Effect
}
func (b *BreathingState) GetColorKey() string {
return b.ColorKey
}
func (b *BreathingState) GetModel() int {
return b.Model
}
func (b *BreathingState) GetMultiColorKey() string {
return b.MultiColorKey
}
func (b *BreathingState) SetColor(color []byte) {
b.Color = color
}
func (b *BreathingState) GetColor() []byte {
return b.Color
}
func (b *BreathingState) GetSpeed() int {
return b.Speed
}
func (b *BreathingState) GetColor1() []byte {
return b.Color1
}
func (b *BreathingState) GetColor2() []byte {
return b.Color2
}
func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.StatusItem) { func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.StatusItem) {
menu.RemoveAllItems() menu.RemoveAllItems()
@@ -25,7 +117,7 @@ func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.S
menu.AddItem(appkit.MenuItem_SeparatorItem()) menu.AddItem(appkit.MenuItem_SeparatorItem())
devices := ScanDevices() devices := ScanDevices()
Devs = devices
// 更新 ToolTip 显示当前连接数 // 更新 ToolTip 显示当前连接数
statusBarItem.Button().SetToolTip(fmt.Sprintf("雷蛇控制器 - 已连接设备: %d", len(devices))) statusBarItem.Button().SetToolTip(fmt.Sprintf("雷蛇控制器 - 已连接设备: %d", len(devices)))
@@ -35,6 +127,9 @@ func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.S
menu.AddItem(none) menu.AddItem(none)
} else { } else {
for _, dev := range devices { for _, dev := range devices {
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
stateVal := DeviceStateCache[key]
// 设备标题 (不可点击) // 设备标题 (不可点击)
devTitle := appkit.NewMenuItemWithAction("⌨️ "+dev.Name, "", func(sender objc.Object) {}) devTitle := appkit.NewMenuItemWithAction("⌨️ "+dev.Name, "", func(sender objc.Object) {})
devTitle.SetEnabled(false) devTitle.SetEnabled(false)
@@ -53,14 +148,21 @@ func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.S
colorMenu := appkit.NewMenuWithTitle("Colors") colorMenu := appkit.NewMenuWithTitle("Colors")
for _, c := range PRESET_COLORS { for _, c := range PRESET_COLORS {
colorItem := appkit.NewMenuItemWithAction(c.Name, "", func(sender objc.Object) { colorItem := appkit.NewMenuItemWithAction(c.Name, "", func(sender objc.Object) {
if c.Name == "自定义" {
DeviceStateCache[key] = &StaticState{Effect: KBD_EFFECT_STATIC, ColorKey: c.Name}
Temp = TempData{TempKey: key, TempState: DeviceStateCache[key]} // [key] = StaticState{Effect: KBD_EFFECT_STATIC, ColorKey: c.Name}
openColorPicker()
} else {
//dev.ApplyEffect(KBD_EFFECT_STATIC, c.R, c.G, c.B) //dev.ApplyEffect(KBD_EFFECT_STATIC, c.R, c.G, c.B)
dev.SetStaticColor([]byte{c.R, c.G, c.B}) dev.SetStaticColor([]byte{c.R, c.G, c.B})
// 更新状态与缓存 // 更新状态与缓存
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID) DeviceStateCache[key] = &StaticState{Effect: KBD_EFFECT_STATIC, ColorKey: c.Name, Color: []byte{c.R, c.G, c.B}}
deviceStateCache[key] = State{Effect: KBD_EFFECT_STATIC, Color: c.Name} }
UpdateMenu(menu, app, statusBarItem) UpdateMenu(menu, app, statusBarItem)
}) })
if dev.CurrentEffect == KBD_EFFECT_STATIC && dev.CurrentColor == c.Name { stateVal := DeviceStateCache[key]
if stateVal != nil && dev.CurrentEffect == KBD_EFFECT_STATIC && stateVal.GetColorKey() == c.Name {
colorItem.SetState(appkit.ControlStateValueOn) colorItem.SetState(appkit.ControlStateValueOn)
} }
colorMenu.AddItem(colorItem) colorMenu.AddItem(colorItem)
@@ -69,52 +171,123 @@ func UpdateMenu(menu appkit.Menu, app appkit.Application, statusBarItem appkit.S
menu.AddItem(staticItem) menu.AddItem(staticItem)
// --- B. 呼吸模式 --- // --- B. 呼吸模式 ---
breathItem := appkit.NewMenuItemWithAction("🌬️ 呼吸模式", "", func(sender objc.Object) { breathItem := appkit.NewMenuItemWithAction("🌬️ 呼吸模式", "", func(sender objc.Object) {})
dev.SetBreathingColor() // 默认绿色
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
deviceStateCache[key] = State{Effect: KBD_EFFECT_BREATHING, Color: ""}
UpdateMenu(menu, app, statusBarItem)
})
if dev.CurrentEffect == KBD_EFFECT_BREATHING { if dev.CurrentEffect == KBD_EFFECT_BREATHING {
breathItem.SetState(appkit.ControlStateValueOn) breathItem.SetState(appkit.ControlStateValueOn)
} }
breathRootMenu := appkit.NewMenuWithTitle("BreathingRoot")
singleItem := appkit.NewMenuItemWithAction("单色模式", "", func(sender objc.Object) {})
singleSub := appkit.NewMenuWithTitle("Single")
for _, color := range PRESET_COLORS {
item := appkit.NewMenuItemWithAction(color.Name, "", func(sender objc.Object) {
if color.Name == "自定义" {
DeviceStateCache[key] = &StaticState{Effect: KBD_EFFECT_BREATHING, ColorKey: color.Name}
Temp = TempData{TempKey: key, TempState: DeviceStateCache[key]} // [key] = StaticState{Effect: KBD_EFFECT_STATIC, ColorKey: c.Name}
openColorPicker()
} else {
if stateVal != nil {
dev.SetBreathingColor(0x01, []byte{color.R, color.G, color.B}, []byte{}, byte(stateVal.GetSpeed()))
} else {
dev.SetBreathingColor(0x01, []byte{color.R, color.G, color.B}, []byte{}, byte(1))
}
}
//dev.SetBreathing(0x01, color.R, color.G, color.B, 0, 0, 0, curState.Speed)
// 0x01: 单色 (只看第一组 RGB)
// 0x02: 双色 (看两组 RGB)
// 0x03: 随机
DeviceStateCache[key] = &BreathingState{Effect: KBD_EFFECT_BREATHING, Model: 0x01, ColorKey: color.Name, Color: []byte{color.R, color.G, color.B}}
UpdateMenu(menu, app, statusBarItem)
})
stateVal := DeviceStateCache[key]
if dev.CurrentEffect == KBD_EFFECT_BREATHING && stateVal != nil && stateVal.GetModel() == 0x01 && stateVal.GetColorKey() == color.Name {
item.SetState(appkit.ControlStateValueOn)
}
singleSub.AddItem(item)
}
stateVal = DeviceStateCache[key]
if dev.CurrentEffect == KBD_EFFECT_BREATHING && stateVal != nil && stateVal.GetModel() == 0x01 {
singleItem.SetState(appkit.ControlStateValueOn)
}
singleItem.SetSubmenu(singleSub)
breathRootMenu.AddItem(singleItem)
// B2. 双色呼吸 (红 <-> 自选)
dualItem := appkit.NewMenuItemWithAction("双色模式", "", func(sender objc.Object) {})
dualSub := appkit.NewMenuWithTitle("Dual")
for _, multiColor := range PRESET_MULTI_COLORS {
item := appkit.NewMenuItemWithAction(multiColor.Name, "", func(sender objc.Object) {
if stateVal != nil {
dev.SetBreathingColor(0x02, multiColor.Color1, multiColor.Color2, byte(stateVal.GetSpeed()))
} else {
dev.SetBreathingColor(0x02, multiColor.Color1, multiColor.Color2, byte(1))
}
DeviceStateCache[key] = &BreathingState{Effect: KBD_EFFECT_BREATHING, Model: 0x02, MultiColorKey: multiColor.Name, Color1: multiColor.Color1, Color2: multiColor.Color2}
UpdateMenu(menu, app, statusBarItem)
})
if dev.CurrentEffect == KBD_EFFECT_BREATHING && stateVal != nil && stateVal.GetModel() == 0x02 && stateVal.GetMultiColorKey() == multiColor.Name {
item.SetState(appkit.ControlStateValueOn)
}
dualSub.AddItem(item)
}
stateVal = DeviceStateCache[key]
if dev.CurrentEffect == KBD_EFFECT_BREATHING && stateVal != nil && stateVal.GetModel() == 0x02 {
dualItem.SetState(appkit.ControlStateValueOn)
}
dualItem.SetSubmenu(dualSub)
breathRootMenu.AddItem(dualItem)
// B3. 随机
randItem := appkit.NewMenuItemWithAction("随机颜色", "", func(sender objc.Object) {
DeviceStateCache[key] = &BreathingState{Effect: KBD_EFFECT_BREATHING, Model: 0x03}
UpdateMenu(menu, app, statusBarItem)
})
stateVal = DeviceStateCache[key]
if dev.CurrentEffect == KBD_EFFECT_BREATHING && stateVal != nil && stateVal.GetModel() == 0x03 {
randItem.SetState(appkit.ControlStateValueOn)
}
breathRootMenu.AddItem(randItem)
breathRootMenu.AddItem(appkit.MenuItem_SeparatorItem())
breathItem.SetSubmenu(breathRootMenu)
menu.AddItem(breathItem) menu.AddItem(breathItem)
// --- C. 波浪模式 --- //// --- C. 波浪模式 ---
waveItem := appkit.NewMenuItemWithAction("🌊 波浪模式", "", func(sender objc.Object) { //waveItem := appkit.NewMenuItemWithAction("🌊 波浪模式", "", func(sender objc.Object) {
//dev.ApplyEffect(KBD_EFFECT_WAVE, 0x01, 0x00, 0x00) // //dev.ApplyEffect(KBD_EFFECT_WAVE, 0x01, 0x00, 0x00)
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID) // key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
deviceStateCache[key] = State{Effect: KBD_EFFECT_WAVE, Color: ""} // deviceStateCache[key] = State{Effect: KBD_EFFECT_WAVE, Color: ""}
UpdateMenu(menu, app, statusBarItem) // UpdateMenu(menu, app, statusBarItem)
}) //})
if dev.CurrentEffect == KBD_EFFECT_WAVE { //if dev.CurrentEffect == KBD_EFFECT_WAVE {
waveItem.SetState(appkit.ControlStateValueOn) // waveItem.SetState(appkit.ControlStateValueOn)
} //}
menu.AddItem(waveItem) //menu.AddItem(waveItem)
// --- D. 响应模式 --- // --- D. 响应模式 ---
reactiveItem := appkit.NewMenuItemWithAction("🌊 响应模式", "", func(sender objc.Object) { //reactiveItem := appkit.NewMenuItemWithAction("🌊 响应模式", "", func(sender objc.Object) {
//dev.ApplyEffect(KBD_EFFECT_WAVE, 0x01, 0x00, 0x00) // //dev.ApplyEffect(KBD_EFFECT_WAVE, 0x01, 0x00, 0x00)
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID) // key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
deviceStateCache[key] = State{Effect: KBD_EFFECT_REACTIVE, Color: ""} // deviceStateCache[key] = State{Effect: KBD_EFFECT_REACTIVE, Color: ""}
UpdateMenu(menu, app, statusBarItem) // UpdateMenu(menu, app, statusBarItem)
}) //})
if dev.CurrentEffect == KBD_EFFECT_REACTIVE { //if dev.CurrentEffect == KBD_EFFECT_REACTIVE {
reactiveItem.SetState(appkit.ControlStateValueOn) // reactiveItem.SetState(appkit.ControlStateValueOn)
} //}
menu.AddItem(reactiveItem) //menu.AddItem(reactiveItem)
// --- E. 关灯模式 --- 关灯 // --- E. 关灯模式 --- 关灯
offLightsItem := appkit.NewMenuItemWithAction("关灯模式", "", func(sender objc.Object) { //offLightsItem := appkit.NewMenuItemWithAction("关灯模式", "", func(sender objc.Object) {
dev.SetOffLightsColor([]byte{0x00, 0x00, 0x00}) // dev.SetOffLightsColor([]byte{0x00, 0x00, 0x00})
key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID) // //key := fmt.Sprintf("%s|%s|%d", dev.Serial, dev.Product, dev.ProductID)
deviceStateCache[key] = State{Effect: KBD_EFFECT_OFFLIGHTS, Color: ""} // deviceStateCache[key] = State{Effect: KBD_EFFECT_OFFLIGHTS, Color: ""}
UpdateMenu(menu, app, statusBarItem) // UpdateMenu(menu, app, statusBarItem)
}) //})
if dev.CurrentEffect == KBD_EFFECT_OFFLIGHTS { //if dev.CurrentEffect == KBD_EFFECT_OFFLIGHTS {
offLightsItem.SetState(appkit.ControlStateValueOn) // offLightsItem.SetState(appkit.ControlStateValueOn)
} //}
menu.AddItem(offLightsItem) //menu.AddItem(offLightsItem)
//modeMenuItem.SetSubmenu(modeSubMenu) //modeMenuItem.SetSubmenu(modeSubMenu)
//menu.AddItem(modeMenuItem) //menu.AddItem(modeMenuItem)

View File

@@ -168,9 +168,9 @@ func ScanDevices() map[string]*RazerDevice {
} }
// 从缓存恢复状态 // 从缓存恢复状态
if s, found := deviceStateCache[key]; found { if s, found := DeviceStateCache[key]; found {
grouped[key].CurrentEffect = s.Effect grouped[key].CurrentEffect = s.GetEffect()
grouped[key].CurrentColor = s.Color //grouped[key].CurrentColor = s.Color
} }
} }