Added listener table view and modal for starting listeners.
This commit is contained in:
@@ -1,26 +1,26 @@
|
|||||||
[Window][Sessions [Table View]]
|
[Window][Sessions [Table View]]
|
||||||
Pos=10,43
|
Pos=10,43
|
||||||
Size=1477,281
|
Size=1477,357
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,0
|
DockId=0x00000003,0
|
||||||
|
|
||||||
[Window][Listeners]
|
[Window][Listeners]
|
||||||
Pos=10,326
|
Pos=10,402
|
||||||
Size=944,663
|
Size=1888,587
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
[Window][Eventlog]
|
[Window][Eventlog]
|
||||||
Pos=1489,43
|
Pos=1489,43
|
||||||
Size=409,281
|
Size=409,357
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
[Window][Dear ImGui Demo]
|
[Window][Dear ImGui Demo]
|
||||||
Pos=1489,43
|
Pos=10,402
|
||||||
Size=409,281
|
Size=1888,587
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,1
|
DockId=0x00000007,1
|
||||||
|
|
||||||
[Window][Dockspace]
|
[Window][Dockspace]
|
||||||
Pos=0,0
|
Pos=0,0
|
||||||
@@ -45,14 +45,14 @@ Size=400,400
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][[G1H2I3J5] diana@WORKSTATION-04]
|
[Window][[G1H2I3J5] diana@WORKSTATION-04]
|
||||||
Pos=10,326
|
Pos=10,402
|
||||||
Size=944,663
|
Size=1888,587
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,1
|
DockId=0x00000007,1
|
||||||
|
|
||||||
[Window][[DEADBEEF] alice@DESKTOP-01]
|
[Window][[DEADBEEF] alice@DESKTOP-01]
|
||||||
Pos=10,326
|
Pos=10,402
|
||||||
Size=1888,663
|
Size=1888,587
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,1
|
DockId=0x00000007,1
|
||||||
|
|
||||||
@@ -77,6 +77,43 @@ Pos=119,266
|
|||||||
Size=1717,576
|
Size=1717,576
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Same title as another window##1]
|
||||||
|
Pos=274,278
|
||||||
|
Size=754,103
|
||||||
|
Collapsed=1
|
||||||
|
|
||||||
|
[Window][Same title as another window##2]
|
||||||
|
Pos=100,200
|
||||||
|
Size=754,103
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000009,1
|
||||||
|
|
||||||
|
[Window][###AnimatedTitle]
|
||||||
|
Pos=100,200
|
||||||
|
Size=754,103
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000009,0
|
||||||
|
|
||||||
|
[Window][Delete?]
|
||||||
|
Pos=696,412
|
||||||
|
Size=516,175
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Stacked 1]
|
||||||
|
Pos=588,335
|
||||||
|
Size=669,457
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][StartListener]
|
||||||
|
Pos=753,446
|
||||||
|
Size=76,76
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Start Listener]
|
||||||
|
Pos=704,387
|
||||||
|
Size=500,225
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
[Table][0x32886A44,8]
|
[Table][0x32886A44,8]
|
||||||
Column 0 Weight=0.6465
|
Column 0 Weight=0.6465
|
||||||
Column 1 Weight=0.9697
|
Column 1 Weight=0.9697
|
||||||
@@ -91,14 +128,21 @@ Column 7 Weight=1.4546
|
|||||||
RefScale=27
|
RefScale=27
|
||||||
Column 0 Sort=0v
|
Column 0 Sort=0v
|
||||||
|
|
||||||
|
[Table][0x064A67CC,4]
|
||||||
|
Column 0 Weight=1.2081
|
||||||
|
Column 1 Weight=1.3299
|
||||||
|
Column 2 Weight=0.4873
|
||||||
|
Column 3 Weight=0.9746
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
|
DockNode ID=0x00000009 Pos=100,200 Size=754,103 Selected=0x64D005CF
|
||||||
DockSpace ID=0x85940918 Window=0x260A4489 Pos=10,43 Size=1888,946 Split=Y
|
DockSpace ID=0x85940918 Window=0x260A4489 Pos=10,43 Size=1888,946 Split=Y
|
||||||
DockNode ID=0x00000001 Parent=0x85940918 SizeRef=1024,281 Split=X
|
DockNode ID=0x00000001 Parent=0x85940918 SizeRef=1024,357 Split=X
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=613,159 CentralNode=1 Selected=0x61E02D75
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=613,159 CentralNode=1 Selected=0x61E02D75
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=409,159 Selected=0x5E5F7166
|
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=409,159 Selected=0x0FA43D88
|
||||||
DockNode ID=0x00000002 Parent=0x85940918 SizeRef=1024,663 Split=X Selected=0x8D780333
|
DockNode ID=0x00000002 Parent=0x85940918 SizeRef=1024,587 Split=X Selected=0x8D780333
|
||||||
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=944,663 Split=X Selected=0x8D780333
|
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=944,663 Split=X Selected=0x8D780333
|
||||||
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=944,663 Selected=0x8D780333
|
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=944,663 Selected=0x6BE22050
|
||||||
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=942,663 Selected=0x4AD091E6
|
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=942,663 Selected=0x4AD091E6
|
||||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=942,663 Selected=0x65D642C0
|
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=942,663 Selected=0x65D642C0
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import times
|
import strutils
|
||||||
import imguin/[cimgui, glfw_opengl, simple]
|
import imguin/[cimgui, glfw_opengl, simple]
|
||||||
import ../utils/appImGui
|
import ../utils/appImGui
|
||||||
import ../../common/[types]
|
import ../../common/[types, utils]
|
||||||
|
import ./modals/startListener
|
||||||
|
|
||||||
type
|
type
|
||||||
ListenersTableComponent = ref object of RootObj
|
ListenersTableComponent = ref object of RootObj
|
||||||
title: string
|
title: string
|
||||||
listeners: seq[Listener]
|
listeners: seq[Listener]
|
||||||
|
selection: ptr ImGuiSelectionBasicStorage
|
||||||
|
startListenerModal: ListenerModalComponent
|
||||||
|
|
||||||
let exampleListeners: seq[Listener] = @[
|
let exampleListeners: seq[Listener] = @[
|
||||||
Listener(
|
Listener(
|
||||||
@@ -27,10 +30,93 @@ proc ListenersTable*(title: string): ListenersTableComponent =
|
|||||||
result = new ListenersTableComponent
|
result = new ListenersTableComponent
|
||||||
result.title = title
|
result.title = title
|
||||||
result.listeners = exampleListeners
|
result.listeners = exampleListeners
|
||||||
|
result.selection = ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage()
|
||||||
|
result.startListenerModal = ListenerModal()
|
||||||
|
|
||||||
proc draw*(component: ListenersTableComponent, showComponent: ptr bool) =
|
proc draw*(component: ListenersTableComponent, showComponent: ptr bool) =
|
||||||
igSetNextWindowSize(vec2(800, 600), ImGuiCond_Once.int32)
|
|
||||||
igBegin(component.title, showComponent, 0)
|
igBegin(component.title, showComponent, 0)
|
||||||
defer: igEnd()
|
defer: igEnd()
|
||||||
|
|
||||||
igText("Listeners")
|
let textSpacing = igGetStyle().ItemSpacing.x
|
||||||
|
|
||||||
|
# Listener creation modal
|
||||||
|
if igButton("Start Listener", vec2(0.0f, 0.0f)):
|
||||||
|
igOpenPopup_str("Start Listener", ImGui_PopupFlags_None.int32)
|
||||||
|
|
||||||
|
let listener = component.startListenerModal.draw()
|
||||||
|
if listener != nil:
|
||||||
|
# TODO: Start listener
|
||||||
|
component.listeners.add(listener)
|
||||||
|
|
||||||
|
#[
|
||||||
|
Listener table
|
||||||
|
]#
|
||||||
|
let tableFlags = (
|
||||||
|
ImGuiTableFlags_Resizable.int32 or
|
||||||
|
ImGuiTableFlags_Reorderable.int32 or
|
||||||
|
ImGuiTableFlags_Hideable.int32 or
|
||||||
|
ImGuiTableFlags_HighlightHoveredColumn.int32 or
|
||||||
|
ImGuiTableFlags_RowBg.int32 or
|
||||||
|
ImGuiTableFlags_BordersV.int32 or
|
||||||
|
ImGuiTableFlags_BordersH.int32 or
|
||||||
|
ImGuiTableFlags_ScrollY.int32 or
|
||||||
|
ImGuiTableFlags_ScrollX.int32 or
|
||||||
|
ImGuiTableFlags_NoBordersInBodyUntilResize.int32 or
|
||||||
|
ImGui_TableFlags_SizingStretchProp.int32
|
||||||
|
)
|
||||||
|
|
||||||
|
let cols: int32 = 4
|
||||||
|
if igBeginTable("Listeners", cols, tableFlags, vec2(0.0f, 0.0f), 0.0f):
|
||||||
|
|
||||||
|
igTableSetupColumn("ListenerID", ImGuiTableColumnFlags_NoReorder.int32 or ImGuiTableColumnFlags_NoHide.int32, 0.0f, 0)
|
||||||
|
igTableSetupColumn("Address", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||||
|
igTableSetupColumn("Port", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||||
|
igTableSetupColumn("Protocol", ImGuiTableColumnFlags_None.int32, 0.0f, 0)
|
||||||
|
|
||||||
|
igTableSetupScrollFreeze(0, 1)
|
||||||
|
igTableHeadersRow()
|
||||||
|
|
||||||
|
var multiSelectIO = igBeginMultiSelect(ImGuiMultiSelectFlags_ClearOnEscape.int32 or ImGuiMultiSelectFlags_BoxSelect1d.int32, component.selection[].Size, int32(component.listeners.len()))
|
||||||
|
ImGuiSelectionBasicStorage_ApplyRequests(component.selection, multiSelectIO)
|
||||||
|
|
||||||
|
for row in 0 ..< component.listeners.len():
|
||||||
|
|
||||||
|
igTableNextRow(ImGuiTableRowFlags_None.int32, 0.0f)
|
||||||
|
let listener = component.listeners[row]
|
||||||
|
|
||||||
|
if igTableSetColumnIndex(0):
|
||||||
|
# Enable multi-select functionality
|
||||||
|
igSetNextItemSelectionUserData(row)
|
||||||
|
var isSelected = ImGuiSelectionBasicStorage_Contains(component.selection, cast[ImGuiID](row))
|
||||||
|
discard igSelectable_Bool(listener.listenerId, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32, vec2(0.0f, 0.0f))
|
||||||
|
|
||||||
|
if igTableSetColumnIndex(1):
|
||||||
|
igText(listener.address)
|
||||||
|
if igTableSetColumnIndex(2):
|
||||||
|
igText($listener.port)
|
||||||
|
if igTableSetColumnIndex(3):
|
||||||
|
igText($listener.protocol)
|
||||||
|
|
||||||
|
# Handle right-click context menu
|
||||||
|
# Right-clicking the table header to hide/show columns or reset the layout is only possible when no sessions are selected
|
||||||
|
if component.selection[].Size > 0 and igBeginPopupContextWindow("TableContextMenu", ImGui_PopupFlags_MouseButtonRight.int32):
|
||||||
|
|
||||||
|
if igMenuItem("Stop", nil, false, true):
|
||||||
|
# Update agents table with only non-selected ones
|
||||||
|
var newListeners: seq[Listener] = @[]
|
||||||
|
for i in 0 ..< component.listeners.len():
|
||||||
|
if not ImGuiSelectionBasicStorage_Contains(component.selection, cast[ImGuiID](i)):
|
||||||
|
newListeners.add(component.listeners[i])
|
||||||
|
|
||||||
|
# TODO: Stop/kill listener
|
||||||
|
|
||||||
|
component.listeners = newListeners
|
||||||
|
ImGuiSelectionBasicStorage_Clear(component.selection)
|
||||||
|
igCloseCurrentPopup()
|
||||||
|
|
||||||
|
igEndPopup()
|
||||||
|
|
||||||
|
multiSelectIO = igEndMultiSelect()
|
||||||
|
ImGuiSelectionBasicStorage_ApplyRequests(component.selection, multiSelectIO)
|
||||||
|
|
||||||
|
igEndTable()
|
||||||
0
src/client/views/modals/buildAgent.nim
Normal file
0
src/client/views/modals/buildAgent.nim
Normal file
97
src/client/views/modals/startListener.nim
Normal file
97
src/client/views/modals/startListener.nim
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import strutils
|
||||||
|
import imguin/[cimgui, glfw_opengl, simple]
|
||||||
|
import ../../utils/appImGui
|
||||||
|
import ../../../common/[types, utils]
|
||||||
|
|
||||||
|
const DEFAULT_PORT = 8080'u16
|
||||||
|
|
||||||
|
type
|
||||||
|
ListenerModalComponent* = ref object of RootObj
|
||||||
|
address: array[256, char]
|
||||||
|
port: uint16
|
||||||
|
protocol: int32
|
||||||
|
protocols: seq[string]
|
||||||
|
|
||||||
|
proc getProtocols(): seq[string] =
|
||||||
|
for p in Protocol.low .. Protocol.high:
|
||||||
|
result.add($p)
|
||||||
|
|
||||||
|
proc ListenerModal*(): ListenerModalComponent =
|
||||||
|
result = new ListenerModalComponent
|
||||||
|
zeroMem(addr result.address[0], 256)
|
||||||
|
result.port = DEFAULT_PORT
|
||||||
|
result.protocol = 0
|
||||||
|
result.protocols = getProtocols()
|
||||||
|
|
||||||
|
proc resetModalValues(component: ListenerModalComponent) =
|
||||||
|
zeroMem(addr component.address[0], 256)
|
||||||
|
component.port = DEFAULT_PORT
|
||||||
|
component.protocol = 0
|
||||||
|
|
||||||
|
proc draw*(component: ListenerModalComponent): Listener =
|
||||||
|
let textSpacing = igGetStyle().ItemSpacing.x
|
||||||
|
|
||||||
|
# Center modal
|
||||||
|
let vp = igGetMainViewport()
|
||||||
|
var center: ImVec2
|
||||||
|
ImGuiViewport_GetCenter(addr center, vp)
|
||||||
|
igSetNextWindowPos(center, ImGuiCond_Appearing.int32, vec2(0.5f, 0.5f))
|
||||||
|
|
||||||
|
let modalWidth = max(500.0f, vp.Size.x * 0.25)
|
||||||
|
igSetNextWindowSize(vec2(modalWidth, 0.0f), ImGuiCond_Always.int32)
|
||||||
|
|
||||||
|
var show = true
|
||||||
|
let windowFlags = ImGuiWindowFlags_None.int32 # or ImGuiWindowFlags_NoMove.int32
|
||||||
|
if igBeginPopupModal("Start Listener", addr show, windowFlags):
|
||||||
|
defer: igEndPopup()
|
||||||
|
|
||||||
|
var availableSize: ImVec2
|
||||||
|
igGetContentRegionAvail(addr availableSize)
|
||||||
|
|
||||||
|
# Listener address
|
||||||
|
igText("Host: ")
|
||||||
|
igSameLine(0.0f, textSpacing)
|
||||||
|
igGetContentRegionAvail(addr availableSize)
|
||||||
|
igSetNextItemWidth(availableSize.x)
|
||||||
|
igInputTextWithHint("##InputAddress", "127.0.0.1", addr component.address[0], 256, ImGui_InputTextFlags_CharsNoBlank.int32, nil, nil)
|
||||||
|
|
||||||
|
# Listener port
|
||||||
|
let step: uint16 = 1
|
||||||
|
igText("Port: ")
|
||||||
|
igSameLine(0.0f, textSpacing)
|
||||||
|
igSetNextItemWidth(availableSize.x)
|
||||||
|
igInputScalar("##InputPort", ImGuiDataType_U16.int32, addr component.port, addr step, nil, "%hu", ImGui_InputTextFlags_CharsDecimal.int32)
|
||||||
|
|
||||||
|
# Listener protocol dropdown selection
|
||||||
|
igText("Protocol: ")
|
||||||
|
igSameLine(0.0f, textSpacing)
|
||||||
|
igSetNextItemWidth(availableSize.x)
|
||||||
|
igCombo_Str("##InputProtocol", addr component.protocol, (component.protocols.join("\0") & "\0").cstring , component.protocols.len().int32)
|
||||||
|
|
||||||
|
igGetContentRegionAvail(addr availableSize)
|
||||||
|
|
||||||
|
igDummy(vec2(0.0f, 10.0f))
|
||||||
|
igSeparator()
|
||||||
|
igDummy(vec2(0.0f, 10.0f))
|
||||||
|
|
||||||
|
# Only enabled the start button when valid values have been entered
|
||||||
|
igBeginDisabled(($(addr component.address[0]) == "") or (component.port <= 0))
|
||||||
|
|
||||||
|
if igButton("Start", vec2(availableSize.x * 0.5 - textSpacing * 0.5, 0.0f)):
|
||||||
|
|
||||||
|
result = Listener(
|
||||||
|
listenerId: generateUUID(),
|
||||||
|
address: $(addr component.address[0]),
|
||||||
|
port: int(component.port),
|
||||||
|
protocol: cast[Protocol](component.protocol)
|
||||||
|
)
|
||||||
|
component.resetModalValues()
|
||||||
|
igCloseCurrentPopup()
|
||||||
|
|
||||||
|
igEndDisabled()
|
||||||
|
igSameLine(0.0f, textSpacing)
|
||||||
|
|
||||||
|
if igButton("Close", vec2(availableSize.x * 0.5 - textSpacing * 0.5, 0.0f)):
|
||||||
|
|
||||||
|
component.resetModalValues()
|
||||||
|
igCloseCurrentPopup()
|
||||||
@@ -107,8 +107,6 @@ proc interact(component: SessionsTableComponent) =
|
|||||||
|
|
||||||
|
|
||||||
proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
proc draw*(component: SessionsTableComponent, showComponent: ptr bool) =
|
||||||
igSetNextWindowSize(vec2(800, 600), ImGuiCond_Once.int32)
|
|
||||||
|
|
||||||
igBegin(component.title, showComponent, 0)
|
igBegin(component.title, showComponent, 0)
|
||||||
defer: igEnd()
|
defer: igEnd()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user