aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ui/tunnelsview.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/ui/tunnelsview.go b/ui/tunnelsview.go
new file mode 100644
index 00000000..c1bba252
--- /dev/null
+++ b/ui/tunnelsview.go
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package ui
+
+import (
+ "sort"
+
+ "github.com/lxn/walk"
+ "golang.zx2c4.com/wireguard/windows/service"
+)
+
+// TunnelModel is a struct to store the currently known tunnels to the GUI, suitable as a model for a walk.TableView.
+type TunnelModel struct {
+ walk.TableModelBase
+ walk.SorterBase
+
+ // TODO: also store the state to display a small icon as the first column
+ tunnels []service.Tunnel
+}
+
+func (t *TunnelModel) RowCount() int {
+ return len(t.tunnels)
+}
+
+func (t *TunnelModel) Value(row, col int) interface{} {
+ tunnel := t.tunnels[row]
+
+ switch col {
+ case 0:
+ return tunnel.Name
+
+ default:
+ panic("unreachable col")
+ }
+}
+
+func (t *TunnelModel) Sort(col int, order walk.SortOrder) error {
+ sort.SliceStable(t.tunnels, func(i, j int) bool {
+ a, b := t.tunnels[i], t.tunnels[j]
+
+ c := func(res bool) bool {
+ if order == walk.SortAscending {
+ return res
+ }
+ return !res
+ }
+
+ // don't match col, always sort by name
+ return c(a.Name < b.Name)
+ })
+
+ return t.SorterBase.Sort(col, order)
+}
+
+type TunnelsView struct {
+ *walk.TableView
+
+ model *TunnelModel
+}
+
+func NewTunnelsView(parent walk.Container) (*TunnelsView, error) {
+ tv, err := walk.NewTableView(parent)
+ if err != nil {
+ return nil, err
+ }
+
+ model := &TunnelModel{}
+
+ tv.SetModel(model)
+ tv.SetAlternatingRowBGColor(walk.RGB(239, 239, 239))
+ tv.SetLastColumnStretched(true)
+ tv.SetHeaderHidden(true)
+ tv.Columns().Add(walk.NewTableViewColumn())
+
+ return &TunnelsView{
+ TableView: tv,
+ model: model,
+ }, nil
+}
+
+func (tv *TunnelsView) CurrentTunnel() *service.Tunnel {
+ idx := tv.CurrentIndex()
+ if idx == -1 {
+ return nil
+ }
+
+ return &tv.model.tunnels[idx]
+}
+
+func (tv *TunnelsView) SetTunnelState(tunnel *service.Tunnel, state service.TunnelState) {
+ idx := -1
+ for i, _ := range tv.model.tunnels {
+ if tv.model.tunnels[i].Name == tunnel.Name {
+ idx = i
+ break
+ }
+ }
+
+ if idx != -1 {
+ // we don't do anything with the state right now
+ return
+ }
+
+ // New tunnel, add it
+ tv.model.tunnels = append(tv.model.tunnels, *tunnel)
+ tv.model.Sort(0, walk.SortAscending)
+ for i, _ := range tv.model.tunnels {
+ if tv.model.tunnels[i].Name == tunnel.Name {
+ idx = i
+ }
+ }
+
+ tv.model.PublishRowsInserted(idx, idx)
+}