Progress
This commit is contained in:
		
							parent
							
								
									867a3d0fcd
								
							
						
					
					
						commit
						99cf3b3843
					
				
					 7 changed files with 119 additions and 29 deletions
				
			
		|  | @ -8,6 +8,7 @@ require ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
|  | 	gio.tools/icons v0.0.0-20240708021058-44790e75e701 // indirect | ||||||
| 	gioui.org/shader v1.0.8 // indirect | 	gioui.org/shader v1.0.8 // indirect | ||||||
| 	github.com/go-text/typesetting v0.2.1 // indirect | 	github.com/go-text/typesetting v0.2.1 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.14 // indirect | 	github.com/mattn/go-colorable v0.1.14 // indirect | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY= | eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY= | ||||||
| eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA= | eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA= | ||||||
|  | gio.tools/icons v0.0.0-20240708021058-44790e75e701 h1:uLF9lM2XdkhjH2bhWdTEONz9y4nuweF377ice94rNVQ= | ||||||
|  | gio.tools/icons v0.0.0-20240708021058-44790e75e701/go.mod h1:yHac4ydqWEu6ZgRJ2c2izqy285pdJRHZczqlbhDZIi0= | ||||||
| gioui.org v0.8.0 h1:QV5p5JvsmSmGiIXVYOKn6d9YDliTfjtLlVf5J+BZ9Pg= | gioui.org v0.8.0 h1:QV5p5JvsmSmGiIXVYOKn6d9YDliTfjtLlVf5J+BZ9Pg= | ||||||
| gioui.org v0.8.0/go.mod h1:vEMmpxMOd/iwJhXvGVIzWEbxMWhnMQ9aByOGQdlQ8rc= | gioui.org v0.8.0/go.mod h1:vEMmpxMOd/iwJhXvGVIzWEbxMWhnMQ9aByOGQdlQ8rc= | ||||||
| gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= | gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= | ||||||
|  |  | ||||||
|  | @ -1,20 +1,19 @@ | ||||||
| package ui | package ui | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"icdb/internal/ui/styling" | ||||||
|  | 	"icdb/pkg/layouts" | ||||||
| 	t_ui "icdb/pkg/types/ui" | 	t_ui "icdb/pkg/types/ui" | ||||||
| 
 | 
 | ||||||
| 	"gioui.org/app" | 	"gioui.org/app" | ||||||
| 	"gioui.org/layout" |  | ||||||
| 	"gioui.org/op" | 	"gioui.org/op" | ||||||
| 	"gioui.org/unit" |  | ||||||
| 	"gioui.org/widget/material" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var currentView t_ui.UIView = t_ui.UIViewMain | var currentView t_ui.UIView = t_ui.UIViewMain | ||||||
| 
 | 
 | ||||||
