diff --git a/cmd/gosdn-tview/app/app.go b/cmd/gosdn-tview/app/app.go index e65af13c574abbc01551afc45e88323d4b36c2da..28a8bc9ed84aedf5c962f88d9035c4cbb2b43792 100644 --- a/cmd/gosdn-tview/app/app.go +++ b/cmd/gosdn-tview/app/app.go @@ -6,11 +6,13 @@ type view interface { GetContent() tview.Primitive } +//App is a GUI-Application bases on tview type App struct { app *tview.Application pages *tview.Pages } +//NewApp creates a new GUI-Application func NewApp() *App { a := &App{ app: tview.NewApplication(), @@ -18,33 +20,40 @@ func NewApp() *App { return a } +//SetRoot sets the root of the GUI-Application func (a *App) SetRoot(v view) { a.pages = v.GetContent().(*tview.Pages) a.app.SetRoot(a.pages, true) } +//SwitchPage switches to the given (as string) tview page func (a *App) SwitchPage(s string) { if a.pages.HasPage(s) { a.pages.SwitchToPage(s) } } +//AddPage adds a new view as page that can be switched to func (a *App) AddPage(name string, p view) { a.pages.AddPage(name, p.GetContent(), true, false) } +//Run starts the GUI-Application func (a *App) Run() error { return a.app.Run() } +//Stop stops the GUI-Application func (a *App) Stop() { a.app.Stop() } +//Draw calls tview.Draw() func (a *App) Draw() { a.app.Draw() } +//SetFocus sets the focus on new tview.Primitive func (a *App) SetFocus(v tview.Primitive) { a.app.SetFocus(v) } diff --git a/cmd/gosdn-tview/grpc/commands.go b/cmd/gosdn-tview/grpc/commands.go index 6eabf835326dcf0a08663bec21632fbc09384744..e46853d29f3d10e3c23ec737dd225852c11842e8 100644 --- a/cmd/gosdn-tview/grpc/commands.go +++ b/cmd/gosdn-tview/grpc/commands.go @@ -8,13 +8,6 @@ import ( "time" ) -type commandType int - -const ( - GoSDN commandType = iota - Database -) - const ( defaultName = "gosdn-cli" ) @@ -22,10 +15,10 @@ const ( type command struct { Name string Description string - //CommandType commandType - Function func(conn *grpc.ClientConn) string + Function func(conn *grpc.ClientConn) string } +//CommandList contains the specific goSDN gRPC calls var CommandList = []command{ {"hello", "test connection to goSDN controller", goSDNSayHello}, {"shutdown", "request goSDN controller to shutdown", goSDNShutdown}, @@ -35,6 +28,7 @@ var CommandList = []command{ {"tapigetlink", "get list of links", TAPIGetLink}, } +//Connect creates a new connection to the gRPC server func Connect() (*grpc.ClientConn, error) { address := "localhost:55055" return grpc.Dial(address, grpc.WithInsecure(), grpc.WithTimeout(5*time.Second), grpc.WithBlock()) diff --git a/cmd/gosdn-tview/views/addPNDView.go b/cmd/gosdn-tview/views/addPNDView.go index 7fdf756110624cfc519a5be7596981c828e8a28c..14fcd475d3b8eb9d13ea4524dc17a00c081cf67f 100644 --- a/cmd/gosdn-tview/views/addPNDView.go +++ b/cmd/gosdn-tview/views/addPNDView.go @@ -5,10 +5,12 @@ import ( "github.com/rivo/tview" ) +//AddPNDView is an application view to create a new goSDN PND type AddPNDView struct { addPNDView *tview.Form } +//NewAddPNDView creates a new AddPNDView func NewAddPNDView(app *app.App) *AddPNDView { pndv := &AddPNDView{ addPNDView: tview.NewForm(), @@ -34,6 +36,7 @@ func NewAddPNDView(app *app.App) *AddPNDView { return pndv } +//GetContent returns the tview.Primitive belonging to the AddPNDView func (pndv *AddPNDView) GetContent() tview.Primitive { return pndv.addPNDView } diff --git a/cmd/gosdn-tview/views/commandsListView.go b/cmd/gosdn-tview/views/commandsListView.go index 2ab3f9452f436669a7f75c536a9775f68b29590a..8c7488daafacd1ca3942056f91bc8c1cfefb42b2 100644 --- a/cmd/gosdn-tview/views/commandsListView.go +++ b/cmd/gosdn-tview/views/commandsListView.go @@ -7,10 +7,12 @@ import ( "google.golang.org/grpc" ) +//CommandListView is an application view to display all the goSDN commands type CommandListView struct { commandsList *tview.List } +//NewCommandListView creates a new CommandListView func NewCommandListView() *CommandListView { cv := &CommandListView{ commandsList: tview.NewList(), @@ -22,10 +24,14 @@ func NewCommandListView() *CommandListView { return cv } +//GetContent returns the tview.Primitive belonging to the CommandListView func (cv *CommandListView) GetContent() tview.Primitive { return cv.commandsList } +//GetCommands gets all goSDN commands from a command list and creates new +//tview.List items for each one of them. The specific gRPC functions are added +//as tview.Selected() function func (cv *CommandListView) GetCommands(app *app.App, rv *ResultAndInputView, conn *grpc.ClientConn) { //TODO: create own command in grpc -> commands diff --git a/cmd/gosdn-tview/views/datbaseStatusView.go b/cmd/gosdn-tview/views/datbaseStatusView.go index 2e9a268666a054fab89b5ddef1ed28dc6c65385f..6c217b416779ecb7ea7232ee0b310298a27d8ce2 100644 --- a/cmd/gosdn-tview/views/datbaseStatusView.go +++ b/cmd/gosdn-tview/views/datbaseStatusView.go @@ -6,10 +6,13 @@ import ( "time" ) +//DatabaseStatusView is an application view to display the current status of +//the database (e.g. connected, disconnected,...) type DatabaseStatusView struct { databaseStatusView *tview.TextView } +//NewDatabaseStatusView creates a new DatabaseStatusView func NewDatabaseStatusView(app *app.App) *DatabaseStatusView { dv := &DatabaseStatusView{ databaseStatusView: tview.NewTextView(), @@ -21,21 +24,25 @@ func NewDatabaseStatusView(app *app.App) *DatabaseStatusView { SetBorder(true). SetTitle("Database") + // run the periodical refresh in a new go routine go databaseTicker(dv) return dv } +//GetContent returns the tview.Primitive belonging to the DatabaseStatusView func (dv *DatabaseStatusView) GetContent() tview.Primitive { return dv.databaseStatusView } +//SetContent sets new string content for the DatabaseStatusView func (dv *DatabaseStatusView) SetContent(s string) { dv.databaseStatusView.Clear() dv.databaseStatusView.SetText(s) } func databaseTicker(dv *DatabaseStatusView) { + //TODO see gRPCStatusView! ticker := time.NewTicker(5 * time.Second) for t := range ticker.C { dv.SetContent(t.String()) diff --git a/cmd/gosdn-tview/views/footerView.go b/cmd/gosdn-tview/views/footerView.go index f998d7ba5e973a3233f0b00c1c2ff880697e531c..09ff7d7dd0771036655b5291f2a5c278dc6ce72a 100644 --- a/cmd/gosdn-tview/views/footerView.go +++ b/cmd/gosdn-tview/views/footerView.go @@ -6,12 +6,15 @@ import ( "google.golang.org/grpc" ) +//FooterView is an application view to display the footer of the application it +//consists multiple other application views type FooterView struct { footerView *tview.Flex databaseStatusView *DatabaseStatusView gRPCStatusView *GRPCStatusView } +//NewFooterView creates a new FooterView func NewFooterView(app *app.App, conn *grpc.ClientConn) *FooterView { fw := &FooterView{ @@ -30,6 +33,7 @@ func NewFooterView(app *app.App, conn *grpc.ClientConn) *FooterView { return fw } +//GetContent returns the tview.Primitive belonging to the FooterView func (fw *FooterView) GetContent() tview.Primitive { return fw.footerView } diff --git a/cmd/gosdn-tview/views/gRPCStatusView.go b/cmd/gosdn-tview/views/gRPCStatusView.go index 3e522db7f18237e8533970fdf29f98233b6aff0e..ef024aecc34363bc3a8edf67ff51ac574dab4e65 100644 --- a/cmd/gosdn-tview/views/gRPCStatusView.go +++ b/cmd/gosdn-tview/views/gRPCStatusView.go @@ -7,10 +7,13 @@ import ( "time" ) +//GRPCStatusView is an application view to display the current status of +//the gRPC server (e.g. connected, unavailable,...) type GRPCStatusView struct { gRPCStatusView *tview.TextView } +//NewGRPCStatusView creates a new GRPCStatusView func NewGRPCStatusView(app *app.App, conn *grpc.ClientConn) *GRPCStatusView { sv := &GRPCStatusView{ gRPCStatusView: tview.NewTextView(), @@ -23,8 +26,8 @@ func NewGRPCStatusView(app *app.App, conn *grpc.ClientConn) *GRPCStatusView { SetBorder(true). SetTitle("gRPC") - //TODO: maybe there is another way to do this. - // pretty ugly atm, since it re-draws every 5 seconds... + //TODO: gRPCs Health Check looks like a way better alternative here! + //--> no app.Draw() required anymore sv.gRPCStatusView.SetChangedFunc(func() { app.Draw() }) @@ -34,10 +37,12 @@ func NewGRPCStatusView(app *app.App, conn *grpc.ClientConn) *GRPCStatusView { return sv } +//GetContent returns the tview.Primitive belonging to the gRPCStatusView func (sv *GRPCStatusView) GetContent() tview.Primitive { return sv.gRPCStatusView } +//SetContent sets new string content for the gRPCStatusView func (sv *GRPCStatusView) SetContent(s string) { sv.gRPCStatusView.Clear() sv.gRPCStatusView.SetText(s) diff --git a/cmd/gosdn-tview/views/headerView.go b/cmd/gosdn-tview/views/headerView.go index 67034bb6492f01563321a8cd777323367689685b..7c68ef2b74442cd30e21ba7fc71bdcbc0a4203b0 100644 --- a/cmd/gosdn-tview/views/headerView.go +++ b/cmd/gosdn-tview/views/headerView.go @@ -9,11 +9,13 @@ var goSDNAscii = ` ____ ____ _ _ _ _ _ \__ |\___/____/|____/|_| \_| |_| |_|\___/ \___|_| |_|___/\___|_| |_|\__,_|_|\___| |____/ \__,_|_| |_| |_| |_|___/\__\__,_|\__,_|\__| |___/ ` +//HeaderView is an application view to display the header of the application type HeaderView struct { headerFlex *tview.Flex titleView *tview.TextView } +//NewHeaderView creates a new HeaderView func NewHeaderView() *HeaderView { //TODO: change to uses FlexBox if there is more to display in the header hv := &HeaderView{ @@ -27,6 +29,7 @@ func NewHeaderView() *HeaderView { return hv } +//GetContent returns the tview.Primitive belonging to the HeaderView func (hv *HeaderView) GetContent() tview.Primitive { return hv.titleView } diff --git a/cmd/gosdn-tview/views/mainView.go b/cmd/gosdn-tview/views/mainView.go index 6c95c811cc408ee1f5e5fa480ba33e573d044555..ab9f4479ef4a765752e3d434b88843fbf95bd7ec 100644 --- a/cmd/gosdn-tview/views/mainView.go +++ b/cmd/gosdn-tview/views/mainView.go @@ -6,6 +6,9 @@ import ( "google.golang.org/grpc" ) +//MainView is an application view to display the main content of the application. +//It is the entry point for the application and contains all necessary views for +//for that purpose type MainView struct { pages *tview.Pages mainGrid *tview.Grid @@ -15,6 +18,7 @@ type MainView struct { footerView *FooterView } +//NewMainView creates a new MainView func NewMainView(app *app.App, conn *grpc.ClientConn) *MainView { mv := &MainView{ pages: tview.NewPages(), @@ -40,6 +44,7 @@ func NewMainView(app *app.App, conn *grpc.ClientConn) *MainView { return mv } +//GetContent returns the tview.Primitive belonging to the MainView func (mv *MainView) GetContent() tview.Primitive { return mv.pages } diff --git a/cmd/gosdn-tview/views/resultAndInputView.go b/cmd/gosdn-tview/views/resultAndInputView.go index 99ae89654349c6347281c34c7b2149a6e4c64463..ec74e2e4929b3e7e7bc902f7eb219b97bed5f4ef 100644 --- a/cmd/gosdn-tview/views/resultAndInputView.go +++ b/cmd/gosdn-tview/views/resultAndInputView.go @@ -5,12 +5,15 @@ import ( "github.com/rivo/tview" ) +//ResultAndInputView is an application view to display different other views. +//Depending on the required features the views are changed. type ResultAndInputView struct { pages *tview.Pages resultView *tview.TextView pndInputView *AddPNDView } +//NewResultAndInputView creates a new ResultAndInputView func NewResultAndInputView(app *app.App) *ResultAndInputView { rv := &ResultAndInputView{ pages: tview.NewPages(), @@ -31,14 +34,18 @@ func NewResultAndInputView(app *app.App) *ResultAndInputView { return rv } +//GetContent returns the tview.Primitive belonging to the ResultAndInputView func (rv *ResultAndInputView) GetContent() tview.Primitive { return rv.pages } +//ChangeContentView changes the current content (tview.Primitive) that is visible +//inside this view func (rv *ResultAndInputView) ChangeContentView(s string) { rv.pages.SwitchToPage(s) } +//SetContent sets new string content for the ResultAndInputView func (rv *ResultAndInputView) SetContent(s string) { rv.resultView.Clear() rv.resultView.SetText(s)