working text input
This commit is contained in:
parent
a53727318a
commit
3550f52530
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.build/
|
.build/
|
||||||
|
dist/
|
||||||
|
first
|
||||||
|
|||||||
79
dist/index.html
vendored
79
dist/index.html
vendored
@ -1,79 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8"/>
|
|
||||||
<title>${name}</title>
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
.game-title {
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
margin-top: 0px;
|
|
||||||
padding-left: 10px;
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
z-index: 1;
|
|
||||||
text-align: left;
|
|
||||||
font-family: "Arial Black", Gadget, sans-serif;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
.game-menu-item {
|
|
||||||
pointer-events: auto;
|
|
||||||
font-size: 18px;
|
|
||||||
padding-left: 10px;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
.game-menu-link {
|
|
||||||
text-decoration: none;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.game {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
border: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
display: block;
|
|
||||||
image-rendering: optimizeSpeed;
|
|
||||||
image-rendering: -moz-crisp-edges;
|
|
||||||
image-rendering: -o-crisp-edges;
|
|
||||||
image-rendering: -webkit-optimize-contrast;
|
|
||||||
image-rendering: optimize-contrast;
|
|
||||||
image-rendering: crisp-edges;
|
|
||||||
image-rendering: pixelated;
|
|
||||||
-ms-interpolation-mode: nearest-neighbor;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body style="background:black">
|
|
||||||
<div class="game-title">${name}
|
|
||||||
<span class="game-menu-item"><a class="game-menu-link" href="index.html">home</a></span>
|
|
||||||
</div>
|
|
||||||
<canvas class="game" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var Module = {
|
|
||||||
onRuntimeInitialized: function () {
|
|
||||||
const originalSet = HEAPU8.set.bind(HEAPU8);
|
|
||||||
HEAPU8.set = function(array, offset) {
|
|
||||||
if (typeof offset === 'bigint') {
|
|
||||||
offset = Number(offset);
|
|
||||||
}
|
|
||||||
return originalSet(array, offset);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
preRun: [],
|
|
||||||
print: (...args) => console.log('[stdout]: ' + args.join(' ')),
|
|
||||||
printErr: (...args) => console.log('[stderr]: ' + args.join(' ')),
|
|
||||||
};
|
|
||||||
window.onerror = (event) => console.log('[onerror]: ' + event.message);
|
|
||||||
</script>
|
|
||||||
<script async type="text/javascript" src="index.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
4927
dist/index.js
vendored
4927
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
BIN
dist/index.wasm
vendored
BIN
dist/index.wasm
vendored
Binary file not shown.
BIN
dist/main.o
vendored
BIN
dist/main.o
vendored
Binary file not shown.
BIN
dist/resources/DroidSerif-Regular.ttf
vendored
BIN
dist/resources/DroidSerif-Regular.ttf
vendored
Binary file not shown.
8
modules/Clipboard.jai
Normal file
8
modules/Clipboard.jai
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// @ToDo: implement clipboard with sokol -ktjst
|
||||||
|
os_clipboard_get_text :: () -> string {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
os_clipboard_set_text :: (s : string) {
|
||||||
|
}
|
||||||
|
|
||||||
@ -87,6 +87,28 @@ get_key_code_for_mouse :: (mb: sapp_mousebutton) -> Key_Code {
|
|||||||
return .UNKNOWN;
|
return .UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_modifier_info :: (sokol_event: *sapp_event, event: *Event) {
|
||||||
|
if sokol_event.modifiers & MODIFIER_SHIFT {
|
||||||
|
event.modifier_flags.shift_pressed = true;
|
||||||
|
}
|
||||||
|
if sokol_event.modifiers & MODIFIER_CTRL {
|
||||||
|
event.modifier_flags.ctrl_pressed = true;
|
||||||
|
}
|
||||||
|
if sokol_event.modifiers & MODIFIER_ALT {
|
||||||
|
event.modifier_flags.alt_pressed = true;
|
||||||
|
}
|
||||||
|
if sokol_event.modifiers & MODIFIER_SUPER {
|
||||||
|
event.modifier_flags.cmd_meta_pressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiers_cause_char_event_ignore :: (sokol_event: *sapp_event) -> bool {
|
||||||
|
if sokol_event.modifiers & MODIFIER_CTRL then return true;
|
||||||
|
if sokol_event.modifiers & MODIFIER_ALT then return true;
|
||||||
|
if sokol_event.modifiers & MODIFIER_SUPER then return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#scope_export
|
#scope_export
|
||||||
|
|
||||||
handle_sokol_event :: (event: *sapp_event) {
|
handle_sokol_event :: (event: *sapp_event) {
|
||||||
@ -97,12 +119,14 @@ handle_sokol_event :: (event: *sapp_event) {
|
|||||||
new_event.type = .KEYBOARD;
|
new_event.type = .KEYBOARD;
|
||||||
new_event.key_code = mapped;
|
new_event.key_code = mapped;
|
||||||
new_event.key_pressed = 1;
|
new_event.key_pressed = 1;
|
||||||
|
add_modifier_info(event, *new_event);
|
||||||
input_button_states[mapped] = .START | .DOWN;
|
input_button_states[mapped] = .START | .DOWN;
|
||||||
case .KEY_UP;
|
case .KEY_UP;
|
||||||
mapped := get_key_code(event.key_code);
|
mapped := get_key_code(event.key_code);
|
||||||
new_event.type = .KEYBOARD;
|
new_event.type = .KEYBOARD;
|
||||||
new_event.key_code = mapped;
|
new_event.key_code = mapped;
|
||||||
new_event.key_pressed = 0;
|
new_event.key_pressed = 0;
|
||||||
|
add_modifier_info(event, *new_event);
|
||||||
input_button_states[mapped] = .END;
|
input_button_states[mapped] = .END;
|
||||||
case .MOUSE_DOWN;
|
case .MOUSE_DOWN;
|
||||||
mapped := get_key_code_for_mouse(event.mouse_button);
|
mapped := get_key_code_for_mouse(event.mouse_button);
|
||||||
@ -117,6 +141,7 @@ handle_sokol_event :: (event: *sapp_event) {
|
|||||||
new_event.key_pressed = 0;
|
new_event.key_pressed = 0;
|
||||||
input_button_states[mapped] = .END;
|
input_button_states[mapped] = .END;
|
||||||
case .CHAR;
|
case .CHAR;
|
||||||
|
if modifiers_cause_char_event_ignore(event) then return;
|
||||||
new_event.type = .TEXT_INPUT;
|
new_event.type = .TEXT_INPUT;
|
||||||
new_event.utf32 = event.char_code;
|
new_event.utf32 = event.char_code;
|
||||||
case .FOCUSED;
|
case .FOCUSED;
|
||||||
@ -133,274 +158,6 @@ handle_sokol_event :: (event: *sapp_event) {
|
|||||||
array_add(*events_this_frame, new_event);
|
array_add(*events_this_frame, new_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// using Key_Code;
|
|
||||||
|
|
||||||
// input_per_frame_event_and_flag_update();
|
|
||||||
|
|
||||||
// display := x_global_display;
|
|
||||||
// XLockDisplay(display);
|
|
||||||
|
|
||||||
// key_press_repeat := false;
|
|
||||||
// while XPending(display) {
|
|
||||||
// xev: XEvent;
|
|
||||||
// XNextEvent(display, *xev);
|
|
||||||
|
|
||||||
// if XFilterEvent(*xev, None) continue;
|
|
||||||
|
|
||||||
// if xev.type == {
|
|
||||||
// case ClientMessage;
|
|
||||||
// message_type := xev.xclient.message_type;
|
|
||||||
// if message_type == XdndEnter {
|
|
||||||
// drop_handled := maybe_handle_xdnd_drop_events(display, *xev, *drop_info);
|
|
||||||
// if drop_handled continue;
|
|
||||||
// } else if message_type == x_global_wm_protocols {
|
|
||||||
// message0 := cast(Atom) xev.xclient.data.l[0];
|
|
||||||
|
|
||||||
// // This can't be a switch, because the values are not constant!
|
|
||||||
// // Except come on guys, every single implementation of X11 in the universe
|
|
||||||
// // is going to agree on these values. Why are we pretending they are not constant?
|
|
||||||
// // How about if we just look them up once and then hardcode them into this program?
|
|
||||||
// // We'd save startup time...
|
|
||||||
|
|
||||||
// if message0 == x_global_wm_delete_window {
|
|
||||||
// event: Event;
|
|
||||||
// event.type = .QUIT;
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// case KeyPress;
|
|
||||||
// event: Event;
|
|
||||||
|
|
||||||
// shift: u32;
|
|
||||||
// if xev.xkey.state & ShiftMask
|
|
||||||
// shift = 1;
|
|
||||||
// if xev.xkey.state & ControlMask
|
|
||||||
// event.ctrl_pressed = true;
|
|
||||||
// if xev.xkey.state & Mod1Mask
|
|
||||||
// event.alt_pressed = true;
|
|
||||||
|
|
||||||
// status: Status;
|
|
||||||
// keysym: KeySym;
|
|
||||||
// text: [16]u32;
|
|
||||||
// lookup_count := XwcLookupString(x_global_input_context, *xev.xkey, xx text.data, xx text.count, *keysym, *status);
|
|
||||||
|
|
||||||
// has_keysym := (status == XLookupKeySym || status == XLookupBoth);
|
|
||||||
// has_text := (status == XLookupChars || status == XLookupBoth);
|
|
||||||
|
|
||||||
// if has_keysym {
|
|
||||||
// if xev.xkey.state & ShiftMask event.shift_pressed = true;
|
|
||||||
// if xev.xkey.state & ControlMask event.ctrl_pressed = true;
|
|
||||||
// if xev.xkey.state & Mod1Mask event.alt_pressed = true;
|
|
||||||
// if xev.xkey.state & Mod4Mask event.cmd_meta_pressed = true;
|
|
||||||
|
|
||||||
// event.type = .KEYBOARD;
|
|
||||||
// event.key_pressed = 1;
|
|
||||||
// event.key_code = get_key_code(keysym);
|
|
||||||
|
|
||||||
// for 0..lookup_count - 1 {
|
|
||||||
// utf32 := text[it];
|
|
||||||
// if utf32 >= 32 && utf32 != 127 event.text_input_count += 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if event.key_code == {
|
|
||||||
// case .SHIFT; event.shift_pressed = true;
|
|
||||||
// case .CTRL; event.ctrl_pressed = true;
|
|
||||||
// case .ALT; event.alt_pressed = true;
|
|
||||||
// case .META; event.cmd_meta_pressed = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// event.repeat = key_press_repeat;
|
|
||||||
// key_press_repeat = false;
|
|
||||||
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// input_button_states[event.key_code] = .START | .DOWN;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// event.shift_pressed = cast(bool) shift;
|
|
||||||
|
|
||||||
// if has_text {
|
|
||||||
// for 0..lookup_count - 1 {
|
|
||||||
// utf32 := text[it];
|
|
||||||
// if utf32 < 32 || utf32 == 127 continue;
|
|
||||||
|
|
||||||
// char_event: Event;
|
|
||||||
// char_event.type = .TEXT_INPUT;
|
|
||||||
// char_event.key_pressed = 1;
|
|
||||||
// char_event.key_code = get_key_code(keysym);
|
|
||||||
// char_event.utf32 = utf32;
|
|
||||||
|
|
||||||
// array_add(*events_this_frame, char_event);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// case KeyRelease;
|
|
||||||
// // For some odd reason X11 generates KeyRelease followed by a near identical KeyPress to simulate repeat events so we have to filter that out
|
|
||||||
// if XEventsQueued(display, QueuedAfterReading) {
|
|
||||||
// nev: XEvent;
|
|
||||||
// XPeekEvent(display, *nev);
|
|
||||||
|
|
||||||
// if nev.type == KeyPress
|
|
||||||
// && nev.xkey.time == xev.xkey.time
|
|
||||||
// && nev.xkey.keycode == xev.xkey.keycode {
|
|
||||||
|
|
||||||
// // This is a repeat, so we ignore the KeyRelease and set the repeat flag.
|
|
||||||
// key_press_repeat = true;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// event: Event;
|
|
||||||
|
|
||||||
// shift: u32;
|
|
||||||
// if xev.xkey.state & ShiftMask
|
|
||||||
// shift = 1;
|
|
||||||
// if xev.xkey.state & ControlMask
|
|
||||||
// event.ctrl_pressed = true;
|
|
||||||
// if xev.xkey.state & Mod1Mask
|
|
||||||
// event.alt_pressed = true;
|
|
||||||
|
|
||||||
// keysym := XkbKeycodeToKeysym(display, xx xev.xkey.keycode, 0, 0 /* English lowercase group*/);
|
|
||||||
// event.type = .KEYBOARD;
|
|
||||||
// event.key_pressed = 0;
|
|
||||||
// event.shift_pressed = cast(bool) shift;
|
|
||||||
// event.key_code = get_key_code(keysym);
|
|
||||||
|
|
||||||
// input_button_states[event.key_code] = .END;
|
|
||||||
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// case ButtonPress;
|
|
||||||
// event: Event;
|
|
||||||
// event.type = .KEYBOARD;
|
|
||||||
|
|
||||||
// event.key_pressed = 1;
|
|
||||||
// button := xev.xbutton.button;
|
|
||||||
|
|
||||||
// // 6/7 is horizontal/secondary wheel, don't handle it
|
|
||||||
// if (button == 6) || (button == 7) continue;
|
|
||||||
|
|
||||||
// // button 4/5 is mwheel up/down
|
|
||||||
// if (button == 4) || (button == 5) {
|
|
||||||
// event.type = .MOUSE_WHEEL;
|
|
||||||
// event.typical_wheel_delta = WHEEL_DELTA;
|
|
||||||
// event.wheel_delta = event.typical_wheel_delta * ifx button & 1 then cast(s32) - 1 else 1;
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// mouse_delta_z += event.wheel_delta;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if button == Button1 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_LEFT;
|
|
||||||
// } else if button == Button2 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_MIDDLE;
|
|
||||||
// } else if button == Button3 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_RIGHT;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// input_button_states[event.key_code] = .START | .DOWN;
|
|
||||||
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// case ButtonRelease;
|
|
||||||
// // it seems that mouse input doesnt generate repeat events so we dont have to peek the queue
|
|
||||||
// event: Event;
|
|
||||||
// event.type = .KEYBOARD;
|
|
||||||
|
|
||||||
// event.key_pressed = 0;
|
|
||||||
// button := xev.xbutton.button;
|
|
||||||
|
|
||||||
// if (button >= 4) && (button <= 7) continue; // No action on button release of mouse wheels.
|
|
||||||
|
|
||||||
// if button == Button1 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_LEFT;
|
|
||||||
// } else if button == Button2 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_MIDDLE;
|
|
||||||
// } else if button == Button3 {
|
|
||||||
// event.key_code = MOUSE_BUTTON_RIGHT;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// input_button_states[event.key_code] = .END;
|
|
||||||
|
|
||||||
// array_add(*events_this_frame, event);
|
|
||||||
// case SelectionRequest;
|
|
||||||
// selreq := cast(*XSelectionRequestEvent) *xev;
|
|
||||||
|
|
||||||
// out: XEvent;
|
|
||||||
// selnot := cast(*XSelectionEvent) *out;
|
|
||||||
// selnot.type = SelectionNotify;
|
|
||||||
// selnot.requestor = selreq.requestor;
|
|
||||||
// selnot.selection = selreq.selection;
|
|
||||||
// selnot.target = selreq.target;
|
|
||||||
// selnot.time = selreq.time;
|
|
||||||
// selnot.property = None;
|
|
||||||
|
|
||||||
// if x_window_is_ours(x_global_display, selreq.owner) {
|
|
||||||
// if selreq.target == x_global_xa_utf8 {
|
|
||||||
// selnot.property = selreq.property;
|
|
||||||
|
|
||||||
// text_data := x_global_clipboard_buffer.text_data;
|
|
||||||
// XChangeProperty(selreq.display, selreq.requestor, selreq.property, selreq.target, 8, PropModeReplace,
|
|
||||||
// text_data.data, cast(s32) text_data.count);
|
|
||||||
// } else if selreq.target == x_global_xa_targets {
|
|
||||||
|
|
||||||
// selnot.property = selreq.property;
|
|
||||||
|
|
||||||
// atoms: [..] Atom;
|
|
||||||
// array_add(*atoms, x_global_xa_utf8);
|
|
||||||
// array_add(*atoms, x_global_xa_targets);
|
|
||||||
// array_add(*atoms, x_global_xa_multiple);
|
|
||||||
// if x_global_clipboard_buffer.rgb_data {
|
|
||||||
// array_add(*atoms, x_global_image_bmp);
|
|
||||||
// }
|
|
||||||
// XChangeProperty(selreq.display, selreq.requestor, selreq.property, x_global_xa_atom, 32, PropModeReplace,
|
|
||||||
// xx atoms.data, cast(s32) atoms.count);
|
|
||||||
|
|
||||||
// array_reset(*atoms);
|
|
||||||
// } else if selreq.target == x_global_image_bmp {
|
|
||||||
// #import "stb_image_write";
|
|
||||||
|
|
||||||
// Data :: struct {
|
|
||||||
// _context: *#Context;
|
|
||||||
// data: [..] u8;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// write_func :: (data_pointer: *void, _data: *void, size: s32) #c_call {
|
|
||||||
// data := cast(*Data) data_pointer;
|
|
||||||
// push_context data._context.* {
|
|
||||||
// data8 := cast(*u8) _data;
|
|
||||||
// for 0..size-1 {
|
|
||||||
// array_add(*data.data, data8[it]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// data: Data;
|
|
||||||
// data._context = *context;
|
|
||||||
// w := x_global_clipboard_buffer.width;
|
|
||||||
// h := x_global_clipboard_buffer.height;
|
|
||||||
// comp: s32 = 3;
|
|
||||||
// stride := x_global_clipboard_buffer.pitch;
|
|
||||||
// stbi_write_bmp_to_func(write_func, *data, w, h, comp, x_global_clipboard_buffer.rgb_data);
|
|
||||||
|
|
||||||
// selnot.property = selreq.property;
|
|
||||||
// XChangeProperty(selreq.display, selreq.requestor, selreq.property, selreq.target, 8, PropModeReplace,
|
|
||||||
// xx data.data.data, cast(s32) data.data.count);
|
|
||||||
|
|
||||||
// array_reset(*data.data);
|
|
||||||
// } else {
|
|
||||||
// // print("GOT REQ: %\n", to_string(XGetAtomName(x_global_display, selreq.target)));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// XSendEvent(selreq.display, selreq.requestor, True, 0, *out);
|
|
||||||
// case ConfigureNotify;
|
|
||||||
// config := cast(*XConfigureEvent) *xev;
|
|
||||||
// add_resize_record(config.window, config.width, config.height);
|
|
||||||
// case FocusIn;
|
|
||||||
// input_application_has_focus = true;
|
|
||||||
// case FocusOut;
|
|
||||||
// input_application_has_focus = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// XUnlockDisplay(display);
|
|
||||||
|
|
||||||
WHEEL_DELTA :: 120;
|
WHEEL_DELTA :: 120;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1,29 +1,3 @@
|
|||||||
mpos : Vector2;
|
|
||||||
|
|
||||||
Queued_State_Set :: struct {
|
|
||||||
code : Input.Key_Code;
|
|
||||||
state : Input.Key_Current_State;
|
|
||||||
ticks : int;
|
|
||||||
};
|
|
||||||
|
|
||||||
state_set_queue : [..]Queued_State_Set;
|
|
||||||
|
|
||||||
state_set_queue_add :: (qss: Queued_State_Set) {
|
|
||||||
array_add(*state_set_queue, qss);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_event :: (e: *sapp_event) {
|
handle_event :: (e: *sapp_event) {
|
||||||
handle_sokol_event(xx,force e);
|
handle_sokol_event(xx,force e);
|
||||||
// if e.type == .MOUSE_MOVE {
|
|
||||||
// mpos.x = e.mouse_x;
|
|
||||||
// mpos.y = e.mouse_y;
|
|
||||||
// }
|
|
||||||
// if e.type == .MOUSE_DOWN {
|
|
||||||
// GR.set_state_for_key(Input.Key_Code.MOUSE_BUTTON_LEFT, .START);
|
|
||||||
// state_set_queue_add(.{Input.Key_Code.MOUSE_BUTTON_LEFT, .DOWN, 2});
|
|
||||||
// }
|
|
||||||
// if e.type == .MOUSE_UP {
|
|
||||||
// GR.set_state_for_key(Input.Key_Code.MOUSE_BUTTON_LEFT, .END);
|
|
||||||
// state_set_queue_add(.{Input.Key_Code.MOUSE_BUTTON_LEFT, .NONE, 2});
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/load.jai
11
src/load.jai
@ -1,6 +1,13 @@
|
|||||||
MAX_FILE_SIZE :: 200_000;
|
MAX_FILE_SIZE :: 200_000;
|
||||||
buf : [MAX_FILE_SIZE]u8;
|
buf : [MAX_FILE_SIZE]u8;
|
||||||
|
|
||||||
|
mandatory_done : bool = false;
|
||||||
|
init_after_mandatory_done : bool = false;
|
||||||
|
|
||||||
|
mandatory_loads_done :: () -> bool {
|
||||||
|
return mandatory_done;
|
||||||
|
}
|
||||||
|
|
||||||
init_font_loads :: () {
|
init_font_loads :: () {
|
||||||
print("SENDING LOAD!!!!\n");
|
print("SENDING LOAD!!!!\n");
|
||||||
sfetch_send(*(sfetch_request_t.{
|
sfetch_send(*(sfetch_request_t.{
|
||||||
@ -16,5 +23,7 @@ init_font_loads :: () {
|
|||||||
fontcb :: (res: *sfetch_response_t) #c_call {
|
fontcb :: (res: *sfetch_response_t) #c_call {
|
||||||
push_context,defer_pop default_context;
|
push_context,defer_pop default_context;
|
||||||
print("RDY! Finished? % Fetched? % \n", res.fetched, res.finished);
|
print("RDY! Finished? % Fetched? % \n", res.fetched, res.finished);
|
||||||
state.font_default = fonsAddFontMem(state.fons, "sans", res.data.ptr, xx res.data.size, 0);
|
state.font_default.fons_font = fonsAddFontMem(state.fons, "sans", res.data.ptr, xx res.data.size, 0);
|
||||||
|
ui_init_font_fields(*state.font_default);
|
||||||
|
mandatory_done = true;
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/main.jai
19
src/main.jai
@ -16,7 +16,7 @@ state: struct {
|
|||||||
pass_action: sg_pass_action;
|
pass_action: sg_pass_action;
|
||||||
dpi_scale: float;
|
dpi_scale: float;
|
||||||
fons: *FONScontext;
|
fons: *FONScontext;
|
||||||
font_default: s32;
|
font_default: Ui_Font;
|
||||||
};
|
};
|
||||||
|
|
||||||
Window_Info :: struct {
|
Window_Info :: struct {
|
||||||
@ -60,19 +60,30 @@ init :: () {
|
|||||||
height = atlas_dim,
|
height = atlas_dim,
|
||||||
}));
|
}));
|
||||||
state.fons = fons_context;
|
state.fons = fons_context;
|
||||||
state.font_default = FONS_INVALID;
|
state.font_default.fons_font = FONS_INVALID;
|
||||||
create_pipelines();
|
create_pipelines();
|
||||||
|
|
||||||
state.pass_action.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0.5, g = 0.5, b = 0.9, a = 1 } };
|
state.pass_action.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0.5, g = 0.5, b = 0.9, a = 1 } };
|
||||||
init_ui();
|
|
||||||
init_font_loads();
|
init_font_loads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_after_mandatory_loads :: () {
|
||||||
|
init_ui();
|
||||||
|
}
|
||||||
|
|
||||||
frame :: () {
|
frame :: () {
|
||||||
dpis := state.dpi_scale;
|
|
||||||
|
|
||||||
sfetch_dowork();
|
sfetch_dowork();
|
||||||
|
|
||||||
|
if mandatory_loads_done() && !init_after_mandatory_done {
|
||||||
|
init_after_mandatory_loads();
|
||||||
|
init_after_mandatory_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !mandatory_loads_done() then return;
|
||||||
|
|
||||||
|
dpis := state.dpi_scale;
|
||||||
|
|
||||||
fonsClearState(state.fons);
|
fonsClearState(state.fons);
|
||||||
for event: Input.events_this_frame {
|
for event: Input.events_this_frame {
|
||||||
GR.getrect_handle_event(event);
|
GR.getrect_handle_event(event);
|
||||||
|
|||||||
@ -11,7 +11,7 @@ create_pipelines :: () {
|
|||||||
create_arbtri_pipeline();
|
create_arbtri_pipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
gArbtriMem : [1000*3*9]float;
|
gArbtriMem : [100000*3*9]float;
|
||||||
|
|
||||||
create_arbtri_pipeline :: () {
|
create_arbtri_pipeline :: () {
|
||||||
pipeline: sg_pipeline_desc;
|
pipeline: sg_pipeline_desc;
|
||||||
@ -31,7 +31,7 @@ create_arbtri_pipeline :: () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pipeline.color_count = 4;
|
pipeline.color_count = 1;
|
||||||
pipeline.colors[0] = color_state;
|
pipeline.colors[0] = color_state;
|
||||||
|
|
||||||
gPipelines.arbtri.pipeline = sg_make_pipeline(*pipeline);
|
gPipelines.arbtri.pipeline = sg_make_pipeline(*pipeline);
|
||||||
|
|||||||
@ -7,14 +7,30 @@ Ui_Font_Glyph :: struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ui_Font :: struct {
|
Ui_Font :: struct {
|
||||||
em_width: u32 = 1;
|
em_width : int = 1;
|
||||||
character_height: u32 = 30;
|
character_height : int = 30;
|
||||||
typical_descender: u32 = 1;
|
typical_descender : int = 1;
|
||||||
typical_ascender: u32 = 1;
|
typical_ascender : int = 1;
|
||||||
|
fons_font : s32 = 0;
|
||||||
temporary_glyphs : [..]Ui_Font_Glyph;
|
temporary_glyphs : [..]Ui_Font_Glyph;
|
||||||
temporary_glyphs_byte_offsets : [..]u32;
|
temporary_glyphs_byte_offsets : [..]u32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ui_init_font_fields :: (font: *Ui_Font) {
|
||||||
|
m_str := "M";
|
||||||
|
fonsSetFont(state.fons, xx font.fons_font);
|
||||||
|
fonsSetSize(state.fons, xx font.character_height);
|
||||||
|
|
||||||
|
ascender, descender, line_h : float;
|
||||||
|
fonsVertMetrics(state.fons, *ascender, *descender, *line_h);
|
||||||
|
|
||||||
|
font.typical_descender = cast(int) descender;
|
||||||
|
font.typical_ascender = cast(int) (ascender * 0.85); // @stupid fix to make the ascender not be so big.
|
||||||
|
|
||||||
|
w := fonsTextBounds(state.fons, 0.0, 0.0, m_str.data, m_str.data + m_str.count, null);
|
||||||
|
font.em_width = xx w;
|
||||||
|
}
|
||||||
|
|
||||||
Ui_Texture :: struct {
|
Ui_Texture :: struct {
|
||||||
tex: sg_image;
|
tex: sg_image;
|
||||||
}
|
}
|
||||||
@ -95,11 +111,24 @@ gPreppedText: string;
|
|||||||
gPreppedTextWidth : s32;
|
gPreppedTextWidth : s32;
|
||||||
|
|
||||||
prepare_text :: (font: *Ui_Type_Indicator.Font, text: string, effects: Ui_Type_Indicator.Font_Effects = 0) -> s64 {
|
prepare_text :: (font: *Ui_Type_Indicator.Font, text: string, effects: Ui_Type_Indicator.Font_Effects = 0) -> s64 {
|
||||||
fonsSetFont(state.fons, state.font_default);
|
fonsSetFont(state.fons, state.font_default.fons_font);
|
||||||
fonsSetSize(state.fons, xx font.character_height);
|
fonsSetSize(state.fons, xx font.character_height);
|
||||||
w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null);
|
w := fonsTextBounds(state.fons, 0.0, 0.0, text.data, text.data + text.count, null);
|
||||||
gPreppedText = text;
|
gPreppedText = text;
|
||||||
gPreppedTextWidth = cast(s32) w;
|
gPreppedTextWidth = cast(s32) w;
|
||||||
|
|
||||||
|
array_reset(*font.temporary_glyphs);
|
||||||
|
array_reset(*font.temporary_glyphs_byte_offsets);
|
||||||
|
|
||||||
|
for 0..(text.count-1) {
|
||||||
|
glyph : Ui_Font_Glyph;
|
||||||
|
|
||||||
|
glyph.advance = cast(u32) fonsTextBounds(state.fons, 0.0, 0.0, text.data + it, text.data + it + 1, null);
|
||||||
|
|
||||||
|
array_add(*font.temporary_glyphs, glyph);
|
||||||
|
array_add(*font.temporary_glyphs_byte_offsets, cast(u32) it);
|
||||||
|
}
|
||||||
|
|
||||||
return cast(s64) w;
|
return cast(s64) w;
|
||||||
}
|
}
|
||||||
draw_prepared_text :: (font: *Ui_Type_Indicator.Font, x: s64, y: s64, text_color: Vector4, effects: Ui_Type_Indicator.Font_Effects = 0) {
|
draw_prepared_text :: (font: *Ui_Type_Indicator.Font, x: s64, y: s64, text_color: Vector4, effects: Ui_Type_Indicator.Font_Effects = 0) {
|
||||||
@ -115,8 +144,8 @@ get_mouse_pointer_position :: (window: Ui_Type_Indicator.Window_Type, right_hand
|
|||||||
}
|
}
|
||||||
get_font_at_size :: (memory: [] u8, pixel_height: int) -> *Font {
|
get_font_at_size :: (memory: [] u8, pixel_height: int) -> *Font {
|
||||||
f : *Font = New(Font);
|
f : *Font = New(Font);
|
||||||
// f.character_height = cast(u32) pixel_height;
|
f.character_height = cast(u32) pixel_height;
|
||||||
// f.em_width = cast(u32) get_font_letter_width(109, cast (s32) pixel_height);
|
ui_init_font_fields(f);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +231,10 @@ get_font_at_size :: (pixel_height: int) -> *Font {
|
|||||||
|
|
||||||
idk : bool;
|
idk : bool;
|
||||||
|
|
||||||
|
test_color : Vector3 = .{1.0, 0.0, 1.0};
|
||||||
|
|
||||||
render_ui :: () {
|
render_ui :: () {
|
||||||
proc := GR.default_theme_procs[3];
|
proc := GR.default_theme_procs[0];
|
||||||
my_theme := proc();
|
my_theme := proc();
|
||||||
GR.set_default_theme(my_theme);
|
GR.set_default_theme(my_theme);
|
||||||
|
|
||||||
@ -220,6 +251,11 @@ render_ui :: () {
|
|||||||
if GR.base_checkbox(r, "CHECK!!!", idk, null) {
|
if GR.base_checkbox(r, "CHECK!!!", idk, null) {
|
||||||
idk = !idk;
|
idk = !idk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.y += 150;
|
||||||
|
r.h = 500;
|
||||||
|
|
||||||
|
GR.color_picker(r, *test_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user