| // run takes a window as parameter and runs the UI on it. | // run takes a window as parameter and runs the UI on it. | ||||||
| func run(window *app.Window) error { | func run(window *app.Window) error { | ||||||
| 	theme := material.NewTheme() | 	theme := styling.GlobalTheme() | ||||||
| 	var ops op.Ops | 	var ops op.Ops | ||||||
| 	for { | 	for { | ||||||
| 		switch e := window.Event().(type) { | 		switch e := window.Event().(type) { | ||||||
|  | @ -23,21 +22,10 @@ func run(window *app.Window) error { | ||||||
| 		case app.FrameEvent: | 		case app.FrameEvent: | ||||||
| 			gtx := app.NewContext(&ops, e) | 			gtx := app.NewContext(&ops, e) | ||||||
| 
 | 
 | ||||||
| 			margins := layout.Inset{ | 			layouts.SplitRatio{Ratio: -0.8}.Layout(gtx, | ||||||
| 				Top:    unit.Dp(10), | 				renderSidebar(theme), | ||||||
| 				Bottom: unit.Dp(10), | 				renderView(theme), | ||||||
| 				Left:   unit.Dp(10), | 			) | ||||||
| 				Right:  unit.Dp(10), |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			margins.Layout(gtx, func(gtx layout.Context) layout.Dimensions { |  | ||||||
| 				return layout.Flex{ |  | ||||||
| 					Axis: layout.Horizontal, |  | ||||||
| 				}.Layout(gtx, |  | ||||||
| 					layout.Rigid(renderSidebar(theme)), |  | ||||||
| 					layout.Flexed(1, renderView(theme)), |  | ||||||
| 				) |  | ||||||
| 			}) |  | ||||||
| 
 | 
 | ||||||
| 			e.Frame(gtx.Ops) | 			e.Frame(gtx.Ops) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -2,9 +2,13 @@ package ui | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	t_ui "icdb/pkg/types/ui" | 	t_ui "icdb/pkg/types/ui" | ||||||
|  | 	"image" | ||||||
| 	"image/color" | 	"image/color" | ||||||
| 
 | 
 | ||||||
|  | 	"gio.tools/icons" | ||||||
| 	"gioui.org/layout" | 	"gioui.org/layout" | ||||||
|  | 	"gioui.org/op/clip" | ||||||
|  | 	"gioui.org/op/paint" | ||||||
| 	"gioui.org/unit" | 	"gioui.org/unit" | ||||||
| 	"gioui.org/widget" | 	"gioui.org/widget" | ||||||
| 	"gioui.org/widget/material" | 	"gioui.org/widget/material" | ||||||
|  | @ -17,27 +21,63 @@ var ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var sidebarWidth = unit.Dp(200) | var sidebarWidth = unit.Dp(200) | ||||||
| var sidebarBackground = color.NRGBA{R: 240, G: 240, B: 240, A: 255} | var sidebarBackground = color.NRGBA{R: 225, G: 225, B: 225, A: 255} | ||||||
| 
 | 
 | ||||||
| // renderSidebar creates the sidebar UI. | // renderSidebar creates the sidebar UI. | ||||||
|  | // It renders a colored background and then adds the navigation buttons. | ||||||
| func renderSidebar(th *material.Theme) layout.Widget { | func renderSidebar(th *material.Theme) layout.Widget { | ||||||
| 	return func(gtx layout.Context) layout.Dimensions { | 	return func(gtx layout.Context) layout.Dimensions { | ||||||
| 		return layout.Flex{ | 		return layout.Stack{Alignment: layout.Center}.Layout(gtx, | ||||||
| 			Axis: layout.Vertical, | 			// Expanded: Draw the background to fill the entire left pane. | ||||||
| 		}.Layout(gtx, | 			layout.Expanded(func(gtx layout.Context) layout.Dimensions { | ||||||
| 			layout.Rigid(renderNavButton(gtx, th, "Main", &mainButton, t_ui.UIViewMain)), | 				// Use a rectangle that covers the full widget area. | ||||||
| 			layout.Rigid(renderNavButton(gtx, th, "Parts", &partsButton, t_ui.UIViewParts)), | 				rect := clip.Rect{ | ||||||
| 			layout.Rigid(renderNavButton(gtx, th, "Settings", &settingsButton, t_ui.UIViewSettings)), | 					Min: image.Pt(0, 0), | ||||||
|  | 					Max: gtx.Constraints.Max, | ||||||
|  | 				} | ||||||
|  | 				paint.FillShape(gtx.Ops, sidebarBackground, rect.Op()) | ||||||
|  | 				return layout.Dimensions{Size: gtx.Constraints.Max} | ||||||
|  | 			}), | ||||||
|  | 			// Stacked: Lay out the navigation buttons. | ||||||
|  | 			layout.Stacked(func(gtx layout.Context) layout.Dimensions { | ||||||
|  | 				// Internal padding for the sidebar. | ||||||
|  | 				in := layout.Inset{ | ||||||
|  | 					Top:    unit.Dp(5), | ||||||
|  | 					Left:   unit.Dp(5), | ||||||
|  | 					Right:  unit.Dp(5), | ||||||
|  | 					Bottom: unit.Dp(5), | ||||||
|  | 				} | ||||||
|  | 				return in.Layout(gtx, func(gtx layout.Context) layout.Dimensions { | ||||||
|  | 					return layout.Flex{ | ||||||
|  | 						Axis:      layout.Vertical, | ||||||
|  | 						Alignment: layout.Start, | ||||||
|  | 					}.Layout(gtx, | ||||||
|  | 						layout.Rigid(renderNavButton(th, icons.ActionHome, "Main", &mainButton, t_ui.UIViewMain)), | ||||||
|  | 						layout.Rigid(renderNavButton(th, icons.ActionBuild, "Parts", &partsButton, t_ui.UIViewParts)), | ||||||
|  | 						layout.Rigid(renderNavButton(th, icons.ActionSettings, "Settings", &settingsButton, t_ui.UIViewSettings)), | ||||||
|  | 					) | ||||||
|  | 				}) | ||||||
|  | 			}), | ||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // renderNavButton creates a navigation button | // renderNavButton creates a navigation icon button. | ||||||
| func renderNavButton(gtx layout.Context, th *material.Theme, label string, btn *widget.Clickable, target t_ui.UIView) layout.Widget { | func renderNavButton(th *material.Theme, icon *widget.Icon, label string, btn *widget.Clickable, target t_ui.UIView) layout.Widget { | ||||||
| 	return func(gtx layout.Context) layout.Dimensions { | 	return func(gtx layout.Context) layout.Dimensions { | ||||||
| 		if btn.Clicked(gtx) { | 		if btn.Clicked(gtx) { | ||||||
| 			currentView = target | 			currentView = target | ||||||
| 		} | 		} | ||||||
| 		return material.Button(th, btn, label).Layout(gtx) | 
 | ||||||
|  | 		// Padding for each button, to add spacing between them. | ||||||
|  | 		in := layout.Inset{ | ||||||
|  | 			Bottom: unit.Dp(8), | ||||||
|  | 			Left:   unit.Dp(4), | ||||||
|  | 			Right:  unit.Dp(4), | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return in.Layout(gtx, func(gtx layout.Context) layout.Dimensions { | ||||||
|  | 			return material.IconButton(th, btn, icon, label).Layout(gtx) | ||||||
|  | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								src/internal/ui/styling/theme.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/internal/ui/styling/theme.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | package styling | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"image/color" | ||||||
|  | 
 | ||||||
|  | 	"gioui.org/widget/material" | ||||||
|  | 	"golang.org/x/image/colornames" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GlobalTheme returns an instance of the global application theme. | ||||||
|  | func GlobalTheme() *material.Theme { | ||||||
|  | 	theme := material.NewTheme() | ||||||
|  | 	theme.Palette.Bg = color.NRGBA(colornames.White) | ||||||
|  | 	theme.Palette.Fg = color.NRGBA(colornames.Black) | ||||||
|  | 	theme.ContrastBg = color.NRGBA(colornames.Orange) | ||||||
|  | 	return theme | ||||||
|  | } | ||||||
|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"gioui.org/app" | 	"gioui.org/app" | ||||||
|  | 	"gioui.org/unit" | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -11,6 +12,9 @@ import ( | ||||||
| func Init() { | func Init() { | ||||||
| 	go func() { | 	go func() { | ||||||
| 		window := new(app.Window) | 		window := new(app.Window) | ||||||
|  | 		window.Option(app.Title("ICDB")) | ||||||
|  | 		window.Option(app.MinSize(unit.Dp(700), unit.Dp(400))) | ||||||
|  | 		window.Option(app.Size(unit.Dp(800), unit.Dp(600))) | ||||||
| 		err := run(window) | 		err := run(window) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal().Err(err).Msg("UI loop exited with error") | 			log.Fatal().Err(err).Msg("UI loop exited with error") | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								src/pkg/layouts/split.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/pkg/layouts/split.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | package layouts | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"image" | ||||||
|  | 
 | ||||||
|  | 	"gioui.org/layout" | ||||||
|  | 	"gioui.org/op" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type SplitRatio struct { | ||||||
|  | 	// Ratio keeps the current layout. | ||||||
|  | 	// 0 is center, -1 completely to the left, 1 completely to the right. | ||||||
|  | 	Ratio float32 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s SplitRatio) Layout(gtx layout.Context, left, right layout.Widget) layout.Dimensions { | ||||||
|  | 	proportion := (s.Ratio + 1) / 2 | ||||||
|  | 	leftsize := int(proportion * float32(gtx.Constraints.Max.X)) | ||||||
|  | 
 | ||||||
|  | 	rightoffset := leftsize | ||||||
|  | 	rightsize := gtx.Constraints.Max.X - rightoffset | ||||||
|  | 
 | ||||||
|  | 	{ | ||||||
|  | 		gtx := gtx | ||||||
|  | 		gtx.Constraints = layout.Exact(image.Pt(leftsize, gtx.Constraints.Max.Y)) | ||||||
|  | 		left(gtx) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	{ | ||||||
|  | 		trans := op.Offset(image.Pt(rightoffset, 0)).Push(gtx.Ops) | ||||||
|  | 		gtx := gtx | ||||||
|  | 		gtx.Constraints = layout.Exact(image.Pt(rightsize, gtx.Constraints.Max.Y)) | ||||||
|  | 		right(gtx) | ||||||
|  | 		trans.Pop() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return layout.Dimensions{Size: gtx.Constraints.Max} | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 zervo
						zervo