bluetooth_page.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  1. package Bluetooth
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strings"
  7. //"errors"
  8. "github.com/fatih/structs"
  9. gotime "time"
  10. "github.com/veandco/go-sdl2/ttf"
  11. "github.com/cuu/gogame/color"
  12. "github.com/cuu/gogame/draw"
  13. "github.com/cuu/gogame/event"
  14. "github.com/cuu/gogame/font"
  15. "github.com/cuu/gogame/rect"
  16. "github.com/cuu/gogame/surface"
  17. "github.com/cuu/gogame/time"
  18. //"github.com/godbus/dbus"
  19. bleapi "github.com/muka/go-bluetooth/api"
  20. //"github.com/muka/go-bluetooth/bluez"
  21. // "github.com/muka/go-bluetooth/bluez/profile"
  22. "github.com/muka/go-bluetooth/bluez/profile/adapter"
  23. "github.com/muka/go-bluetooth/bluez/profile/device"
  24. "github.com/clockworkpi/LauncherGoDev/sysgo/UI"
  25. logrus "github.com/sirupsen/logrus"
  26. )
  27. func showDeviceInfo(dev *device.Device1) {
  28. if dev == nil {
  29. return
  30. }
  31. props, err := dev.GetProperties()
  32. if err != nil {
  33. fmt.Printf("%s: Failed to get properties: %s\n", dev.Path, err.Error())
  34. return
  35. }
  36. fmt.Printf("name=%s addr=%s rssi=%d\n", props.Name, props.Address, props.RSSI)
  37. }
  38. type BleForgetConfirmPage struct {
  39. UI.ConfirmPage
  40. }
  41. func NewBleForgetConfirmPage() *BleForgetConfirmPage {
  42. p := &BleForgetConfirmPage{}
  43. p.ListFont = UI.Fonts["veramono20"]
  44. p.FootMsg = [5]string{"Nav", "", "", "Cancel", "Yes"}
  45. p.ConfirmText = "Confirm Forget?"
  46. p.ConfirmPage.ConfirmText = p.ConfirmText
  47. return p
  48. }
  49. func (self *BleForgetConfirmPage) KeyDown(ev *event.Event) {
  50. if ev.Data["Key"] == UI.CurKeys["A"] || ev.Data["Key"] == UI.CurKeys["Menu"] {
  51. self.ReturnToUpLevelPage()
  52. self.Screen.Draw()
  53. self.Screen.SwapAndShow()
  54. }
  55. if ev.Data["Key"] == UI.CurKeys["B"] {
  56. self.SnapMsg("Deleting")
  57. self.Screen.Draw()
  58. self.Screen.SwapAndShow()
  59. time.BlockDelay(400)
  60. self.ReturnToUpLevelPage()
  61. self.Screen.Draw()
  62. self.Screen.SwapAndShow()
  63. }
  64. }
  65. func (self *BleForgetConfirmPage) Draw() {
  66. self.DrawBG()
  67. for _, v := range self.MyList {
  68. v.Draw()
  69. }
  70. }
  71. type BleInfoPageSelector struct {
  72. UI.InfoPageSelector
  73. }
  74. func NewBleInfoPageSelector() *BleInfoPageSelector {
  75. p := &BleInfoPageSelector{}
  76. p.Width = UI.Width
  77. p.BackgroundColor = &color.Color{131, 199, 219, 255} //SkinManager().GiveColor('Front')
  78. return p
  79. }
  80. func (self *BleInfoPageSelector) Draw() {
  81. idx := self.Parent.GetPsIndex()
  82. mylist := self.Parent.GetMyList()
  83. if idx < len(mylist) {
  84. _, y := mylist[idx].Coord()
  85. _, h := mylist[idx].Size()
  86. x := self.PosX + 2
  87. self.PosY = y + 1
  88. self.Height = h - 3
  89. canvas_ := self.Parent.GetCanvasHWND()
  90. rect_ := rect.Rect(x, self.PosY, self.Width-4, self.Height)
  91. draw.AARoundRect(canvas_, &rect_, self.BackgroundColor, 4, 0, self.BackgroundColor)
  92. }
  93. }
  94. type BleInfoPage struct {
  95. UI.Page
  96. ListFontObj *ttf.Font
  97. ListSmFontObj *ttf.Font
  98. ListSm2FontObj *ttf.Font
  99. AList map[string]interface{}
  100. Scroller *UI.ListScroller
  101. ConfirmPage1 *BleForgetConfirmPage
  102. MyDevice *device.Device1 // from NetItem-> from BluetoothPage
  103. Props *device.Device1Properties
  104. Path string
  105. }
  106. func NewBleInfoPage() *BleInfoPage {
  107. p := &BleInfoPage{}
  108. p.FootMsg = [5]string{"Nav", "Disconnect", "Forget", "Back", ""}
  109. p.ListFontObj = UI.Fonts["varela15"]
  110. p.ListSmFontObj = UI.Fonts["varela12"]
  111. p.ListSm2FontObj = UI.Fonts["varela11"]
  112. return p
  113. }
  114. func (self *BleInfoPage) Init() {
  115. if self.Screen != nil {
  116. if self.Screen.CanvasHWND != nil && self.CanvasHWND == nil {
  117. self.CanvasHWND = self.Screen.CanvasHWND
  118. }
  119. }
  120. self.PosX = self.Index * self.Screen.Width
  121. self.Width = self.Screen.Width // equals to screen width
  122. self.Height = self.Screen.Height
  123. ps := NewBleInfoPageSelector()
  124. ps.Parent = self
  125. self.Ps = ps
  126. self.PsIndex = 0
  127. self.Scroller = UI.NewListScroller()
  128. self.Scroller.Parent = self
  129. self.Scroller.PosX = 2
  130. self.Scroller.PosY = 2
  131. self.Scroller.Init()
  132. self.ConfirmPage1 = NewBleForgetConfirmPage()
  133. self.ConfirmPage1.Screen = self.Screen
  134. self.ConfirmPage1.Name = "Confirm Forget"
  135. self.ConfirmPage1.Init()
  136. }
  137. func (self *BleInfoPage) GenList() {
  138. self.AList = structs.Map(self.Props) //map[string]interface{}
  139. self.MyList = nil
  140. self.PsIndex = 0
  141. start_x := 0
  142. start_y := 0
  143. i := 0
  144. skip_arrays := []string{"ManufacturerData", "AdvertisingFlags", "ServiceData"}
  145. for k, v := range self.AList {
  146. skip2 := false
  147. for _, u := range skip_arrays {
  148. if strings.HasPrefix(k, u) {
  149. skip2 = true
  150. break
  151. }
  152. }
  153. if skip2 {
  154. continue
  155. }
  156. li := UI.NewInfoPageListItem()
  157. li.Parent = self
  158. li.PosX = start_x
  159. li.PosY = start_y + i*NetItemDefaultHeight
  160. li.Width = UI.Width
  161. li.Fonts["normal"] = self.ListFontObj
  162. if k == "UUIDs" {
  163. li.Fonts["small"] = self.ListSm2FontObj
  164. } else {
  165. li.Fonts["small"] = self.ListSmFontObj
  166. }
  167. li.Init(k)
  168. li.Flag = k
  169. sm_text := ""
  170. if k == "UUIDs" {
  171. if len(v.([]string)) > 1 {
  172. sm_text = v.([]string)[0]
  173. } else {
  174. sm_text = "<empty>"
  175. }
  176. } else {
  177. sm_text = fmt.Sprintf("%v", v)
  178. }
  179. if len(sm_text) > 20 {
  180. sm_text = sm_text[:20]
  181. }
  182. li.SetSmallText(sm_text)
  183. li.PosX = 2
  184. self.MyList = append(self.MyList, li)
  185. i += 1
  186. }
  187. }
  188. func (self *BleInfoPage) ScrollUp() {
  189. if len(self.MyList) == 0 {
  190. return
  191. }
  192. self.PsIndex -= 1
  193. if self.PsIndex < 0 {
  194. self.PsIndex = 0
  195. }
  196. cur_li := self.MyList[self.PsIndex]
  197. x, y := cur_li.Coord()
  198. if y < 0 {
  199. for i, v := range self.MyList {
  200. x, y = v.Coord()
  201. _, h := v.Size()
  202. self.MyList[i].NewCoord(x, y+h)
  203. }
  204. }
  205. }
  206. func (self *BleInfoPage) ScrollDown() {
  207. if len(self.MyList) == 0 {
  208. return
  209. }
  210. self.PsIndex += 1
  211. if self.PsIndex >= len(self.MyList) {
  212. self.PsIndex = len(self.MyList) - 1
  213. }
  214. cur_li := self.MyList[self.PsIndex]
  215. x, y := cur_li.Coord()
  216. _, h := cur_li.Size()
  217. if y+h > self.Height {
  218. for i, v := range self.MyList {
  219. x, y = v.Coord()
  220. _, h = v.Size()
  221. self.MyList[i].NewCoord(x, y-h)
  222. }
  223. }
  224. }
  225. func (self *BleInfoPage) TryToForget() {
  226. //muka Adapter1 RemoveDevice Path
  227. adapter, err := bleapi.GetAdapter(adapterID)
  228. if err == nil {
  229. self.Screen.MsgBox.SetText("Forgeting")
  230. self.Screen.MsgBox.Draw()
  231. self.Screen.SwapAndShow()
  232. err = adapter.RemoveDevice(self.MyDevice.Path())
  233. if err != nil {
  234. fmt.Println("BleInfoPage TryToForget: ", err)
  235. }
  236. time.BlockDelay(400)
  237. self.ReturnToUpLevelPage()
  238. self.Screen.Draw()
  239. self.Screen.SwapAndShow()
  240. } else {
  241. fmt.Println("BleInfoPage TryToForget GetAdapter: ", err)
  242. }
  243. }
  244. func (self *BleInfoPage) TryToDisconnect() {
  245. is_connected, _ := self.MyDevice.GetConnected()
  246. if is_connected {
  247. self.Screen.FootBar.UpdateNavText("Disconnecting")
  248. self.Screen.MsgBox.SetText("Disconnecting")
  249. self.Screen.MsgBox.Draw()
  250. self.Screen.SwapAndShow()
  251. self.MyDevice.Disconnect()
  252. time.BlockDelay(350)
  253. self.ReturnToUpLevelPage()
  254. self.Screen.Draw()
  255. self.Screen.SwapAndShow()
  256. self.Screen.FootBar.ResetNavText()
  257. }
  258. }
  259. func (self *BleInfoPage) Click() {
  260. if self.PsIndex >= len(self.MyList) {
  261. return
  262. }
  263. cur_li := self.MyList[self.PsIndex]
  264. fmt.Println(cur_li.(*UI.InfoPageListItem).Flag)
  265. }
  266. func (self *BleInfoPage) OnLoadCb() {
  267. if self.Props.Connected == true {
  268. self.FootMsg[1] = "Disconnect"
  269. } else {
  270. self.FootMsg[1] = ""
  271. }
  272. self.GenList()
  273. }
  274. func (self *BleInfoPage) KeyDown(ev *event.Event) {
  275. if ev.Data["Key"] == UI.CurKeys["A"] || ev.Data["Key"] == UI.CurKeys["Menu"] {
  276. self.ReturnToUpLevelPage()
  277. self.Screen.Draw()
  278. self.Screen.SwapAndShow()
  279. }
  280. if ev.Data["Key"] == UI.CurKeys["Up"] {
  281. self.ScrollUp()
  282. self.Screen.Draw()
  283. self.Screen.SwapAndShow()
  284. }
  285. if ev.Data["Key"] == UI.CurKeys["Down"] {
  286. self.ScrollDown()
  287. self.Screen.Draw()
  288. self.Screen.SwapAndShow()
  289. }
  290. if ev.Data["Key"] == UI.CurKeys["Enter"] {
  291. self.Click()
  292. }
  293. if ev.Data["Key"] == UI.CurKeys["X"] {
  294. self.TryToDisconnect()
  295. }
  296. if ev.Data["Key"] == UI.CurKeys["Y"] {
  297. self.TryToForget()
  298. }
  299. }
  300. func (self *BleInfoPage) Draw() {
  301. if len(self.MyList) == 0 {
  302. return
  303. }
  304. self.ClearCanvas()
  305. if len(self.MyList)*UI.DefaultInfoPageListItemHeight > self.Height {
  306. self.Ps.(*BleInfoPageSelector).Width = self.Width - 10
  307. self.Ps.(*BleInfoPageSelector).PosX = 9
  308. self.Ps.Draw()
  309. for _, v := range self.MyList {
  310. v.Draw()
  311. }
  312. self.Scroller.UpdateSize(len(self.MyList)*UI.DefaultInfoPageListItemHeight,
  313. self.PsIndex*UI.DefaultInfoPageListItemHeight)
  314. self.Scroller.Draw()
  315. } else {
  316. self.Ps.(*BleInfoPageSelector).Width = self.Width
  317. self.Ps.Draw()
  318. for _, v := range self.MyList {
  319. v.Draw()
  320. }
  321. }
  322. }
  323. type BleListMessageBox struct {
  324. UI.Label
  325. Parent UI.PageInterface
  326. }
  327. func NewBleListMessageBox() *BleListMessageBox {
  328. p := &BleListMessageBox{}
  329. p.Color = &color.Color{83, 83, 83, 255}
  330. return p
  331. }
  332. func (self *BleListMessageBox) Draw() {
  333. my_text := font.Render(self.FontObj, self.Text, true, self.Color, nil)
  334. w := surface.GetWidth(my_text)
  335. h := surface.GetHeight(my_text)
  336. pw, ph := self.Parent.Size()
  337. x := (pw - w) / 2
  338. y := (ph - h) / 2
  339. padding := 10
  340. rect_ := rect.Rect(x-padding, y-padding, w+padding*2, h+padding*2)
  341. draw.Rect(self.CanvasHWND, &color.Color{255, 255, 255, 255}, &rect_, 0)
  342. draw.Rect(self.CanvasHWND, &color.Color{0, 0, 0, 255}, &rect_, 1)
  343. rect2_ := rect.Rect(x, y, w, h)
  344. surface.Blit(self.CanvasHWND, my_text, &rect2_, nil)
  345. my_text.Free()
  346. }
  347. type BluetoothPage struct {
  348. UI.Page
  349. Devices []*device.Device1
  350. BlePassword string
  351. Connecting bool
  352. Scanning bool
  353. ListFontObj *ttf.Font
  354. Scroller *UI.ListScroller
  355. InfoPage *BleInfoPage
  356. PrevState int
  357. ShowingMessageBox bool
  358. MsgBox *BleListMessageBox
  359. ConnectTry int
  360. //BlockCb ??
  361. LastStatusMsg string
  362. ADAPTER_DEV string // == adapterID
  363. Offline bool
  364. Leader *BluetoothPlugin
  365. }
  366. func NewBluetoothPage() *BluetoothPage {
  367. p := &BluetoothPage{}
  368. p.PageIconMargin = 20
  369. p.SelectedIconTopOffset = 20
  370. p.EasingDur = 10
  371. p.Align = UI.ALIGN["SLeft"]
  372. p.ADAPTER_DEV = adapterID
  373. p.FootMsg = [5]string{"Nav", "Scan", "Info", "Back", "TryConnect"}
  374. p.ListFontObj = UI.Fonts["notosanscjk15"]
  375. return p
  376. }
  377. func (self *BluetoothPage) ShowBox(msg string) {
  378. self.MsgBox.Text = msg
  379. self.ShowingMessageBox = true
  380. self.Screen.Draw()
  381. self.MsgBox.Draw()
  382. self.Screen.SwapAndShow()
  383. }
  384. func (self *BluetoothPage) HideBox() {
  385. self.Draw()
  386. self.ShowingMessageBox = false
  387. self.Screen.SwapAndShow()
  388. }
  389. func (self *BluetoothPage) Init() {
  390. self.PosX = self.Index * self.Screen.Width
  391. self.Width = self.Screen.Width
  392. self.Height = self.Screen.Height
  393. self.CanvasHWND = self.Screen.CanvasHWND
  394. ps := NewBleInfoPageSelector()
  395. ps.Parent = self
  396. ps.Width = UI.Width - 12
  397. self.Ps = ps
  398. self.PsIndex = 0
  399. msgbox := NewBleListMessageBox()
  400. msgbox.CanvasHWND = self.CanvasHWND
  401. msgbox.Init(" ", UI.Fonts["veramono12"], nil)
  402. msgbox.Parent = self
  403. self.MsgBox = msgbox
  404. self.Scroller = UI.NewListScroller()
  405. self.Scroller.Parent = self
  406. self.Scroller.PosX = 2
  407. self.Scroller.PosY = 2
  408. self.Scroller.Init()
  409. self.InfoPage = NewBleInfoPage()
  410. self.InfoPage.Screen = self.Screen
  411. self.InfoPage.Name = "BluetoothInfo"
  412. self.InfoPage.Init()
  413. }
  414. func (self *BluetoothPage) AbortedAndReturnToUpLevel() {
  415. self.HideBox()
  416. self.Screen.FootBar.ResetNavText()
  417. self.ReturnToUpLevelPage()
  418. self.Screen.Draw()
  419. self.Screen.SwapAndShow()
  420. }
  421. func (self *BluetoothPage) TryConnect() {
  422. if self.PsIndex >= len(self.MyList) {
  423. return
  424. }
  425. cur_li := self.MyList[self.PsIndex]
  426. if cur_li.(*NetItem).Props.Connected {
  427. return
  428. }
  429. self.Screen.FootBar.UpdateNavText("Connecting")
  430. self.ShowBox("Connecting")
  431. self.Leader.PairPage.DevObj = cur_li.(*NetItem).Device
  432. err := cur_li.(*NetItem).Device.Pair()
  433. if err != nil {
  434. fmt.Println(err)
  435. err_msg := ""
  436. s := err.Error()
  437. err_msg = "Pair error"
  438. if strings.Contains(s, "ConnectionAttemptFailed") {
  439. err_msg = "Page Timeout"
  440. }
  441. if strings.Contains(s, "NoReply") {
  442. err_msg = "NoReply,Cancelling"
  443. dev1 := cur_li.(*NetItem).Device
  444. dev1.CancelPairing()
  445. }
  446. if strings.Contains(s, "Exists") {
  447. err_msg = "Already Exists"
  448. adapter, err := bleapi.GetAdapter(adapterID)
  449. if err == nil {
  450. err = adapter.RemoveDevice(cur_li.(*NetItem).Device.Path())
  451. if err != nil {
  452. fmt.Println(err)
  453. }
  454. } else {
  455. fmt.Println(err)
  456. }
  457. }
  458. self.Leader.PairPage.PairErrorCb(err_msg)
  459. self.Leader.PairPage.DevObj = nil
  460. } else {
  461. self.Leader.PairPage.PairOKCb()
  462. dev1 := cur_li.(*NetItem).Device
  463. err = dev1.SetTrusted(true)
  464. if err != nil {
  465. fmt.Println(err)
  466. }
  467. cur_li.(*NetItem).Device.Connect()
  468. }
  469. self.HideBox()
  470. self.Screen.FootBar.ResetNavText()
  471. }
  472. //GetDevices returns a list of bluetooth discovered Devices
  473. func (self *BluetoothPage) GetDevices() ([]*device.Device1, error) {
  474. adapter, err := bleapi.GetAdapter(adapterID)
  475. if err != nil {
  476. return nil, err
  477. }
  478. list, err := adapter.GetDevices()
  479. return list, err
  480. }
  481. func (self *BluetoothPage) RefreshDevices() {
  482. // sync the cached devices
  483. self.Devices = self.Devices[:0]
  484. devices, err := self.GetDevices()
  485. if err != nil {
  486. panic(err)
  487. os.Exit(1)
  488. }
  489. self.Devices = devices
  490. }
  491. func (self *BluetoothPage) GenNetworkList() {
  492. self.MyList = nil
  493. start_x := 0
  494. start_y := 0
  495. for i, v := range self.Devices { // v == bleapi.Device
  496. props, err := v.GetProperties()
  497. if err != nil {
  498. log.Printf("%s: Failed to get properties: %s\n", v.Path, err.Error())
  499. return
  500. }
  501. ni := NewNetItem()
  502. ni.Parent = self
  503. ni.PosX = start_x
  504. ni.PosY = start_y + i*NetItemDefaultHeight
  505. ni.Width = UI.Width
  506. ni.FontObj = self.ListFontObj
  507. ni.Props = props
  508. ni.Parent = self
  509. ni.Device = v
  510. if props.Name != "" {
  511. ni.Init(props.Name)
  512. } else {
  513. ni.Init(props.Address)
  514. }
  515. self.MyList = append(self.MyList, ni)
  516. }
  517. self.PsIndex = 0
  518. }
  519. func (self *BluetoothPage) Rescan() {
  520. if self.Scanning == true {
  521. self.ShowBox("Bluetooth scanning")
  522. self.Screen.FootBar.UpdateNavText("Scanning")
  523. }
  524. a, err := adapter.GetAdapter(adapterID)
  525. if err != nil {
  526. fmt.Println(err)
  527. return
  528. }
  529. discovery, cancel, err := bleapi.Discover(a, nil)
  530. if err != nil {
  531. fmt.Println(err)
  532. }
  533. defer cancel()
  534. wait := make(chan error)
  535. self.Scanning = true
  536. self.ShowBox("Bluetooth scanning")
  537. self.Screen.FootBar.UpdateNavText("Scanning")
  538. go func() {
  539. for dev := range discovery {
  540. if dev == nil {
  541. return
  542. }
  543. wait <- nil
  544. }
  545. }()
  546. go func() {
  547. sleep := 5
  548. gotime.Sleep(gotime.Duration(sleep) * gotime.Second)
  549. logrus.Debugf("Discovery timeout exceeded (%ds)", sleep)
  550. wait <- nil
  551. }()
  552. err = <-wait
  553. if err != nil {
  554. fmt.Println(err)
  555. }
  556. self.Scanning = false
  557. self.HideBox()
  558. self.Screen.FootBar.ResetNavText()
  559. }
  560. func (self *BluetoothPage) OnLoadCb() {
  561. self.Offline = false
  562. if self.Screen.TitleBar.InAirPlaneMode == false {
  563. out := UI.System("hcitool dev | grep hci0 |cut -f3")
  564. if len(out) < 17 {
  565. self.Offline = true
  566. fmt.Println("Bluetooth OnLoadCb ,can not find hci0 alive,try to reboot")
  567. } else {
  568. self.Rescan()
  569. self.RefreshDevices()
  570. self.GenNetworkList()
  571. }
  572. } else {
  573. self.Offline = true
  574. }
  575. }
  576. func (self *BluetoothPage) ScrollUp() {
  577. if len(self.MyList) == 0 {
  578. return
  579. }
  580. self.PsIndex -= 1
  581. if self.PsIndex < 0 {
  582. self.PsIndex = 0
  583. }
  584. cur_ni := self.MyList[self.PsIndex] //*NetItem
  585. if cur_ni.(*NetItem).PosY < 0 {
  586. for i := 0; i < len(self.MyList); i++ {
  587. self.MyList[i].(*NetItem).PosY += self.MyList[i].(*NetItem).Height
  588. }
  589. }
  590. }
  591. func (self *BluetoothPage) ScrollDown() {
  592. if len(self.MyList) == 0 {
  593. return
  594. }
  595. self.PsIndex += 1
  596. if self.PsIndex >= len(self.MyList) {
  597. self.PsIndex = len(self.MyList) - 1
  598. }
  599. cur_ni := self.MyList[self.PsIndex]
  600. if cur_ni.(*NetItem).PosY+cur_ni.(*NetItem).Height > self.Height {
  601. for i := 0; i < len(self.MyList); i++ {
  602. self.MyList[i].(*NetItem).PosY -= self.MyList[i].(*NetItem).Height
  603. }
  604. }
  605. }
  606. func (self *BluetoothPage) KeyDown(ev *event.Event) {
  607. if ev.Data["Key"] == UI.CurKeys["A"] || ev.Data["Key"] == UI.CurKeys["Menu"] {
  608. if self.Offline == true {
  609. self.AbortedAndReturnToUpLevel()
  610. return
  611. }
  612. a, nil := bleapi.GetAdapter(adapterID)
  613. err := a.StopDiscovery()
  614. if err != nil {
  615. fmt.Println(err)
  616. }
  617. self.HideBox()
  618. self.ReturnToUpLevelPage()
  619. self.Screen.Draw()
  620. self.Screen.SwapAndShow()
  621. self.Screen.FootBar.ResetNavText()
  622. }
  623. if ev.Data["Key"] == UI.CurKeys["Up"] {
  624. self.ScrollUp()
  625. self.Screen.Draw()
  626. self.Screen.SwapAndShow()
  627. }
  628. if ev.Data["Key"] == UI.CurKeys["Down"] {
  629. self.ScrollDown()
  630. self.Screen.Draw()
  631. self.Screen.SwapAndShow()
  632. }
  633. if ev.Data["Key"] == UI.CurKeys["X"] {
  634. if self.Offline == false {
  635. self.Rescan()
  636. }
  637. }
  638. if ev.Data["Key"] == UI.CurKeys["Y"] {
  639. if len(self.MyList) == 0 {
  640. return
  641. }
  642. if self.Offline == true {
  643. return
  644. }
  645. self.InfoPage.Props = self.MyList[self.PsIndex].(*NetItem).Props
  646. self.InfoPage.Path = self.MyList[self.PsIndex].(*NetItem).Path
  647. self.InfoPage.MyDevice = self.MyList[self.PsIndex].(*NetItem).Device
  648. self.Screen.PushPage(self.InfoPage)
  649. self.Screen.Draw()
  650. self.Screen.SwapAndShow()
  651. }
  652. if ev.Data["Key"] == UI.CurKeys["B"] {
  653. if self.Offline == false {
  654. self.TryConnect()
  655. }
  656. }
  657. }
  658. func (self *BluetoothPage) Draw() {
  659. self.ClearCanvas()
  660. if len(self.MyList) == 0 {
  661. return
  662. }
  663. if len(self.MyList)*NetItemDefaultHeight > self.Height {
  664. self.Ps.(*BleInfoPageSelector).Width = self.Width - 11
  665. self.Ps.Draw()
  666. for _, v := range self.MyList {
  667. v.Draw()
  668. }
  669. self.Scroller.UpdateSize(len(self.MyList)*NetItemDefaultHeight, self.PsIndex*NetItemDefaultHeight)
  670. self.Scroller.Draw()
  671. } else {
  672. self.Ps.(*BleInfoPageSelector).Width = self.Width
  673. self.Ps.Draw()
  674. for _, v := range self.MyList {
  675. v.Draw()
  676. }
  677. }
  678. }