Compare commits
	
		
			No commits in common. "31fa374c7f7d97eb211f1ea8e2dddc7221086a85" and "265caa30a29fc88c7b900687a29d02da4c7ef12e" have entirely different histories.
		
	
	
		
			31fa374c7f
			...
			265caa30a2
		
	
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							|  | @ -4,7 +4,7 @@ go 1.13 | |||
| 
 | ||||
| require ( | ||||
| 	gioui.org v0.0.0-20191126175243-2ca2e5462f16 | ||||
| 	git.wow.st/gmp/ble v0.0.0-20191127164604-2af636b9461a | ||||
| 	git.wow.st/gmp/ble v0.0.0-20191205134941-3bc712870db2 | ||||
| 	github.com/google/go-github/v24 v24.0.1 // indirect | ||||
| 	golang.org/x/oauth2 v0.0.0-20191122200657-5d9234df094c // indirect | ||||
| 	gopkg.in/yaml.v2 v2.2.7 | ||||
|  |  | |||
							
								
								
									
										301
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										301
									
								
								main.go
									
									
									
									
									
								
							|  | @ -9,7 +9,6 @@ import ( | |||
| 	"log" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"git.wow.st/gmp/ble" | ||||
| 
 | ||||
|  | @ -78,25 +77,9 @@ func hrDecode(x []byte) int { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| type Stopwatch struct { | ||||
| 	lasttime time.Time | ||||
| 	elapsed time.Time | ||||
| 	running bool | ||||
| 	startstopBtn *widget.Button | ||||
| 	resetBtn *widget.Button | ||||
| 	h, m, s int | ||||
| } | ||||
| 
 | ||||
| func NewStopwatch() Stopwatch { | ||||
| 	return Stopwatch{ | ||||
| 		startstopBtn: &widget.Button{}, | ||||
| 		resetBtn: &widget.Button{}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func eventloop() { | ||||
| 	w := app.NewWindow( | ||||
| 		app.Size(unit.Dp(350), unit.Dp(600)), | ||||
| 		app.Size(unit.Dp(400), unit.Dp(400)), | ||||
| 		app.Title("HRM"), | ||||
| 	) | ||||
| 	gofont.Register() | ||||
|  | @ -119,7 +102,6 @@ func eventloop() { | |||
| 	state := "starting" | ||||
| 	var hr int | ||||
| 	var periph ble.Peripheral | ||||
| 	var wide bool | ||||
| 	periphs := make([]ble.Peripheral, 0) | ||||
| 	btns := make([]*widget.Button, 0) | ||||
| 	backBtn := &widget.Button{} | ||||
|  | @ -128,101 +110,91 @@ func eventloop() { | |||
| 
 | ||||
| 	f := &layout.Flex{Axis: layout.Vertical} | ||||
| 	offpage = func() { | ||||
| 		f.Layout(gtx, | ||||
| 			f.Rigid(gtx, func() { | ||||
| 				th.Body1("Heart Rate Monitor").Layout(gtx) | ||||
| 			}), | ||||
| 			f.Rigid(gtx, func() { | ||||
| 				th.Body1("Bluetooth is Powered Off").Layout(gtx) | ||||
| 			}), | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	appname := func() { | ||||
| 		layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 		c1 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Heart Rate Monitor").Layout(gtx) | ||||
| 		}) | ||||
| 		c2 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Bluetooth is Powered Off").Layout(gtx) | ||||
| 		}) | ||||
| 		f.Layout(gtx, c1, c2) | ||||
| 	} | ||||
| 	appstate := func() { | ||||
| 		layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 	scanpage = func() { | ||||
| 		c1 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Heart Rate Monitor").Layout(gtx) | ||||
| 		}) | ||||
| 		c2 := f.Rigid(gtx, func() { | ||||
| 			th.Body1(state).Layout(gtx) | ||||
| 		}) | ||||
| 	} | ||||
| 	periphname := func() { | ||||
| 		layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 			th.Body1("COOSPO").Layout(gtx) | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	leftbar := func() { | ||||
| 		f := &layout.Flex{Axis: layout.Vertical} | ||||
| 		f.Layout(gtx, | ||||
| 			f.Rigid(gtx, appname), | ||||
| 			f.Rigid(gtx, func() { th.Body1("").Layout(gtx) }), | ||||
| 			f.Rigid(gtx, appstate), | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	scanlist := func() { | ||||
| 		lst := &layout.List{Axis: layout.Vertical} | ||||
| 		lst.Layout(gtx, len(periphs), func(i int) { | ||||
| 			gtx.Constraints.Width.Min = gtx.Constraints.Width.Max | ||||
| 			layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 				th.Button(periphs[i].Name).Layout(gtx, btns[i]) | ||||
| 		c3 := f.Rigid(gtx, func() { | ||||
| 			lst := &layout.List{Axis: layout.Vertical} | ||||
| 			lst.Layout(gtx, len(periphs), func(i int) { | ||||
| 				gtx.Constraints.Width.Min = gtx.Constraints.Width.Max | ||||
| 				layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 					th.Button(periphs[i].Name).Layout(gtx, btns[i]) | ||||
| 				}) | ||||
| 				if btns[i].Clicked(gtx) { | ||||
| 					b.StopScan() | ||||
| 					periph = periphs[i] | ||||
| 					b.Connect(periph) | ||||
| 					state = "connecting" | ||||
| 					page = connpage | ||||
| 					w.Invalidate() | ||||
| 				} | ||||
| 			}) | ||||
| 			if btns[i].Clicked(gtx) { | ||||
| 				b.StopScan() | ||||
| 				periph = periphs[i] | ||||
| 				b.Connect(periph) | ||||
| 				state = "connecting" | ||||
| 				page = connpage | ||||
| 				w.Invalidate() | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	scanpage = func() { | ||||
| 		if wide { | ||||
| 			f2 := &layout.Flex{Axis: layout.Horizontal} | ||||
| 			f2.Layout(gtx, | ||||
| 				f2.Flex(gtx, 0.2, leftbar), | ||||
| 				f2.Rigid(gtx, scanlist), | ||||
| 			) | ||||
| 		} else { | ||||
| 			f.Layout(gtx, | ||||
| 				f.Rigid(gtx, appname), | ||||
| 				f.Rigid(gtx, appstate), | ||||
| 				f.Rigid(gtx, scanlist), | ||||
| 			) | ||||
| 		} | ||||
| 		f.Layout(gtx, c1, c2, c3) | ||||
| 	} | ||||
| 
 | ||||
| 	connpage = func() { | ||||
| 		f.Layout(gtx, | ||||
| 			f.Rigid(gtx, appname), | ||||
| 			f.Rigid(gtx, appstate), | ||||
| 			f.Rigid(gtx, periphname), | ||||
| 			f.Rigid(gtx, func() { | ||||
| 				th.Button("Cancel").Layout(gtx, backBtn) | ||||
| 				if backBtn.Clicked(gtx) { | ||||
| 					ble.CancelConnection(periph) | ||||
| 					periphs = periphs[:0] | ||||
| 					Config.Autoconnect = "" | ||||
| 					saveConfig() | ||||
| 					b.Scan() | ||||
| 					state = "scanning" | ||||
| 					page = scanpage | ||||
| 				} | ||||
| 			}), | ||||
| 		) | ||||
| 		c1 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Heart Rate Monitor").Layout(gtx) | ||||
| 		}) | ||||
| 		c2 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Connecting").Layout(gtx) | ||||
| 		}) | ||||
| 		c3 := f.Rigid(gtx, func() { | ||||
| 			th.Body1(periph.Name).Layout(gtx) | ||||
| 		}) | ||||
| 		c4 := f.Rigid(gtx, func() { | ||||
| 			th.Button("Cancel").Layout(gtx, backBtn) | ||||
| 			if backBtn.Clicked(gtx) { | ||||
| 				ble.CancelConnection(periph) | ||||
| 				periphs = periphs[:0] | ||||
| 				Config.Autoconnect = "" | ||||
| 				saveConfig() | ||||
| 				b.Scan() | ||||
| 				state = "scanning" | ||||
| 				page = scanpage | ||||
| 			} | ||||
| 		}) | ||||
| 		f.Layout(gtx, c1, c2, c3, c4) | ||||
| 	} | ||||
| 
 | ||||
| 	hrcircle := func() int { | ||||
| 		var w, h1 float32 | ||||
| 		layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 	hrpage = func() { | ||||
| 		c1 := f.Rigid(gtx, func() { | ||||
| 			th.Body1("Heart Rate Monitor").Layout(gtx) | ||||
| 		}) | ||||
| 		c2 := f.Rigid(gtx, func() { | ||||
| 			th.Body1(periph.Name).Layout(gtx) | ||||
| 		}) | ||||
| 		c4 := f.Rigid(gtx, func() { | ||||
| 			layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 				th.Button("Stop").Layout(gtx, backBtn) | ||||
| 			}) | ||||
| 			if backBtn.Clicked(gtx) { | ||||
| 				ble.Disconnect(periph) | ||||
| 				periphs = periphs[:0] | ||||
| 				Config.Autoconnect = "" | ||||
| 				saveConfig() | ||||
| 				b.Scan() | ||||
| 				state = "scanning" | ||||
| 				page = scanpage | ||||
| 			} | ||||
| 		}) | ||||
| 		c3 := f.Rigid(gtx, func() { | ||||
| 			blue := color.RGBA{0x3f, 0x51, 0xb5, 255} | ||||
| 			white := color.RGBA{255, 255, 255, 255} | ||||
| 			w, h1 = float32(gtx.Constraints.Width.Max), float32(gtx.Constraints.Height.Max) | ||||
| 			w, h1 := float32(gtx.Constraints.Width.Max), float32(gtx.Constraints.Height.Max) | ||||
| 			if w < h1 { | ||||
| 				h1 = w | ||||
| 			} | ||||
|  | @ -249,135 +221,13 @@ func eventloop() { | |||
| 			}) | ||||
| 			gtx.Dimensions.Size = image.Point{int(h1), int(h1)} | ||||
| 		}) | ||||
| 		return int(h1) | ||||
| 	} | ||||
| 
 | ||||
| 	sw := NewStopwatch() | ||||
| 
 | ||||
| 	stopwatch := func() { | ||||
| 		startstoptxt := "start" | ||||
| 		if sw.running { | ||||
| 			sw.elapsed = sw.elapsed.Add(time.Since(sw.lasttime)) | ||||
| 			startstoptxt = "stop" | ||||
| 		} | ||||
| 		sw.lasttime = time.Now() | ||||
| 		f := layout.Flex{Axis: layout.Vertical} | ||||
| 		f.Layout(gtx, | ||||
| 			f.Rigid(gtx, func() { | ||||
| 				layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 					gtx.Constraints.Width.Max = 1e6 | ||||
| 					th.H4(sw.elapsed.Format("15:04:05.00")).Layout(gtx) | ||||
| 				}) | ||||
| 			}), | ||||
| 			f.Rigid(gtx, func() { | ||||
| 				f2 := layout.Flex{Axis: layout.Horizontal} | ||||
| 				gtx.Constraints.Height.Min = 100 | ||||
| 				f2.Layout(gtx, | ||||
| 					f2.Flex(gtx, 0.5, func() { | ||||
| 						layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 							th.Button(startstoptxt).Layout(gtx, sw.startstopBtn) | ||||
| 						}) | ||||
| 					}), | ||||
| 					f2.Flex(gtx, 0.5, func() { | ||||
| 						layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 							th.Button("reset").Layout(gtx, sw.resetBtn) | ||||
| 						}) | ||||
| 					}), | ||||
| 				) | ||||
| 				if sw.startstopBtn.Clicked(gtx) { | ||||
| 					if sw.running { | ||||
| 						sw.running = false | ||||
| 					} else { | ||||
| 						sw.running = true | ||||
| 					} | ||||
| 				} | ||||
| 				if sw.resetBtn.Clicked(gtx) { | ||||
| 					sw.elapsed = time.Time{} | ||||
| 					sw.running = false | ||||
| 				} | ||||
| 			}), | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	swidth := new(int) | ||||
| 	*swidth = 900 | ||||
| 	hrpage = func() { | ||||
| 		stopbtn := func() { | ||||
| 			gtx.Constraints.Width.Min = *swidth | ||||
| 			gtx.Constraints.Height.Min = 100 | ||||
| 			layout.UniformInset(unit.Dp(2)).Layout(gtx, func() { | ||||
| 				th.Button("Disconnect").Layout(gtx, backBtn) | ||||
| 			}) | ||||
| 		} | ||||
| 		if wide { | ||||
| 			f2 := &layout.Flex{Axis: layout.Horizontal} | ||||
| 			f2.Layout(gtx, | ||||
| 				f2.Flex(gtx, 0.4, func() { | ||||
| 					f3 := &layout.Flex{Axis: layout.Vertical} | ||||
| 					c1 := f3.Rigid(gtx, func() { | ||||
| 						appname() | ||||
| 						*swidth = gtx.Dimensions.Size.X | ||||
| 					}) | ||||
| 					c2 := f3.Rigid(gtx, func() { | ||||
| 						periphname() | ||||
| 						s2 := gtx.Dimensions.Size.X | ||||
| 						if s2 > *swidth { | ||||
| 							*swidth = s2 | ||||
| 						} | ||||
| 					}) | ||||
| 					c3 := f3.Rigid(gtx, stopwatch) | ||||
| 					c4 := f3.Rigid(gtx, stopbtn) | ||||
| 					f3.Layout(gtx, | ||||
| 						c1, | ||||
| 						f3.Rigid(gtx, appstate), | ||||
| 						c2, | ||||
| 						f3.Flex(gtx, 1.0, func() { th.Body1("").Layout(gtx) }), | ||||
| 						c3, | ||||
| 						c4, | ||||
| 					) | ||||
| 				}), | ||||
| 				f2.Flex(gtx, 0.6, func() { hrcircle() }), | ||||
| 			) | ||||
| 		} else { // !wide
 | ||||
| 			c1 := f.Rigid(gtx, func() { | ||||
| 				layout.Align(layout.Center).Layout(gtx, func() { | ||||
| 					gtx.Constraints.Width.Min = *swidth | ||||
| 					gtx.Constraints.Width.Max = *swidth | ||||
| 					stopwatch() | ||||
| 				}) | ||||
| 			}) | ||||
| 			c2 := f.Rigid(gtx, func() { | ||||
| 				layout.Align(layout.Center).Layout(gtx, stopbtn) | ||||
| 			}) | ||||
| 			f.Layout(gtx, | ||||
| 				f.Rigid(gtx, appname), | ||||
| 				f.Rigid(gtx, appstate), | ||||
| 				f.Rigid(gtx, periphname), | ||||
| 				f.Flex(gtx, 1.0, func() { | ||||
| 					*swidth = hrcircle() | ||||
| 				}), | ||||
| 				c1, | ||||
| 				c2, | ||||
| 			) | ||||
| 		} | ||||
| 		if backBtn.Clicked(gtx) { | ||||
| 			ble.Disconnect(periph) | ||||
| 			periphs = periphs[:0] | ||||
| 			Config.Autoconnect = "" | ||||
| 			saveConfig() | ||||
| 			b.Scan() | ||||
| 			state = "scanning" | ||||
| 			page = scanpage | ||||
| 		} | ||||
| 		f.Layout(gtx, c1, c2, c3, c4) | ||||
| 	} | ||||
| 
 | ||||
| 	page = offpage | ||||
| 
 | ||||
| 	t := time.NewTicker(time.Second/30) | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-t.C: | ||||
| 			w.Invalidate() | ||||
| 		case e := <-b.Events(): | ||||
| 			switch e := e.(type) { | ||||
| 			case ble.UpdateStateEvent: | ||||
|  | @ -447,11 +297,6 @@ func eventloop() { | |||
| 				return | ||||
| 			case system.FrameEvent: | ||||
| 				gtx.Reset(e.Config, e.Size) | ||||
| 				if e.Size.X > e.Size.Y { | ||||
| 					wide = true | ||||
| 				} else { | ||||
| 					wide = false | ||||
| 				} | ||||
| 				resetSysinset(e.Insets) | ||||
| 				sysinset.Layout(gtx, func() { | ||||
| 					margin.Layout(gtx, page) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user