@@ -62,6 +62,13 @@ var gPushSelectorPopupImpl*: PushSelectorPopupImpl
6262proc getView * (self: LayoutService , id: Id ): Option [View ]
6363proc preRender * (self: LayoutService )
6464
65+ proc getViews * (self: LayoutService , T: typedesc ): seq [T] =
66+ var res = newSeq [T]()
67+ for v in self.allViews:
68+ if v of T:
69+ res.add v.T
70+ return res
71+
6572proc addViewFactory * (self: LayoutService , name: string , create: CreateView , override: bool = false ) =
6673 if not override and name in self.viewFactories:
6774 log lvlError, & " Trying to define duplicate view factory '{ name} ' "
@@ -78,6 +85,21 @@ proc getExistingView(self: LayoutService, config: JsonNode): View {.raises: [Val
7885 log lvlError, & " Missing or invalid id for { config} "
7986 return nil
8087
88+ proc getOrCreateView (self: LayoutService , config: JsonNode ): View =
89+ let kind = config[" kind" ].getStr
90+ for v in self.allViews:
91+ if v.kind == kind:
92+ return v
93+
94+ if kind in self.viewFactories:
95+ try :
96+ result = self.viewFactories [kind](config)
97+ self.allViews.add result
98+ return result
99+ except ValueError as e:
100+ log lvlError, & " Failed to create view using view factory { kind} : { e.msg} "
101+ return nil
102+
81103method createViews (self: Layout , config: JsonNode , layouts: LayoutService ) {.base , raises : [ValueError ].} =
82104 if config.kind == JNull :
83105 return
@@ -86,7 +108,10 @@ method createViews(self: Layout, config: JsonNode, layouts: LayoutService) {.bas
86108 proc resolve (id: Id ): View =
87109 return layouts.getView (id).get (nil )
88110
89- # debugf"{self.desc}.createViews: {config}"
111+ proc createView (config: JsonNode ): View =
112+ return layouts.getOrCreateView (config)
113+
114+ # debugf"{self.desc}.createViews {self}\n{config.pretty}"
90115 if config.hasKey (" children" ):
91116 let children = config[" children" ]
92117 checkJson children.kind == JArray , " 'children' must be an array"
@@ -99,8 +124,11 @@ method createViews(self: Layout, config: JsonNode, layouts: LayoutService) {.bas
99124 if i < self.children.len:
100125 if self.children[i] != nil and self.children[i] of Layout :
101126 self.children[i].Layout .createViews (c, layouts)
127+ elif self.children[i] != nil :
128+ # reuse existing child
129+ discard
102130 elif self.childTemplate != nil :
103- let newChild = self.childTemplate.copy ()
131+ let newChild = self.childTemplate.copy (). Layout
104132 self.children.add (newChild)
105133 self.activeIndex = self.activeIndex.clamp (0 , self.children.high)
106134 newChild.createViews (c, layouts)
@@ -110,11 +138,11 @@ method createViews(self: Layout, config: JsonNode, layouts: LayoutService) {.bas
110138 self.children[i] = layouts.getExistingView (c)
111139 self.activeIndex = self.activeIndex.clamp (0 , self.children.high)
112140 elif c.hasKey (" kind" ):
113- let subLayout = createLayout (c, resolve)
141+ let subLayout = createLayout (c, resolve, createView )
114142 self.children.add (subLayout)
115143 self.activeIndex = self.activeIndex.clamp (0 , self.children.high)
116144 elif self.childTemplate != nil :
117- let newChild = self.childTemplate.copy ()
145+ let newChild = self.childTemplate.copy (). Layout
118146 self.children.add (newChild)
119147 self.activeIndex = self.activeIndex.clamp (0 , self.children.high)
120148 newChild.createViews (c, layouts)
@@ -148,7 +176,10 @@ method createViews(self: CenterLayout, config: JsonNode, layouts: LayoutService)
148176 proc resolve (id: Id ): View =
149177 return layouts.getView (id).get (nil )
150178
151- # debugf"CenterLayout.createViews: {config}"
179+ proc createView (config: JsonNode ): View =
180+ return layouts.getOrCreateView (config)
181+
182+ # debugf"{self.desc}.createViews {self}\n{config.pretty}"
152183 if config.hasKey (" children" ):
153184 let children = config[" children" ]
154185 checkJson children.kind == JArray , " 'children' must be an array"
@@ -160,11 +191,11 @@ method createViews(self: CenterLayout, config: JsonNode, layouts: LayoutService)
160191 if self.children[i] != nil and self.children[i] of Layout :
161192 self.children[i].Layout .createViews (c, layouts)
162193 elif c.hasKey (" kind" ):
163- let subLayout = createLayout (c, resolve)
194+ let subLayout = createLayout (c, resolve, createView )
164195 self.children[i] = subLayout
165196 self.activeIndex = i
166197 elif self.childTemplates[i] != nil :
167- let newChild = self.childTemplates[i].copy ()
198+ let newChild = self.childTemplates[i].copy (). Layout
168199 self.children[i] = newChild
169200 self.activeIndex = i
170201 newChild.createViews (c, layouts)
@@ -193,19 +224,25 @@ proc updateLayoutTree(self: LayoutService) =
193224
194225 var layoutReferences = newSeq [(string , string )]()
195226
227+ proc createView (config: JsonNode ): View =
228+ return self.getOrCreateView (config)
229+
196230 for key, value in config.fields.pairs:
197231 if value.kind == JString :
198232 layoutReferences.add (key, value.getStr)
199233 else :
200- let view = createLayout (value.toJson)
201- if view != nil and view of Layout :
202- self.layouts[key] = view.Layout
203- else :
204- self.layouts[key] = AlternatingLayout (children: @ [view])
234+ let view = createLayout (value.toJson, createView = createView)
235+ if view != nil :
236+ let l = view.saveLayout (initHashSet [Id ]())
237+ if view of Layout :
238+ self.layouts[key] = view.Layout
239+ else :
240+ self.layouts[key] = AlternatingLayout (children: @ [view])
205241
206242 for (key, target) in layoutReferences:
207243 if target in self.layouts:
208- let l = self.layouts[target].copy ()
244+ let l = self.layouts[target].copy ().Layout
245+
209246 assert l != nil
210247 self.layouts[key] = l
211248 else :
@@ -217,7 +254,7 @@ proc updateLayoutTree(self: LayoutService) =
217254 if self.layout == nil :
218255 self.layout = AlternatingLayout (children: @ [])
219256 except Exception as e:
220- log lvlError, & " Failed to create layout from config: { e.msg} "
257+ log lvlError, & " [update-layout-tree] Failed to create layout from config: { e.msg} "
221258
222259func serviceName * (_: typedesc [LayoutService ]): string = " LayoutService"
223260
@@ -629,6 +666,14 @@ proc getVisibleViews*(self: LayoutService): seq[View] =
629666 res.add (v)
630667 return res
631668
669+ proc isViewVisible * (self: LayoutService , view: View ): bool =
670+ var res = false
671+ self.layout.forEachVisibleView proc (v: View ): bool =
672+ if v == view:
673+ res = true
674+ return true
675+ return res
676+
632677proc getNumVisibleViews * (self: LayoutService ): int {.expose (" layout" ).} =
633678 # # Returns the amount of visible views
634679 var res = 0
@@ -1104,7 +1149,7 @@ proc wrapLayout(self: LayoutService, layout: JsonNode, slot: string = "**") {.ex
11041149 let newLayout = if layout.kind == JString :
11051150 let name = layout.getStr
11061151 if name in self.layouts:
1107- self.layouts[name].copy ()
1152+ self.layouts[name].copy (). Layout
11081153 else :
11091154 log lvlError, & " Unknown layout '{ name} ' "
11101155 return
@@ -1117,7 +1162,7 @@ proc wrapLayout(self: LayoutService, layout: JsonNode, slot: string = "**") {.ex
11171162 log lvlError, & " Not a layout: { layout} "
11181163 return
11191164 except ValueError as e:
1120- log lvlError, & " Failed to create layout from config: { e.msg} "
1165+ log lvlError, & " [wrap-layout] Failed to create layout from config: { e.msg} "
11211166 return
11221167
11231168 try :
@@ -1171,6 +1216,11 @@ proc chooseLayout(self: LayoutService) {.expose("layout").} =
11711216proc logLayout * (self: LayoutService ) {.expose (" layout" ).} =
11721217 log lvlInfo, self.layout.saveLayout (initHashSet [Id ]()).pretty
11731218
1219+ proc logViews * (self: LayoutService ) {.expose (" layout" ).} =
1220+ for v in self.allViews:
1221+ if v != nil :
1222+ debugf " {v}"
1223+
11741224proc open * (self: LayoutService , path: string , slot: string = " " ) {.expose (" layout" ).} =
11751225 # # Opens the specified file. Relative paths are relative to the main workspace.
11761226 # # `path` - File path to open.
0 commit comments