Last active
April 28, 2019 19:26
-
-
Save paniq/28334ce7c61d16ff80f10ec2af2dcd56 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env scopes | |
let stringtest = "Hello" | |
let booltest = true | |
import .tukan.glmain | |
import .tukan.screen | |
#import .tukan.imgui | |
let glmain = tukan.glmain | |
let screen = tukan.screen | |
import .tukan.dockgui | |
let dockgui = tukan.dockgui | |
using import glm | |
using import glsl | |
using import Capture | |
using import Map | |
using import .tukan.gl | |
using import .tukan.imgui | |
let fbsize = | |
ivec2 1920 1080 | |
run-stage; | |
glmain.init | |
title = "Tukan" | |
width = 960 | |
height = 540 | |
resizable = true | |
print "setting up texture..." | |
let fbtex = | |
'setup (glCreateTexture GL_TEXTURE_2D) | |
size = fbsize | |
format = GL_RGBA8 | |
#global fbtex = (dupe fbtex) | |
local color = | |
arrayof u8 255 0 255 255 | |
glClearTexImage fbtex 0 GL_RGBA GL_UNSIGNED_BYTE (bitcast &color (pointer void)) | |
print "setting up framebuffer..." | |
let fb = (glCreateFramebuffer) | |
setup-framebuffer fb | |
color = fbtex | |
print "building shaders" | |
fn normsin (x) | |
(sin x) * 0.5 + 0.5 | |
struct ShaderGlobals plain | |
aspect : f32 | |
let BUFFER_COUNT = 3 | |
uniform phase : f32 | |
location = 0 | |
uniform shglobals : ShaderGlobals | |
binding = 0 | |
let globals-data = (glCreateBuffer) | |
setup-ubo globals-data shglobals BUFFER_COUNT | |
#------------------------------------------------------------------------------- | |
inout uv : vec2 (location = 0) | |
inout pos : vec2 (location = 1) | |
fn test-vertex () | |
uv.out = | |
((screen.set-vertex-position) * 0.5) + 0.5 | |
return; | |
fn make-phase () | |
deref phase | |
out out_Color : vec4 | |
fn test-fragment () | |
let uv = | |
(uv.in * 2.0 - 1.0) * (vec2 shglobals.aspect 1) | |
out_Color = | |
vec4 | |
vec2 (clamp ((length uv) - 0.5) 0.0 1.0) | |
make-phase; | |
1 | |
return; | |
#compile-glsl 'vertex | |
typify fragment-fn | |
'dump-module | |
print "attaching shaders..." | |
let pg-test = (glCreateProgram) | |
call | |
attach-shaders pg-test | |
vertex = test-vertex | |
fragment = test-fragment | |
#debug = true | |
locals; | |
#------------------------------------------------------------------------------- | |
print "running main program" | |
global test-window-visible = false | |
@@ 'on dockgui.on-define-windows | |
fn () | |
if test-window-visible | |
ShowDemoWindow test-window-visible | |
@@ 'on dockgui.on-define-main-menu | |
fn () | |
if (WithMenu "View") | |
MenuItem "Show Demo Window" | |
selected = test-window-visible | |
global g_phase = 0.0 | |
global g_frame = 0 | |
inline render-view (size) | |
glBindFramebuffer GL_FRAMEBUFFER fb | |
glViewport 0 0 (i32 size.x) (i32 size.y) | |
glClearColor 0 0 1 1 | |
glClear | |
| | |
GL_COLOR_BUFFER_BIT | |
GL_DEPTH_BUFFER_BIT | |
GL_STENCIL_BUFFER_BIT | |
glUseProgram pg-test | |
glUniform phase (normsin g_phase) | |
let buffer-index = (g_frame % BUFFER_COUNT) | |
local data = | |
ShaderGlobals | |
aspect = (size.x / size.y) | |
bind-ubo globals-data shglobals buffer-index &data | |
g_phase = (g_phase + 0.1) | |
g_frame = g_frame + 1 | |
screen.draw; | |
glUseProgram 0 | |
let | |
HPADDING = 5 | |
HMARGIN = 2 | |
VMARGIN = 2 | |
ROUNDING = 2 | |
let | |
SAME = 'same | |
CHANGED = 'changed | |
DELETE = 'delete | |
INSERT = 'insert | |
fn branchnode (title selected) | |
AlignTextToFramePadding; | |
WithTreeNode title | |
| ImGuiTreeNodeFlags_DefaultOpen | |
ImGuiTreeNodeFlags_OpenOnArrow | |
ImGuiTreeNodeFlags_OpenOnDoubleClick | |
? selected (ImGuiTreeNodeFlags_Selected as u32 as i32) 0 | |
fn leafnode (title) | |
AlignTextToFramePadding; | |
let result = | |
TreeNodeEx title | |
| ImGuiTreeNodeFlags_Leaf | |
ImGuiTreeNodeFlags_NoTreePushOnOpen | |
ImGuiTreeNodeFlags_Bullet | |
SameLine; | |
result | |
fn default-ui-width (item) | |
#let T = ('typeof item) | |
return 100.0 | |
fn root-ui | |
fn list-widget-ui | |
fn tail-drop-button (output count changed) | |
Button "##drag_target" | |
vec2 100 5 | |
if (WithDragDropTarget) | |
if ((let payload = (AcceptDragDropPayload "VALUE")) != null) | |
let src = (@ (payload.Data as (pointer Value))) | |
output @ count = (deref src) | |
_ (count + 1) CHANGED | |
else | |
_ count changed | |
else | |
_ count changed | |
fn inner-drop-button () | |
if (WithDragDropTarget) | |
if ((let payload = (AcceptDragDropPayload "VALUE")) != null) | |
let src = (deref (@ (payload.Data as (pointer Value)))) | |
return true src | |
return false `none | |
let MAX_TMPSTR = 255 | |
global tmpstr : (array i8 MAX_TMPSTR) | |
fn inner-ui (ctx listelem level) | |
static-assert ((typeof listelem) == list) | |
let output = (alloca-array Value ((countof listelem) + 1)) | |
loop (idx count listelem changed = 0 0 listelem SAME) | |
if (empty? listelem) | |
vvv bind count changed | |
tail-drop-button output count changed | |
if (changed == SAME) | |
return listelem SAME | |
else | |
loop (k outp = count '()) | |
if (k == 0) | |
return outp CHANGED | |
let k = (k - 1) | |
repeat k (cons (output @ k) outp) | |
WithID idx | |
let item next = (decons listelem) | |
inline return-unchanged () | |
output @ count = item | |
repeat (idx + 2) (count + 1) next changed | |
inline return-insert (newitem) | |
output @ count = newitem | |
output @ (count + 1) = item | |
repeat (idx + 2) (count + 2) next CHANGED | |
inline return-changed (item) | |
output @ count = item | |
repeat (idx + 2) (count + 1) next CHANGED | |
inline return-delete () | |
repeat (idx + 2) count next CHANGED | |
let T = ('typeof item) | |
match T | |
case list | |
let p = (GetCursorScreenPos) | |
#SetCursorScreenPos | |
vec2 (p.x + width + HPADDING + HMARGIN) p.y | |
let next changed = | |
list-widget-ui ctx item level idx | |
switch changed | |
case INSERT | |
return-insert next | |
case DELETE | |
return-delete; | |
case CHANGED | |
return-changed next | |
default | |
; | |
case Symbol | |
let sym = (item as Symbol) | |
if ((sym == 'true) or (sym == 'false)) | |
#local data = (sym == 'true) | |
#let changed = (Checkbox "" data) | |
#if changed | |
return-changed | |
? (sym == 'true) true false | |
elseif (idx > 0) | |
Text (sym as string) | |
case string | |
#PushItemWidth width | |
if (leafnode "string") | |
vvv bind insert? src | |
inner-drop-button; | |
let id = (GetID idx) | |
let s = (item as string) | |
let count = (min (MAX_TMPSTR as usize) (countof s)) | |
loop (i = 0:usize) | |
if (i == count) | |
tmpstr @ i = 0:i8 | |
break; | |
tmpstr @ i = s @ i | |
i + 1:usize | |
let changed = | |
InputText "" &tmpstr MAX_TMPSTR | |
ImGuiInputTextFlags_EnterReturnsTrue as u32 as i32 | |
if insert? | |
return-insert src | |
#PopItemWidth; | |
if changed | |
return-changed | |
string &tmpstr | |
case bool | |
if (leafnode "bool") | |
vvv bind insert? src | |
inner-drop-button; | |
local data = (item as bool) | |
let changed = (Checkbox "" data) | |
if insert? | |
return-insert src | |
if changed | |
return-changed (data == true) | |
case i32 | |
if (leafnode "i32") | |
vvv bind insert? src | |
inner-drop-button; | |
#PushItemWidth width | |
local data = (item as i32) | |
let changed = (InputInt "" data) | |
#PopItemWidth; | |
if insert? | |
return-insert src | |
if changed | |
return-changed (deref data) | |
case f32 | |
if (leafnode "f32") | |
vvv bind insert? src | |
inner-drop-button; | |
#PushItemWidth width | |
local data = (item as f32) | |
let changed = (InputFloat "" data) | |
#PopItemWidth; | |
if insert? | |
return-insert src | |
if changed | |
return-changed (deref data) | |
default | |
Text (tostring item) | |
return-unchanged; | |
typedef SelectTag : i32 | |
inline __typecall (cls group) | |
bitcast group this-type | |
fn list-widget-ui (ctx item level idx) | |
returning Value Symbol | |
let listitem = (item as list) | |
let select-group listitem = | |
do | |
let head rest = (decons listitem) | |
if (('typeof head) == SelectTag) | |
_ (storagecast (head as SelectTag)) rest | |
else | |
_ 0 listitem | |
let head rest = (decons listitem) | |
let head = | |
if (('typeof head) == Symbol) (head as Symbol) | |
else unnamed | |
let selected = (select-group == ctx.select-group) | |
let open = (branchnode (head as string) selected) | |
vvv bind insert? src | |
inner-drop-button; | |
if (WithPopupContextItem "context menu") | |
if (Selectable "Delete") | |
ctx.next-delete-group = ctx.select-group | |
else false | |
vvv bind select-group | |
if (IsItemClicked) | |
if ((GetIO) . KeyCtrl) | |
if selected 0 | |
else (deref ctx.select-group) | |
else | |
ctx.select-group += 1 | |
deref ctx.select-group | |
else select-group | |
vvv bind item changed | |
if open | |
let newitem changed = | |
inner-ui ctx listitem (level + 1) | |
if (changed == SAME) | |
_ listitem SAME | |
else | |
_ newitem changed | |
else | |
_ listitem SAME | |
vvv bind item changed | |
if (select-group == ctx.select-group) | |
_ (cons (SelectTag select-group) item) CHANGED | |
elseif (select-group != 0) # need to strip selection tag | |
_ item CHANGED | |
else | |
_ item changed | |
let delete? = (select-group == ctx.delete-group) | |
let item = `item | |
if insert? | |
return src INSERT | |
elseif delete? | |
return item DELETE | |
else | |
return item changed | |
fn root-ui (ctx listelem level) | |
static-assert ((typeof listelem) == list) | |
let output = (alloca-array Value ((countof listelem) + 1)) | |
loop (idx count listelem changed = 0 0 listelem SAME) | |
if (empty? listelem) | |
vvv bind count changed | |
tail-drop-button output count changed | |
if (changed == SAME) | |
return listelem SAME | |
else | |
loop (k outp = count '()) | |
if (k == 0) | |
return outp CHANGED | |
let k = (k - 1) | |
repeat k (cons (output @ k) outp) | |
WithID idx | |
let item next = (decons listelem) | |
inline return-unchanged () | |
output @ count = item | |
repeat (idx + 2) (count + 1) next changed | |
inline return-insert (newitem) | |
output @ count = newitem | |
output @ (count + 1) = item | |
repeat (idx + 2) (count + 2) next CHANGED | |
inline return-changed (item) | |
output @ count = item | |
repeat (idx + 2) (count + 1) next CHANGED | |
inline return-delete () | |
repeat (idx + 2) count next CHANGED | |
let T = ('typeof item) | |
match T | |
case list | |
let newitem changed = | |
list-widget-ui ctx item level idx | |
switch changed | |
case INSERT | |
return-insert newitem | |
case DELETE | |
return-delete; | |
case CHANGED | |
return-changed newitem | |
default | |
; | |
default | |
leafnode (tostring item) | |
; | |
return-unchanged; | |
fn render-source-item (ctx rootitem) | |
ctx.delete-group = ctx.next-delete-group | |
ctx.next-delete-group = -1 | |
let s = (deref ctx.newheader) | |
let count = (min (MAX_TMPSTR as usize) (countof s)) | |
loop (i = 0:usize) | |
if (i == count) | |
tmpstr @ i = 0:i8 | |
break; | |
tmpstr @ i = s @ i | |
i + 1:usize | |
if | |
InputText "##newheader" &tmpstr MAX_TMPSTR | |
#ImGuiInputTextFlags_EnterReturnsTrue as u32 as i32 | |
ctx.newheader = (string &tmpstr) | |
SameLine; Button "Drag" | |
if (WithDragDropSource) | |
let s = (deref ctx.newheader) | |
local payload = `[(list (Symbol s))] | |
SetDragDropPayload "VALUE" payload | |
Text s | |
do | |
WithChild "content" | |
let result changed = | |
do | |
WithStyleVar ImGuiStyleVar_FramePadding (vec2 2 2) | |
root-ui ctx (deref rootitem) 0 | |
if (changed != SAME) | |
rootitem = result | |
global source = #'() | |
sugar-quote | |
print "this is some text" | |
print "this is a sublist" | |
+ 1 2 | |
+ 3 4 | |
303 | |
print true false | |
print 1 1.0 | |
struct EditorContext | |
#selected : (Set u32) | |
newheader = "print" | |
select-group = 1 | |
next-delete-group = -1 | |
delete-group = -1 | |
local context = (EditorContext) | |
@@ 'on dockgui.on-define-dock | |
inline () | |
SetNextDock ImGuiDockSlot_Left | |
if (WithDock "Code") | |
render-source-item context source | |
SetNextDock ImGuiDockSlot_Right | |
if (WithDock "3D") | |
let size = | |
GetContentRegionAvail; | |
if ((size.x > 0) & (size.y > 0)) | |
render-view size | |
Image | |
inttoptr fbtex ImTextureID | |
size = size | |
uv0 = | |
vec2 0.0 | |
size.y / (f32 fbsize.y) | |
uv1 = | |
vec2 | |
size.x / (f32 fbsize.x) | |
0.0 | |
SetNextDock ImGuiDockSlot_Tab | |
if (WithDock "Output") | |
Text | |
sc_list_serialize (deref source) | |
@@ 'on dockgui.on-frame | |
fn (s size) | |
#glBlitNamedFramebuffer fb 0 | |
\ 0 0 size.x size.y | |
\ 0 0 size.x size.y | |
GL_COLOR_BUFFER_BIT | |
GL_NEAREST | |
glmain.loop; | |
glmain.shutdown; | |
print "done." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment