Skip to content

Commit a0cd8e0

Browse files
committed
snippet editor
1 parent f436b70 commit a0cd8e0

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

Examples/Content/HelloSnippet.umap

7.85 KB
Binary file not shown.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
const UMG = require('UMG')
2+
const _ = require('lodash')
3+
const fontSize = 12
4+
5+
function GetPC() {
6+
return PlayerController.C(GWorld.GetAllActorsOfClass(PlayerController).OutActors[0])
7+
}
8+
9+
function editor() {
10+
let source = `
11+
let actor = new StaticMeshActor(GWorld)
12+
actor.StaticMeshComponent.SetMobility('Movable')
13+
actor.StaticMeshComponent.SetStaticMesh(StaticMesh.Load('/Engine/BasicShapes/Cube'))
14+
15+
function tick() {
16+
if (!actor.IsValid()) return
17+
let rad = $time
18+
let r = 50
19+
let p = {Y:Math.cos(rad) * r, Z:Math.sin(rad) * r}
20+
actor.SetActorLocation(p)
21+
process.nextTick(tick)
22+
}
23+
24+
tick()
25+
`
26+
let actors = GWorld.GetAllActorsOfClass(Actor).OutActors
27+
let elem
28+
function fire() {
29+
_.difference(GWorld.GetAllActorsOfClass(Actor).OutActors, actors).forEach(actor => actor.DestroyActor())
30+
console.log(eval(`(function (){${elem.GetText()}})()`))
31+
}
32+
33+
class MyEditor extends JavascriptWidget {
34+
AddChild(x) {
35+
console.log('add child')
36+
this.SetRootWidget(x)
37+
return {}
38+
}
39+
RemoveChild(x) {
40+
this.SetRootWidget(null)
41+
}
42+
OnPreviewKeyDown(geom, key) {
43+
let K = KeyEvent.C(key).GetKey().KeyName
44+
if (K == 'F5') {
45+
fire()
46+
}
47+
return EventReply.Unhandled()
48+
}
49+
}
50+
51+
let MyEditor_C = require('uclass')()(global, MyEditor)
52+
53+
return UMG(MyEditor_C, { 'slot.size.size-rule': 'Fill' },
54+
UMG.div({ 'slot.size.size-rule': 'Fill' },
55+
UMG(Button, { OnClicked: _ => fire() }, "RUN (F5)"),
56+
UMG(MultiLineEditableTextBox, {
57+
'slot.size.size-rule': 'Fill',
58+
WidgetStyle: { 'font.size': fontSize },
59+
Text: source,
60+
$link: _elem => {
61+
elem = _elem
62+
},
63+
$unlink: _ => {
64+
}
65+
})
66+
)
67+
)
68+
}
69+
70+
function logWindow() {
71+
let onMessage = null
72+
let myOutput
73+
74+
return UMG(JavascriptMultiLineEditableTextBox, {
75+
'slot.size.size-rule': 'Fill',
76+
AlwaysShowScrollbars: true,
77+
IsReadOnly: true,
78+
$link: elem => {
79+
class MyOutput extends JavascriptOutputDevice {
80+
OnMessage(msg, verbosity, category) {
81+
onMessage && onMessage(msg, verbosity, category)
82+
}
83+
}
84+
85+
let MyOutput_C = require('uclass')()(global, MyOutput)
86+
myOutput = new MyOutput_C
87+
88+
let layout
89+
let style = TextBlockStyle({
90+
Font: { Size: fontSize },
91+
ColorAndOpacity: {
92+
SpecifiedColor: { R: 1, G: 1, B: 1, A: 1 }
93+
}
94+
})
95+
let style2 = TextBlockStyle({
96+
Font: { Size: fontSize },
97+
ColorAndOpacity: {
98+
SpecifiedColor: { R: 1, G: 1, B: 1, A: 0.5 }
99+
}
100+
})
101+
elem.SetTextDelegate = (text, _layout) => {
102+
layout = _layout
103+
}
104+
let timer = null
105+
let userScrolled = false
106+
elem.OnVScrollBarUserScrolled = offset => {
107+
userScrolled = (offset < 1 - 1e-5)
108+
}
109+
let lines = 0
110+
onMessage = (msg, v, category) => {
111+
let str = [category, msg].join(':')
112+
let model = new JavascriptTextModel()
113+
model.SetString(str)
114+
115+
if (!layout) return
116+
layout.AddLine(model, [
117+
model.CreateRun(style2, 0, category.length),
118+
model.CreateRun(style, category.length, str.length)
119+
])
120+
121+
lines++
122+
if (!userScrolled) {
123+
elem.ScrollTo(lines - 1)
124+
}
125+
}
126+
},
127+
$unlink: _ => {
128+
myOutput.Kill()
129+
myOutput = null
130+
onMessage = null
131+
}
132+
})
133+
}
134+
135+
function main() {
136+
let widget = null
137+
let PC = GetPC()
138+
139+
// create a widget
140+
widget = GWorld.CreateWidget(JavascriptWidget, PC)
141+
widget.JavascriptContext = Context
142+
widget.bSupportsKeyboardFocus = true
143+
144+
let design = UMG.span({},
145+
UMG.div({'slot.size.value':0.5}),
146+
UMG.div({'slot.size.value':0.5},
147+
editor(),
148+
logWindow()
149+
)
150+
)
151+
152+
let instantiator = require('instantiator')
153+
let page = instantiator(design)
154+
155+
page.Visibility = 'Visible'
156+
157+
widget.SetRootWidget(page)
158+
widget.AddToViewport()
159+
160+
// Switch PC to UI only mode.
161+
PC.bShowMouseCursor = true
162+
PC.SetInputMode_UIOnly(page)
163+
164+
return function() {
165+
onMessage = null
166+
myOutput = null
167+
widget.RemoveFromViewport()
168+
}
169+
}
170+
171+
try {
172+
module.exports = () => {
173+
let cleanup = null
174+
process.nextTick(() => cleanup = main());
175+
return () => cleanup()
176+
}
177+
}
178+
catch (e) {
179+
require('bootstrap')('helloSnippet')
180+
}

0 commit comments

Comments
 (0)