HUGE refactor to SDL + SDL_TTF rendering
parent
99dea9e863
commit
96338e2924
|
@ -59,6 +59,8 @@
|
|||
fixed-odin
|
||||
local-rust
|
||||
rust-analyzer
|
||||
SDL2
|
||||
SDL2_ttf
|
||||
darwin.apple_sdk.frameworks.CoreData
|
||||
darwin.apple_sdk.frameworks.Kernel
|
||||
darwin.apple_sdk.frameworks.CoreVideo
|
||||
|
|
|
@ -361,119 +361,246 @@ pub enum Hook {
|
|||
|
||||
#[repr(i32)]
|
||||
pub enum Key {
|
||||
KeyNull = 0, // Key: NULL, used for no key pressed
|
||||
// Alphanumeric keys
|
||||
Apostrophe = 39, // key: '
|
||||
Comma = 44, // Key: ,
|
||||
Minus = 45, // Key: -
|
||||
Period = 46, // Key: .
|
||||
Slash = 47, // Key: /
|
||||
Zero = 48, // Key: 0
|
||||
One = 49, // Key: 1
|
||||
Two = 50, // Key: 2
|
||||
Three = 51, // Key: 3
|
||||
Four = 52, // Key: 4
|
||||
Five = 53, // Key: 5
|
||||
Six = 54, // Key: 6
|
||||
Seven = 55, // Key: 7
|
||||
Eight = 56, // Key: 8
|
||||
Nine = 57, // Key: 9
|
||||
Semicolon = 59, // Key: ;
|
||||
Equal = 61, // Key: =
|
||||
A = 65, // Key: A | a
|
||||
B = 66, // Key: B | b
|
||||
C = 67, // Key: C | c
|
||||
D = 68, // Key: D | d
|
||||
E = 69, // Key: E | e
|
||||
F = 70, // Key: F | f
|
||||
G = 71, // Key: G | g
|
||||
H = 72, // Key: H | h
|
||||
I = 73, // Key: I | i
|
||||
J = 74, // Key: J | j
|
||||
K = 75, // Key: K | k
|
||||
L = 76, // Key: L | l
|
||||
M = 77, // Key: M | m
|
||||
N = 78, // Key: N | n
|
||||
O = 79, // Key: O | o
|
||||
P = 80, // Key: P | p
|
||||
Q = 81, // Key: Q | q
|
||||
R = 82, // Key: R | r
|
||||
S = 83, // Key: S | s
|
||||
T = 84, // Key: T | t
|
||||
U = 85, // Key: U | u
|
||||
V = 86, // Key: V | v
|
||||
W = 87, // Key: W | w
|
||||
X = 88, // Key: X | x
|
||||
Y = 89, // Key: Y | y
|
||||
Z = 90, // Key: Z | z
|
||||
LeftBracket = 91, // Key: [
|
||||
Backslash = 92, // Key: '\'
|
||||
RightBracket = 93, // Key: ]
|
||||
Grave = 96, // Key: `
|
||||
// Function keys
|
||||
Space = 32, // Key: Space
|
||||
Escape = 256, // Key: Esc
|
||||
Enter = 257, // Key: Enter
|
||||
Tab = 258, // Key: Tab
|
||||
Backspace = 259, // Key: Backspace
|
||||
Insert = 260, // Key: Ins
|
||||
Delete = 261, // Key: Del
|
||||
Right = 262, // Key: Cursor right
|
||||
Left = 263, // Key: Cursor left
|
||||
Down = 264, // Key: Cursor down
|
||||
Up = 265, // Key: Cursor up
|
||||
PageUp = 266, // Key: Page up
|
||||
PageDown = 267, // Key: Page down
|
||||
Home = 268, // Key: Home
|
||||
End = 269, // Key: End
|
||||
CapsLock = 280, // Key: Caps lock
|
||||
ScrollLock = 281, // Key: Scroll down
|
||||
NumLock = 282, // Key: Num lock
|
||||
PrintScreen = 283, // Key: Print screen
|
||||
Pause = 284, // Key: Pause
|
||||
F1 = 290, // Key: F1
|
||||
F2 = 291, // Key: F2
|
||||
F3 = 292, // Key: F3
|
||||
F4 = 293, // Key: F4
|
||||
F5 = 294, // Key: F5
|
||||
F6 = 295, // Key: F6
|
||||
F7 = 296, // Key: F7
|
||||
F8 = 297, // Key: F8
|
||||
F9 = 298, // Key: F9
|
||||
F10 = 299, // Key: F10
|
||||
F11 = 300, // Key: F11
|
||||
F12 = 301, // Key: F12
|
||||
LeftShift = 340, // Key: Shift left
|
||||
LeftControl = 341, // Key: Control left
|
||||
LeftAlt = 342, // Key: Alt left
|
||||
LeftSuper = 343, // Key: Super left
|
||||
RightShift = 344, // Key: Shift right
|
||||
RightControl = 345, // Key: Control right
|
||||
RightAlt = 346, // Key: Alt right
|
||||
RightSuper = 347, // Key: Super right
|
||||
KbMenu = 348, // Key: KB menu
|
||||
// Keypad keys
|
||||
Kp0 = 320, // Key: Keypad 0
|
||||
Kp1 = 321, // Key: Keypad 1
|
||||
Kp2 = 322, // Key: Keypad 2
|
||||
Kp3 = 323, // Key: Keypad 3
|
||||
Kp4 = 324, // Key: Keypad 4
|
||||
Kp5 = 325, // Key: Keypad 5
|
||||
Kp6 = 326, // Key: Keypad 6
|
||||
Kp7 = 327, // Key: Keypad 7
|
||||
Kp8 = 328, // Key: Keypad 8
|
||||
Kp9 = 329, // Key: Keypad 9
|
||||
KpDecimal = 330, // Key: Keypad .
|
||||
KpDivide = 331, // Key: Keypad /
|
||||
KpMultiply = 332, // Key: Keypad *
|
||||
KpSubtract = 333, // Key: Keypad -
|
||||
KpAdd = 334, // Key: Keypad +
|
||||
KpEnter = 335, // Key: Keypad Enter
|
||||
KpEqual = 336, // Key: Keypad =
|
||||
// Android key buttons
|
||||
Back = 4, // Key: Android back button
|
||||
VolumeUp = 24, // Key: Android volume up button
|
||||
VolumeDown = 25, // Key: Android volume down button
|
||||
UNKNOWN = 0,
|
||||
Enter = 13,
|
||||
ESCAPE = 27,
|
||||
BACKSPACE = 8,
|
||||
TAB = 9,
|
||||
Space = 32,
|
||||
EXCLAIM = 33,
|
||||
QUOTEDBL = 34,
|
||||
HASH = 35,
|
||||
PERCENT = 37,
|
||||
DOLLAR = 36,
|
||||
AMPERSAND = 38,
|
||||
QUOTE = 39,
|
||||
LEFTPAREN = 40,
|
||||
RIGHTPAREN = 41,
|
||||
ASTERISK = 42,
|
||||
PLUS = 43,
|
||||
COMMA = 44,
|
||||
MINUS = 45,
|
||||
PERIOD = 46,
|
||||
SLASH = 47,
|
||||
NUM0 = 48,
|
||||
NUM1 = 49,
|
||||
NUM2 = 50,
|
||||
NUM3 = 51,
|
||||
NUM4 = 52,
|
||||
NUM5 = 53,
|
||||
NUM6 = 54,
|
||||
NUM7 = 55,
|
||||
NUM8 = 56,
|
||||
NUM9 = 57,
|
||||
COLON = 58,
|
||||
SEMICOLON = 59,
|
||||
LESS = 60,
|
||||
EQUAL = 61,
|
||||
GREATER = 62,
|
||||
QUESTION = 63,
|
||||
AT = 64,
|
||||
LEFTBRACKET = 91,
|
||||
BACKSLASH = 92,
|
||||
RIGHTBRACKET = 93,
|
||||
CARET = 94,
|
||||
UNDERSCORE = 95,
|
||||
BACKQUOTE = 96,
|
||||
A = 97,
|
||||
B = 98,
|
||||
C = 99,
|
||||
D = 100,
|
||||
E = 101,
|
||||
F = 102,
|
||||
G = 103,
|
||||
H = 104,
|
||||
I = 105,
|
||||
J = 106,
|
||||
K = 107,
|
||||
L = 108,
|
||||
M = 109,
|
||||
N = 110,
|
||||
O = 111,
|
||||
P = 112,
|
||||
Q = 113,
|
||||
R = 114,
|
||||
S = 115,
|
||||
T = 116,
|
||||
U = 117,
|
||||
V = 118,
|
||||
W = 119,
|
||||
X = 120,
|
||||
Y = 121,
|
||||
Z = 122,
|
||||
CAPSLOCK = 1073741881,
|
||||
F1 = 1073741882,
|
||||
F2 = 1073741883,
|
||||
F3 = 1073741884,
|
||||
F4 = 1073741885,
|
||||
F5 = 1073741886,
|
||||
F6 = 1073741887,
|
||||
F7 = 1073741888,
|
||||
F8 = 1073741889,
|
||||
F9 = 1073741890,
|
||||
F10 = 1073741891,
|
||||
F11 = 1073741892,
|
||||
F12 = 1073741893,
|
||||
PRINTSCREEN = 1073741894,
|
||||
SCROLLLOCK = 1073741895,
|
||||
PAUSE = 1073741896,
|
||||
INSERT = 1073741897,
|
||||
HOME = 1073741898,
|
||||
PAGEUP = 1073741899,
|
||||
DELETE = 127,
|
||||
END = 1073741901,
|
||||
PAGEDOWN = 1073741902,
|
||||
RIGHT = 1073741903,
|
||||
LEFT = 1073741904,
|
||||
DOWN = 1073741905,
|
||||
UP = 1073741906,
|
||||
NUMLOCKCLEAR = 1073741907,
|
||||
KpDivide = 1073741908,
|
||||
KpMultiply = 1073741909,
|
||||
KpMinus = 1073741910,
|
||||
KpPlus = 1073741911,
|
||||
KpEnter = 1073741912,
|
||||
Kp1 = 1073741913,
|
||||
Kp2 = 1073741914,
|
||||
Kp3 = 1073741915,
|
||||
Kp4 = 1073741916,
|
||||
Kp5 = 1073741917,
|
||||
Kp6 = 1073741918,
|
||||
Kp7 = 1073741919,
|
||||
Kp8 = 1073741920,
|
||||
Kp9 = 1073741921,
|
||||
Kp0 = 1073741922,
|
||||
KpPeriod = 1073741923,
|
||||
APPLICATION = 1073741925,
|
||||
POWER = 1073741926,
|
||||
KpEquals = 1073741927,
|
||||
F13 = 1073741928,
|
||||
F14 = 1073741929,
|
||||
F15 = 1073741930,
|
||||
F16 = 1073741931,
|
||||
F17 = 1073741932,
|
||||
F18 = 1073741933,
|
||||
F19 = 1073741934,
|
||||
F20 = 1073741935,
|
||||
F21 = 1073741936,
|
||||
F22 = 1073741937,
|
||||
F23 = 1073741938,
|
||||
F24 = 1073741939,
|
||||
EXECUTE = 1073741940,
|
||||
HELP = 1073741941,
|
||||
MENU = 1073741942,
|
||||
SELECT = 1073741943,
|
||||
STOP = 1073741944,
|
||||
AGAIN = 1073741945,
|
||||
UNDO = 1073741946,
|
||||
CUT = 1073741947,
|
||||
COPY = 1073741948,
|
||||
PASTE = 1073741949,
|
||||
FIND = 1073741950,
|
||||
MUTE = 1073741951,
|
||||
VOLUMEUP = 1073741952,
|
||||
VOLUMEDOWN = 1073741953,
|
||||
KpComma = 1073741957,
|
||||
KpEqualsas400 = 1073741958,
|
||||
ALTERASE = 1073741977,
|
||||
SYSREQ = 1073741978,
|
||||
CANCEL = 1073741979,
|
||||
CLEAR = 1073741980,
|
||||
PRIOR = 1073741981,
|
||||
RETURN2 = 1073741982,
|
||||
SEPARATOR = 1073741983,
|
||||
OUT = 1073741984,
|
||||
OPER = 1073741985,
|
||||
CLEARAGAIN = 1073741986,
|
||||
CRSEL = 1073741987,
|
||||
EXSEL = 1073741988,
|
||||
Kp00 = 1073742000,
|
||||
Kp000 = 1073742001,
|
||||
THOUSANDSSEPARATOR = 1073742002,
|
||||
DECIMALSEPARATOR = 1073742003,
|
||||
CURRENCYUNIT = 1073742004,
|
||||
CURRENCYSUBUNIT = 1073742005,
|
||||
KpLeftparen = 1073742006,
|
||||
KpRightparen = 1073742007,
|
||||
KpLeftbrace = 1073742008,
|
||||
KpRightbrace = 1073742009,
|
||||
KpTab = 1073742010,
|
||||
KpBackspace = 1073742011,
|
||||
KpA = 1073742012,
|
||||
KpB = 1073742013,
|
||||
KpC = 1073742014,
|
||||
KpD = 1073742015,
|
||||
KpE = 1073742016,
|
||||
KpF = 1073742017,
|
||||
KpXor = 1073742018,
|
||||
KpPower = 1073742019,
|
||||
KpPercent = 1073742020,
|
||||
KpLess = 1073742021,
|
||||
KpGreater = 1073742022,
|
||||
KpAmpersand = 1073742023,
|
||||
KpDblampersand = 1073742024,
|
||||
KpVerticalbar = 1073742025,
|
||||
KpDblverticalbar = 1073742026,
|
||||
KpColon = 1073742027,
|
||||
KpHash = 1073742028,
|
||||
KpSpace = 1073742029,
|
||||
KpAt = 1073742030,
|
||||
KpExclam = 1073742031,
|
||||
KpMemstore = 1073742032,
|
||||
KpMemrecall = 1073742033,
|
||||
KpMemclear = 1073742034,
|
||||
KpMemadd = 1073742035,
|
||||
KpMemsubtract = 1073742036,
|
||||
KpMemmultiply = 1073742037,
|
||||
KpMemdivide = 1073742038,
|
||||
KpPlusminus = 1073742039,
|
||||
KpClear = 1073742040,
|
||||
KpClearentry = 1073742041,
|
||||
KpBinary = 1073742042,
|
||||
KpOctal = 1073742043,
|
||||
KpDecimal = 1073742044,
|
||||
KpHexadecimal = 1073742045,
|
||||
LCTRL = 1073742048,
|
||||
LSHIFT = 1073742049,
|
||||
LALT = 1073742050,
|
||||
LGUI = 1073742051,
|
||||
RCTRL = 1073742052,
|
||||
RSHIFT = 1073742053,
|
||||
RALT = 1073742054,
|
||||
RGUI = 1073742055,
|
||||
MODE = 1073742081,
|
||||
AUDIONEXT = 1073742082,
|
||||
AUDIOPREV = 1073742083,
|
||||
AUDIOSTOP = 1073742084,
|
||||
AUDIOPLAY = 1073742085,
|
||||
AUDIOMUTE = 1073742086,
|
||||
MEDIASELECT = 1073742087,
|
||||
WWW = 1073742088,
|
||||
MAIL = 1073742089,
|
||||
CALCULATOR = 1073742090,
|
||||
COMPUTER = 1073742091,
|
||||
AcSearch = 1073742092,
|
||||
AcHome = 1073742093,
|
||||
AcBack = 1073742094,
|
||||
AcForward = 1073742095,
|
||||
AcStop = 1073742096,
|
||||
AcRefresh = 1073742097,
|
||||
AcBookmarks = 1073742098,
|
||||
BRIGHTNESSDOWN = 1073742099,
|
||||
BRIGHTNESSUP = 1073742100,
|
||||
DISPLAYSWITCH = 1073742101,
|
||||
KBDILLUMTOGGLE = 1073742102,
|
||||
KBDILLUMDOWN = 1073742103,
|
||||
KBDILLUMUP = 1073742104,
|
||||
EJECT = 1073742105,
|
||||
SLEEP = 1073742106,
|
||||
APP1 = 1073742107,
|
||||
APP2 = 1073742108,
|
||||
AUDIOREWIND = 1073742109,
|
||||
AUDIOFASTFORWARD = 1073742110,
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
|
|
|
@ -4,7 +4,6 @@ package buffer_search;
|
|||
import "core:runtime"
|
||||
import "core:fmt"
|
||||
import "core:path/filepath"
|
||||
import "vendor:raylib"
|
||||
|
||||
import p "../../src/plugin"
|
||||
import "../../src/theme"
|
||||
|
@ -109,24 +108,24 @@ draw_buffer_window :: proc "c" (plugin: Plugin, win: rawptr) {
|
|||
source_font_width := plugin.get_font_width();
|
||||
source_font_height := plugin.get_font_height();
|
||||
|
||||
win_rec := raylib.Rectangle {
|
||||
x = f32(screen_width/8),
|
||||
y = f32(screen_height/8),
|
||||
width = f32(screen_width - screen_width/4),
|
||||
height = f32(screen_height - screen_height/4),
|
||||
win_rec := [4]f32 {
|
||||
f32(screen_width/8),
|
||||
f32(screen_height/8),
|
||||
f32(screen_width - screen_width/4),
|
||||
f32(screen_height - screen_height/4),
|
||||
};
|
||||
plugin.draw_rect(
|
||||
i32(win_rec.x),
|
||||
i32(win_rec.y),
|
||||
i32(win_rec.width),
|
||||
i32(win_rec.height),
|
||||
i32(win_rec.z),
|
||||
i32(win_rec.w),
|
||||
.Background4
|
||||
);
|
||||
|
||||
win_margin := raylib.Vector2 { f32(source_font_width), f32(source_font_height) };
|
||||
win_margin := [2]f32 { f32(source_font_width), f32(source_font_height) };
|
||||
|
||||
buffer_prev_width := (win_rec.width - win_margin.x*2) / 2;
|
||||
buffer_prev_height := win_rec.height - win_margin.y*2;
|
||||
buffer_prev_width := (win_rec.z - win_margin.x*2) / 2;
|
||||
buffer_prev_height := win_rec.w - win_margin.y*2;
|
||||
|
||||
glyph_buffer_width := int(buffer_prev_width) / source_font_width - 1;
|
||||
glyph_buffer_height := int(buffer_prev_height) / source_font_height;
|
||||
|
@ -134,7 +133,7 @@ draw_buffer_window :: proc "c" (plugin: Plugin, win: rawptr) {
|
|||
directory := string(plugin.get_current_directory());
|
||||
|
||||
plugin.draw_rect(
|
||||
i32(win_rec.x + win_rec.width / 2),
|
||||
i32(win_rec.x + win_rec.z / 2),
|
||||
i32(win_rec.y + win_margin.y),
|
||||
i32(buffer_prev_width),
|
||||
i32(buffer_prev_height),
|
||||
|
@ -151,7 +150,7 @@ draw_buffer_window :: proc "c" (plugin: Plugin, win: rawptr) {
|
|||
if index == win.selected_index {
|
||||
plugin.draw_buffer_from_index(
|
||||
index,
|
||||
int(win_rec.x + win_margin.x + win_rec.width / 2),
|
||||
int(win_rec.x + win_margin.x + win_rec.z / 2),
|
||||
int(win_rec.y + win_margin.y),
|
||||
glyph_buffer_width,
|
||||
glyph_buffer_height,
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
};
|
||||
|
||||
use grep::{
|
||||
regex::{RegexMatcherBuilder},
|
||||
regex::RegexMatcherBuilder,
|
||||
searcher::{BinaryDetection, SearcherBuilder, Sink, SinkError},
|
||||
};
|
||||
use plugin_rs_bindings::{Buffer, Closure, Hook, InputMap, Key, PaletteColor, Plugin};
|
||||
|
@ -213,17 +213,19 @@ pub extern "C" fn OnInitialize(plugin: Plugin) {
|
|||
None => 0,
|
||||
};
|
||||
|
||||
let index_threshold = std::cmp::max(max_mats_to_draw-4, 0) as usize;
|
||||
if match_count > 0 {
|
||||
let index_threshold = std::cmp::max(max_mats_to_draw-4, 0) as usize;
|
||||
|
||||
if window.selected_match < match_count-1 {
|
||||
window.selected_match += 1;
|
||||
if window.selected_match < match_count-1 {
|
||||
window.selected_match += 1;
|
||||
|
||||
if window.selected_match - window.top_index > index_threshold {
|
||||
window.top_index += 1;
|
||||
if window.selected_match - window.top_index > index_threshold {
|
||||
window.top_index += 1;
|
||||
}
|
||||
} else {
|
||||
window.selected_match = 0;
|
||||
window.top_index = 0;
|
||||
}
|
||||
} else {
|
||||
window.selected_match = 0;
|
||||
window.top_index = 0;
|
||||
}
|
||||
}
|
||||
}), "move selection down\0".as_ptr());
|
||||
|
|
|
@ -2,7 +2,7 @@ package core
|
|||
|
||||
import "core:runtime"
|
||||
import "core:fmt"
|
||||
import "vendor:raylib"
|
||||
import "vendor:sdl2"
|
||||
|
||||
import "../plugin"
|
||||
|
||||
|
@ -42,12 +42,13 @@ close_window_and_free :: proc(state: ^State) {
|
|||
|
||||
State :: struct {
|
||||
ctx: runtime.Context,
|
||||
sdl_renderer: ^sdl2.Renderer,
|
||||
font_atlas: FontAtlas,
|
||||
|
||||
mode: Mode,
|
||||
should_close: bool,
|
||||
screen_height: int,
|
||||
screen_width: int,
|
||||
font: raylib.Font,
|
||||
|
||||
directory: string,
|
||||
|
||||
|
@ -86,14 +87,14 @@ Action :: struct {
|
|||
description: string,
|
||||
}
|
||||
InputMap :: struct {
|
||||
key_actions: map[raylib.KeyboardKey]Action,
|
||||
ctrl_key_actions: map[raylib.KeyboardKey]Action,
|
||||
key_actions: map[plugin.Key]Action,
|
||||
ctrl_key_actions: map[plugin.Key]Action,
|
||||
}
|
||||
|
||||
new_input_map :: proc() -> InputMap {
|
||||
input_map := InputMap {
|
||||
key_actions = make(map[raylib.KeyboardKey]Action),
|
||||
ctrl_key_actions = make(map[raylib.KeyboardKey]Action),
|
||||
key_actions = make(map[plugin.Key]Action),
|
||||
ctrl_key_actions = make(map[plugin.Key]Action),
|
||||
}
|
||||
|
||||
return input_map;
|
||||
|
@ -106,7 +107,7 @@ delete_input_map :: proc(input_map: ^InputMap) {
|
|||
// NOTE(pcleavelin): might be a bug in the compiler where it can't coerce
|
||||
// `EditorAction` to `InputGroup` when given as a proc parameter, that is why there
|
||||
// are two functions
|
||||
register_plugin_key_action_single :: proc(input_map: ^InputMap, key: raylib.KeyboardKey, action: PluginEditorAction, description: string = "") {
|
||||
register_plugin_key_action_single :: proc(input_map: ^InputMap, key: plugin.Key, action: PluginEditorAction, description: string = "") {
|
||||
if ok := key in input_map.key_actions; ok {
|
||||
// TODO: log that key is already registered
|
||||
fmt.eprintln("plugin key already registered with single action", key);
|
||||
|
@ -118,7 +119,7 @@ register_plugin_key_action_single :: proc(input_map: ^InputMap, key: raylib.Keyb
|
|||
};
|
||||
}
|
||||
|
||||
register_key_action_single :: proc(input_map: ^InputMap, key: raylib.KeyboardKey, action: EditorAction, description: string = "") {
|
||||
register_key_action_single :: proc(input_map: ^InputMap, key: plugin.Key, action: EditorAction, description: string = "") {
|
||||
if ok := key in input_map.key_actions; ok {
|
||||
// TODO: log that key is already registered
|
||||
fmt.eprintln("key already registered with single action", key);
|
||||
|
@ -130,7 +131,7 @@ register_key_action_single :: proc(input_map: ^InputMap, key: raylib.KeyboardKey
|
|||
};
|
||||
}
|
||||
|
||||
register_key_action_group :: proc(input_map: ^InputMap, key: raylib.KeyboardKey, input_group: InputGroup, description: string = "") {
|
||||
register_key_action_group :: proc(input_map: ^InputMap, key: plugin.Key, input_group: InputGroup, description: string = "") {
|
||||
if ok := key in input_map.key_actions; ok {
|
||||
// TODO: log that key is already registered
|
||||
fmt.eprintln("key already registered with single action", key);
|
||||
|
@ -142,7 +143,7 @@ register_key_action_group :: proc(input_map: ^InputMap, key: raylib.KeyboardKey,
|
|||
};
|
||||
}
|
||||
|
||||
register_ctrl_key_action_single :: proc(input_map: ^InputMap, key: raylib.KeyboardKey, action: EditorAction, description: string = "") {
|
||||
register_ctrl_key_action_single :: proc(input_map: ^InputMap, key: plugin.Key, action: EditorAction, description: string = "") {
|
||||
if ok := key in input_map.key_actions; ok {
|
||||
// TODO: log that key is already registered
|
||||
fmt.eprintln("key already registered with single action", key);
|
||||
|
@ -154,7 +155,7 @@ register_ctrl_key_action_single :: proc(input_map: ^InputMap, key: raylib.Keyboa
|
|||
};
|
||||
}
|
||||
|
||||
register_ctrl_key_action_group :: proc(input_map: ^InputMap, key: raylib.KeyboardKey, input_group: InputGroup, description: string = "") {
|
||||
register_ctrl_key_action_group :: proc(input_map: ^InputMap, key: plugin.Key, input_group: InputGroup, description: string = "") {
|
||||
if ok := key in input_map.key_actions; ok {
|
||||
// TODO: log that key is already registered
|
||||
fmt.eprintln("key already registered with single action", key);
|
||||
|
|
|
@ -8,7 +8,6 @@ import "core:math"
|
|||
import "core:slice"
|
||||
import "core:runtime"
|
||||
import "core:strings"
|
||||
import "vendor:raylib"
|
||||
|
||||
import "../theme"
|
||||
import "../plugin"
|
||||
|
@ -752,7 +751,7 @@ update_glyph_buffer :: proc(buffer: ^FileBuffer) {
|
|||
}
|
||||
}
|
||||
|
||||
draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, font: raylib.Font, show_line_numbers: bool = true) {
|
||||
draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, show_line_numbers: bool = true) {
|
||||
update_glyph_buffer(buffer);
|
||||
if highlighter, exists := state.highlighters[buffer.extension]; exists {
|
||||
highlighter(state.plugin_vtable, buffer);
|
||||
|
@ -771,9 +770,11 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, fon
|
|||
|
||||
// draw cursor
|
||||
if state.mode == .Normal {
|
||||
raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Background4));
|
||||
draw_rect(state, cursor_x, cursor_y, state.source_font_width, state.source_font_height, .Background4);
|
||||
//raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Background4));
|
||||
} else if state.mode == .Insert {
|
||||
raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Green));
|
||||
draw_rect(state, cursor_x, cursor_y, state.source_font_width, state.source_font_height, .Green);
|
||||
// raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Green));
|
||||
|
||||
num_line_break := 0;
|
||||
line_length := 0;
|
||||
|
@ -793,14 +794,16 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, fon
|
|||
cursor_x += line_length * state.source_font_width;
|
||||
}
|
||||
|
||||
raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Blue));
|
||||
draw_rect(state, cursor_x, cursor_y, state.source_font_width, state.source_font_height, .Blue);
|
||||
//raylib.DrawRectangle(i32(cursor_x), i32(cursor_y), i32(state.source_font_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Blue));
|
||||
}
|
||||
|
||||
for j in 0..<buffer.glyph_buffer_height {
|
||||
text_y := y + state.source_font_height * j;
|
||||
|
||||
if show_line_numbers {
|
||||
raylib.DrawTextEx(font, raylib.TextFormat("%d", begin + j + 1), raylib.Vector2 { f32(x), f32(text_y) }, f32(state.source_font_height), 0, theme.get_palette_raylib_color(.Background4));
|
||||
draw_text(state, fmt.tprintf("%d", begin + j + 1), x, text_y);
|
||||
//raylib.DrawTextEx(font, raylib.TextFormat("%d", begin + j + 1), raylib.Vector2 { f32(x), f32(text_y) }, f32(state.source_font_height), 0, theme.get_palette_raylib_color(.Background4));
|
||||
}
|
||||
|
||||
for i in 0..<buffer.glyph_buffer_width {
|
||||
|
@ -809,7 +812,8 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, fon
|
|||
|
||||
if glyph.codepoint == 0 { break; }
|
||||
|
||||
raylib.DrawTextCodepoint(font, rune(glyph.codepoint), raylib.Vector2 { f32(text_x), f32(text_y) }, f32(state.source_font_height), theme.get_palette_raylib_color(glyph.color));
|
||||
draw_codepoint(state, rune(glyph.codepoint), text_x, text_y, glyph.color);
|
||||
//raylib.DrawTextCodepoint(font, rune(glyph.codepoint), raylib.Vector2 { f32(text_x), f32(text_y) }, f32(state.source_font_height), theme.get_palette_raylib_color(glyph.color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
package core
|
||||
|
||||
import "core:fmt"
|
||||
import "vendor:sdl2"
|
||||
import "vendor:sdl2/ttf"
|
||||
|
||||
import "../theme"
|
||||
|
||||
scale :: 2;
|
||||
start_char :: ' ';
|
||||
end_char :: '~';
|
||||
|
||||
FontAtlas :: struct {
|
||||
texture: ^sdl2.Texture,
|
||||
font: ^ttf.Font,
|
||||
max_width: int,
|
||||
max_height: int,
|
||||
}
|
||||
|
||||
gen_font_atlas :: proc(state: ^State, path: cstring) -> FontAtlas {
|
||||
free_font_atlas(state.font_atlas);
|
||||
|
||||
font_height := i32(state.source_font_height*scale);
|
||||
|
||||
atlas := FontAtlas {
|
||||
// FIXME: check if this failed
|
||||
font = ttf.OpenFont(path, font_height),
|
||||
}
|
||||
ttf.SetFontKerning(atlas.font, false);
|
||||
ttf.SetFontStyle(atlas.font, ttf.STYLE_NORMAL);
|
||||
ttf.SetFontOutline(atlas.font, 0);
|
||||
|
||||
minx, maxx, miny, maxy: i32;
|
||||
advanced: i32;
|
||||
for char in start_char..=end_char {
|
||||
ttf.GlyphMetrics32(atlas.font, char, &minx, &maxx, &miny, &maxy, &advanced);
|
||||
|
||||
width := maxx-minx;
|
||||
height := maxy+miny;
|
||||
|
||||
if width > i32(atlas.max_width) {
|
||||
atlas.max_width = int(width);
|
||||
}
|
||||
if height > i32(atlas.max_height) {
|
||||
atlas.max_height = int(height);
|
||||
}
|
||||
|
||||
// if atlas.max_width%2 != 0 {
|
||||
// atlas.max_width += 1;
|
||||
// }
|
||||
}
|
||||
|
||||
font_width := i32(atlas.max_width);
|
||||
font_height = i32(atlas.max_height);
|
||||
state.source_font_width = int(font_width/scale);// int(font_width/scale);
|
||||
state.source_font_height = int(font_height/scale);//int(font_height/scale);
|
||||
//fmt.println("font_width:", font_width, "font height:", font_height);
|
||||
//state.source_font_width = int(f32(font_width)/f32(scale));
|
||||
|
||||
temp_surface: ^sdl2.Surface;
|
||||
sdl2.SetHint(sdl2.HINT_RENDER_SCALE_QUALITY, "2");
|
||||
// FIXME: check if this failed
|
||||
font_surface := sdl2.CreateRGBSurface(0, font_width * (end_char-start_char + 1), font_height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
|
||||
rect: sdl2.Rect;
|
||||
|
||||
white := sdl2.Color { 0xff, 0xff, 0xff, 0xff };
|
||||
for char, index in start_char..=end_char {
|
||||
// ttf.GlyphMetrics32(atlas.font, char, &minx, &maxx, &miny, &maxy, &advanced);
|
||||
|
||||
rect.x = i32(index) * font_width;
|
||||
rect.y = 0;//-font_height/8;
|
||||
|
||||
// FIXME: check if this failed
|
||||
temp_surface = ttf.RenderGlyph32_Blended(atlas.font, char, white);
|
||||
|
||||
src_rect := sdl2.Rect {
|
||||
0,
|
||||
0,
|
||||
temp_surface.w,
|
||||
temp_surface.h
|
||||
};
|
||||
//fmt.println("char", char, src_rect.x, src_rect.y, src_rect.w, src_rect.h, atlas.max_width, atlas.max_height);
|
||||
|
||||
// FIXME: check if this failed
|
||||
sdl2.BlitSurface(temp_surface, &src_rect, font_surface, &rect);
|
||||
sdl2.FreeSurface(temp_surface);
|
||||
}
|
||||
|
||||
// FIXME: check if this failed
|
||||
atlas.texture = sdl2.CreateTextureFromSurface(state.sdl_renderer, font_surface);
|
||||
sdl2.SetTextureScaleMode(atlas.texture, .Best);
|
||||
// sdl2.SetTextureAlphaMod(atlas.texture, 0xff);
|
||||
// sdl2.SetTextureBlendMode(atlas.texture, .BLEND);
|
||||
return atlas;
|
||||
}
|
||||
|
||||
free_font_atlas :: proc(font_atlas: FontAtlas) {
|
||||
if font_atlas.font != nil {
|
||||
ttf.CloseFont(font_atlas.font);
|
||||
}
|
||||
if font_atlas.texture != nil {
|
||||
sdl2.DestroyTexture(font_atlas.texture);
|
||||
}
|
||||
}
|
||||
|
||||
draw_rect_outline :: proc(state: ^State, x,y,w,h: int, color: theme.PaletteColor) {
|
||||
color := theme.get_palette_color(color);
|
||||
|
||||
sdl2.SetRenderDrawColor(state.sdl_renderer, color.r, color.g, color.b, color.a);
|
||||
sdl2.RenderDrawRect(state.sdl_renderer, &sdl2.Rect { i32(x), i32(y), i32(w), i32(h) });
|
||||
}
|
||||
|
||||
draw_rect :: proc(state: ^State, x,y,w,h: int, color: theme.PaletteColor) {
|
||||
color := theme.get_palette_color(color);
|
||||
|
||||
sdl2.SetRenderDrawColor(state.sdl_renderer, color.r, color.g, color.b, color.a);
|
||||
sdl2.RenderFillRect(state.sdl_renderer, &sdl2.Rect { i32(x), i32(y), i32(w), i32(h) });
|
||||
}
|
||||
|
||||
draw_codepoint :: proc(state: ^State, codepoint: rune, x,y: int, color: theme.PaletteColor) {
|
||||
color := theme.get_palette_color(color);
|
||||
|
||||
if codepoint >= start_char && codepoint <= end_char {
|
||||
codepoint := codepoint - start_char;
|
||||
|
||||
src_rect := sdl2.Rect {
|
||||
x = i32(codepoint) * i32(state.font_atlas.max_width),
|
||||
y = 0,
|
||||
w = i32(state.font_atlas.max_width),
|
||||
h = i32(state.font_atlas.max_height),
|
||||
};
|
||||
|
||||
dest_rect := sdl2.Rect {
|
||||
x = i32(x),
|
||||
y = i32(y),
|
||||
w = i32(state.font_atlas.max_width/scale),
|
||||
h = i32(state.font_atlas.max_height/scale),
|
||||
};
|
||||
|
||||
sdl2.SetTextureColorMod(state.font_atlas.texture, color.r, color.g, color.b);
|
||||
sdl2.RenderCopy(state.sdl_renderer, state.font_atlas.texture, &src_rect, &dest_rect);
|
||||
}
|
||||
}
|
||||
|
||||
draw_text :: proc(state: ^State, text: string, x,y: int, color: theme.PaletteColor = .Foreground1) {
|
||||
for char, idx in text {
|
||||
if char < start_char || char > end_char {
|
||||
draw_codepoint(state, '?', x + idx * state.source_font_width, y, color);
|
||||
} else {
|
||||
draw_codepoint(state, char, x + idx * state.source_font_width, y, color);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
731
src/main.odin
731
src/main.odin
|
@ -8,7 +8,8 @@ import "core:runtime"
|
|||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:slice"
|
||||
import "vendor:raylib"
|
||||
import "vendor:sdl2"
|
||||
import "vendor:sdl2/ttf"
|
||||
|
||||
import "core"
|
||||
import "theme"
|
||||
|
@ -20,44 +21,49 @@ FileBuffer :: core.FileBuffer;
|
|||
|
||||
state := core.State {};
|
||||
|
||||
StateWithUi :: struct {
|
||||
state: ^State,
|
||||
ui_context: ^ui.Context,
|
||||
}
|
||||
|
||||
// TODO: use buffer list in state
|
||||
do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) {
|
||||
if state.current_input_map != nil {
|
||||
if raylib.IsKeyPressed(.ESCAPE) {
|
||||
core.request_window_close(state);
|
||||
} else if raylib.IsKeyDown(.LEFT_CONTROL) {
|
||||
for key, action in &state.current_input_map.ctrl_key_actions {
|
||||
if raylib.IsKeyPressed(key) {
|
||||
switch value in action.action {
|
||||
case core.PluginEditorAction:
|
||||
value(state.plugin_vtable);
|
||||
case core.EditorAction:
|
||||
value(state);
|
||||
case core.InputMap:
|
||||
state.current_input_map = &(&state.current_input_map.ctrl_key_actions[key]).action.(core.InputMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for key, action in state.current_input_map.key_actions {
|
||||
if raylib.IsKeyPressed(key) {
|
||||
switch value in action.action {
|
||||
case core.PluginEditorAction:
|
||||
value(state.plugin_vtable);
|
||||
case core.EditorAction:
|
||||
value(state);
|
||||
case core.InputMap:
|
||||
state.current_input_map = &(&state.current_input_map.key_actions[key]).action.(core.InputMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if raylib.IsKeyPressed(.ESCAPE) {
|
||||
// core.request_window_close(state);
|
||||
// } else if raylib.IsKeyDown(.LEFT_CONTROL) {
|
||||
// for key, action in &state.current_input_map.ctrl_key_actions {
|
||||
// if raylib.IsKeyPressed(key) {
|
||||
// switch value in action.action {
|
||||
// case core.PluginEditorAction:
|
||||
// value(state.plugin_vtable);
|
||||
// case core.EditorAction:
|
||||
// value(state);
|
||||
// case core.InputMap:
|
||||
// state.current_input_map = &(&state.current_input_map.ctrl_key_actions[key]).action.(core.InputMap)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// for key, action in state.current_input_map.key_actions {
|
||||
// if raylib.IsKeyPressed(key) {
|
||||
// switch value in action.action {
|
||||
// case core.PluginEditorAction:
|
||||
// value(state.plugin_vtable);
|
||||
// case core.EditorAction:
|
||||
// value(state);
|
||||
// case core.InputMap:
|
||||
// state.current_input_map = &(&state.current_input_map.key_actions[key]).action.(core.InputMap)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use buffer list in state
|
||||
do_insert_mode :: proc(state: ^State, buffer: ^FileBuffer) {
|
||||
key := raylib.GetCharPressed();
|
||||
key := 0; // raylib.GetCharPressed();
|
||||
|
||||
for key > 0 {
|
||||
if key >= 32 && key <= 125 && len(buffer.input_buffer) < 1024-1 {
|
||||
|
@ -68,38 +74,38 @@ do_insert_mode :: proc(state: ^State, buffer: ^FileBuffer) {
|
|||
}
|
||||
}
|
||||
|
||||
key = raylib.GetCharPressed();
|
||||
key = 0; // raylib.GetCharPressed();
|
||||
}
|
||||
|
||||
if raylib.IsKeyPressed(.ENTER) {
|
||||
append(&buffer.input_buffer, '\n');
|
||||
}
|
||||
// if raylib.IsKeyPressed(.ENTER) {
|
||||
// append(&buffer.input_buffer, '\n');
|
||||
// }
|
||||
|
||||
if raylib.IsKeyPressed(.ESCAPE) {
|
||||
state.mode = .Normal;
|
||||
// if raylib.IsKeyPressed(.ESCAPE) {
|
||||
// state.mode = .Normal;
|
||||
|
||||
core.insert_content(buffer, buffer.input_buffer[:]);
|
||||
runtime.clear(&buffer.input_buffer);
|
||||
return;
|
||||
}
|
||||
// core.insert_content(buffer, buffer.input_buffer[:]);
|
||||
// runtime.clear(&buffer.input_buffer);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if raylib.IsKeyPressed(.BACKSPACE) {
|
||||
core.delete_content(buffer, 1);
|
||||
// if raylib.IsKeyPressed(.BACKSPACE) {
|
||||
// core.delete_content(buffer, 1);
|
||||
|
||||
for hook_proc in state.hooks[plugin.Hook.BufferInput] {
|
||||
hook_proc(state.plugin_vtable, buffer);
|
||||
}
|
||||
}
|
||||
// for hook_proc in state.hooks[plugin.Hook.BufferInput] {
|
||||
// hook_proc(state.plugin_vtable, buffer);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
switch_to_buffer :: proc(state: ^State, item: ^ui.MenuBarItem) {
|
||||
for buffer, index in state.buffers {
|
||||
if strings.compare(buffer.file_path, item.text) == 0 {
|
||||
state.current_buffer = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// switch_to_buffer :: proc(state: ^State, item: ^ui.MenuBarItem) {
|
||||
// for buffer, index in state.buffers {
|
||||
// if strings.compare(buffer.file_path, item.text) == 0 {
|
||||
// state.current_buffer = index;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
register_default_leader_actions :: proc(input_map: ^core.InputMap) {
|
||||
core.register_key_action(input_map, .Q, proc(state: ^State) {
|
||||
|
@ -160,16 +166,18 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
|||
state.source_font_height -= 2;
|
||||
state.source_font_width = state.source_font_height / 2;
|
||||
|
||||
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
|
||||
//state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||
//raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
}
|
||||
}, "increase font size");
|
||||
core.register_ctrl_key_action(input_map, .EQUAL, proc(state: ^State) {
|
||||
state.source_font_height += 2;
|
||||
state.source_font_width = state.source_font_height / 2;
|
||||
|
||||
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
|
||||
//state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||
//raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
}, "decrease font size");
|
||||
}
|
||||
|
||||
|
@ -219,11 +227,159 @@ ui_font_height :: proc() -> i32 {
|
|||
return i32(state.source_font_height);
|
||||
}
|
||||
|
||||
draw :: proc(state_with_ui: ^StateWithUi) {
|
||||
buffer := &state_with_ui.state.buffers[state_with_ui.state.current_buffer];
|
||||
|
||||
buffer.glyph_buffer_height = math.min(256, int((state_with_ui.state.screen_height - state_with_ui.state.source_font_height*2) / state_with_ui.state.source_font_height)) + 1;
|
||||
buffer.glyph_buffer_width = math.min(256, int((state_with_ui.state.screen_width - state_with_ui.state.source_font_width) / state_with_ui.state.source_font_width));
|
||||
|
||||
// raylib.BeginDrawing();
|
||||
// defer raylib.EndDrawing();
|
||||
|
||||
render_color := theme.get_palette_color(.Background);
|
||||
sdl2.SetRenderDrawColor(state_with_ui.state.sdl_renderer, render_color.r, render_color.g, render_color.b, render_color.a);
|
||||
sdl2.RenderClear(state_with_ui.state.sdl_renderer);
|
||||
|
||||
// raylib.ClearBackground(theme.get_palette_raylib_color(.Background));
|
||||
|
||||
// core.draw_file_buffer(state_with_ui.state, buffer, 32, state_with_ui.state.source_font_height);
|
||||
|
||||
ui.compute_layout(state_with_ui.ui_context, { state_with_ui.state.screen_width, state_with_ui.state.screen_height }, state_with_ui.state.source_font_width, state_with_ui.state.source_font_height, state_with_ui.ui_context.root);
|
||||
ui.draw(state_with_ui.ui_context, state_with_ui.state, state_with_ui.state.source_font_width, state_with_ui.state.source_font_height, state_with_ui.ui_context.root);
|
||||
//ui.draw_menu_bar(&state_with_ui.state, &menu_bar_state_with_ui.state, 0, 0, i32(state_with_ui.state.screen_width), i32(state_with_ui.state.screen_height), state_with_ui.state.source_font_height);
|
||||
|
||||
//raylib.DrawRectangle(0, i32(state_with_ui.state.screen_height - state_with_ui.state.source_font_height), i32(state_with_ui.state.screen_width), i32(state_with_ui.state.source_font_height), theme.get_palette_raylib_color(.Background2));
|
||||
|
||||
if state_with_ui.state.window != nil && state_with_ui.state.window.draw != nil {
|
||||
state_with_ui.state.window.draw(state_with_ui.state.plugin_vtable, state_with_ui.state.window.user_data);
|
||||
}
|
||||
|
||||
if state_with_ui.state.current_input_map != &state_with_ui.state.input_map {
|
||||
longest_description := 0;
|
||||
for key, action in state_with_ui.state.current_input_map.key_actions {
|
||||
if len(action.description) > longest_description {
|
||||
longest_description = len(action.description);
|
||||
}
|
||||
}
|
||||
for key, action in state_with_ui.state.current_input_map.ctrl_key_actions {
|
||||
if len(action.description) > longest_description {
|
||||
longest_description = len(action.description);
|
||||
}
|
||||
}
|
||||
longest_description += 8;
|
||||
|
||||
helper_height := state_with_ui.state.source_font_height * (len(state_with_ui.state.current_input_map.key_actions) + len(state_with_ui.state.current_input_map.ctrl_key_actions));
|
||||
offset_from_bottom := state_with_ui.state.source_font_height * 2;
|
||||
|
||||
core.draw_rect(
|
||||
state_with_ui.state,
|
||||
state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width,
|
||||
state_with_ui.state.screen_height - helper_height - offset_from_bottom,
|
||||
longest_description*state_with_ui.state.source_font_width,
|
||||
helper_height,
|
||||
.Background2
|
||||
);
|
||||
//raylib.DrawRectangle(
|
||||
// i32(state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width),
|
||||
// i32(state_with_ui.state.screen_height - helper_height - offset_from_bottom),
|
||||
// i32(longest_description*state_with_ui.state.source_font_width),
|
||||
// i32(helper_height),
|
||||
// theme.get_palette_raylib_color(.Background2)
|
||||
//);
|
||||
|
||||
index := 0;
|
||||
for key, action in state_with_ui.state.current_input_map.key_actions {
|
||||
core.draw_text(
|
||||
state_with_ui.state,
|
||||
fmt.tprintf("%s - %s", key, action.description),
|
||||
state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width,
|
||||
state_with_ui.state.screen_height - helper_height + index * state_with_ui.state.source_font_height - offset_from_bottom
|
||||
);
|
||||
|
||||
// raylib.DrawTextEx(
|
||||
// state_with_ui.state.font,
|
||||
// raylib.TextFormat("%s - %s", key, action.description),
|
||||
// raylib.Vector2 { f32(state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width), f32(state_with_ui.state.screen_height - helper_height + index * state_with_ui.state.source_font_height - offset_from_bottom) },
|
||||
// f32(state_with_ui.state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Foreground1)
|
||||
// );
|
||||
index += 1;
|
||||
}
|
||||
for key, action in state_with_ui.state.current_input_map.ctrl_key_actions {
|
||||
core.draw_text(
|
||||
state_with_ui.state,
|
||||
fmt.tprintf("<C>-%s - %s", key, action.description),
|
||||
state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width,
|
||||
state_with_ui.state.screen_height - helper_height + index * state_with_ui.state.source_font_height - offset_from_bottom
|
||||
);
|
||||
// raylib.DrawTextEx(
|
||||
// state_with_ui.state.font,
|
||||
// raylib.TextFormat("<C>-%s - %s", key, action.description),
|
||||
// raylib.Vector2 { f32(state_with_ui.state.screen_width - longest_description * state_with_ui.state.source_font_width), f32(state_with_ui.state.screen_height - helper_height + index * state_with_ui.state.source_font_height - offset_from_bottom) },
|
||||
// f32(state_with_ui.state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Foreground1)
|
||||
// );
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
sdl2.RenderPresent(state_with_ui.state.sdl_renderer);
|
||||
}
|
||||
|
||||
// TODO: need to wrap state and ui context into one structure so that it can be used in this function
|
||||
expose_event_watcher :: proc "c" (state: rawptr, event: ^sdl2.Event) -> i32 {
|
||||
if event.type == .WINDOWEVENT {
|
||||
state := transmute(^StateWithUi)state;
|
||||
context = state.state.ctx;
|
||||
|
||||
if event.window.event == .EXPOSED {
|
||||
//draw(state);
|
||||
} else if event.window.event == .SIZE_CHANGED {
|
||||
w,h: i32;
|
||||
|
||||
sdl2.GetRendererOutputSize(state.state.sdl_renderer, &w, &h);
|
||||
|
||||
state.state.screen_width = int(w);
|
||||
state.state.screen_height = int(h);
|
||||
draw(state);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ui_file_buffer :: proc(ctx: ^ui.Context, buffer: ^FileBuffer) -> ui.Interaction {
|
||||
draw_func := proc(state: ^State, box: ^ui.Box, user_data: rawptr) {
|
||||
buffer := transmute(^FileBuffer)user_data;
|
||||
buffer.glyph_buffer_width = box.computed_size.x / state.source_font_width;
|
||||
buffer.glyph_buffer_height = box.computed_size.y / state.source_font_height + 1;
|
||||
|
||||
core.draw_file_buffer(state, buffer, box.computed_pos.x, box.computed_pos.y);
|
||||
};
|
||||
|
||||
relative_file_path, _ := filepath.rel(state.directory, buffer.file_path, context.temp_allocator)
|
||||
ui.push_parent(ctx, ui.push_box(ctx, relative_file_path, {}, .Vertical, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Fill, 0)}));
|
||||
defer ui.pop_parent(ctx);
|
||||
|
||||
interaction := ui.custom(ctx, "buffer1", draw_func, transmute(rawptr)buffer);
|
||||
|
||||
{
|
||||
ui.push_parent(ctx, ui.push_box(ctx, "buffer info", {}, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Exact, state.source_font_height)}));
|
||||
defer ui.pop_parent(ctx);
|
||||
|
||||
ui.label(ctx, relative_file_path);
|
||||
}
|
||||
|
||||
return interaction;
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
state = State {
|
||||
ctx = context,
|
||||
source_font_width = 8,
|
||||
source_font_height = 16,
|
||||
source_font_width = 8 + 2 * 3,
|
||||
source_font_height = 16 + 2 * 3,
|
||||
input_map = core.new_input_map(),
|
||||
window = nil,
|
||||
directory = os.get_current_directory(),
|
||||
|
@ -232,11 +388,6 @@ main :: proc() {
|
|||
hooks = make(map[plugin.Hook][dynamic]plugin.OnHookProc),
|
||||
};
|
||||
|
||||
ui_ctx := ui.Context {
|
||||
text_width = ui_font_width,
|
||||
text_height = ui_font_height,
|
||||
}
|
||||
|
||||
state.plugin_vtable = plugin.Plugin {
|
||||
state = cast(rawptr)&state,
|
||||
register_hook = proc "c" (hook: plugin.Hook, on_hook: plugin.OnHookProc) {
|
||||
|
@ -259,7 +410,6 @@ main :: proc() {
|
|||
context = state.ctx;
|
||||
|
||||
to_be_edited_map: ^core.InputMap = nil;
|
||||
key := raylib.KeyboardKey(int(key));
|
||||
|
||||
if input_map != nil {
|
||||
to_be_edited_map = transmute(^core.InputMap)input_map;
|
||||
|
@ -286,7 +436,6 @@ main :: proc() {
|
|||
context = state.ctx;
|
||||
|
||||
to_be_edited_map: ^core.InputMap = nil;
|
||||
key := raylib.KeyboardKey(int(key));
|
||||
description := strings.clone(string(description));
|
||||
|
||||
if input_map != nil {
|
||||
|
@ -362,21 +511,22 @@ main :: proc() {
|
|||
draw_rect = proc "c" (x: i32, y: i32, width: i32, height: i32, color: theme.PaletteColor) {
|
||||
context = state.ctx;
|
||||
|
||||
raylib.DrawRectangle(x, y, width, height, theme.get_palette_raylib_color(color));
|
||||
core.draw_rect(&state, int(x), int(y), int(width), int(height), color);
|
||||
//raylib.DrawRectangle(x, y, width, height, theme.get_palette_raylib_color(color));
|
||||
},
|
||||
draw_text = proc "c" (text: cstring, x: f32, y: f32, color: theme.PaletteColor) {
|
||||
context = state.ctx;
|
||||
|
||||
text := string(text);
|
||||
for codepoint, index in text {
|
||||
raylib.DrawTextCodepoint(
|
||||
state.font,
|
||||
rune(codepoint),
|
||||
raylib.Vector2 { x + f32(index * state.source_font_width), y },
|
||||
f32(state.source_font_height),
|
||||
theme.get_palette_raylib_color(color)
|
||||
);
|
||||
}
|
||||
core.draw_text(&state, string(text), int(x), int(y), color);
|
||||
// for codepoint, index in text {
|
||||
// raylib.DrawTextCodepoint(
|
||||
// state.font,
|
||||
// rune(codepoint),
|
||||
// raylib.Vector2 { x + f32(index * state.source_font_width), y },
|
||||
// f32(state.source_font_height),
|
||||
// theme.get_palette_raylib_color(color)
|
||||
// );
|
||||
// }
|
||||
},
|
||||
draw_buffer_from_index = proc "c" (buffer_index: int, x: int, y: int, glyph_buffer_width: int, glyph_buffer_height: int, show_line_numbers: bool) {
|
||||
context = state.ctx;
|
||||
|
@ -388,7 +538,6 @@ main :: proc() {
|
|||
&state.buffers[buffer_index],
|
||||
x,
|
||||
y,
|
||||
state.font,
|
||||
show_line_numbers);
|
||||
},
|
||||
draw_buffer = proc "c" (buffer: rawptr, x: int, y: int, glyph_buffer_width: int, glyph_buffer_height: int, show_line_numbers: bool) {
|
||||
|
@ -403,7 +552,6 @@ main :: proc() {
|
|||
buffer,
|
||||
x,
|
||||
y,
|
||||
state.font,
|
||||
show_line_numbers);
|
||||
},
|
||||
iter = plugin.Iterator {
|
||||
|
@ -730,15 +878,6 @@ main :: proc() {
|
|||
|
||||
runtime.append(&state.buffers, buffer);
|
||||
}
|
||||
buffer_items := make([dynamic]ui.MenuBarItem, 0, len(state.buffers));
|
||||
for buffer, index in state.buffers {
|
||||
item := ui.MenuBarItem {
|
||||
text = buffer.file_path,
|
||||
on_click = switch_to_buffer,
|
||||
};
|
||||
|
||||
runtime.append(&buffer_items, item);
|
||||
}
|
||||
|
||||
// Load plugins
|
||||
// TODO(pcleavelin): Get directory of binary instead of shells current working directory
|
||||
|
@ -750,245 +889,260 @@ main :: proc() {
|
|||
}
|
||||
}
|
||||
|
||||
raylib.InitWindow(640, 480, "odin_editor - [now with more ui]");
|
||||
raylib.SetWindowState({ .WINDOW_RESIZABLE, .VSYNC_HINT });
|
||||
raylib.SetTargetFPS(144);
|
||||
raylib.SetExitKey(.KEY_NULL);
|
||||
if sdl2.Init({.VIDEO}) < 0 {
|
||||
fmt.eprintln("SDL failed to initialize:", sdl2.GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if ttf.Init() < 0 {
|
||||
fmt.eprintln("SDL_TTF failed to initialize:", ttf.GetError());
|
||||
return;
|
||||
}
|
||||
defer ttf.Quit();
|
||||
|
||||
sdl_window := sdl2.CreateWindow(
|
||||
"odin_editor - [now with more ui]",
|
||||
sdl2.WINDOWPOS_UNDEFINED,
|
||||
0,
|
||||
640,
|
||||
480,
|
||||
{.SHOWN, .RESIZABLE, .METAL, .ALLOW_HIGHDPI}
|
||||
);
|
||||
defer if sdl_window != nil {
|
||||
sdl2.DestroyWindow(sdl_window);
|
||||
}
|
||||
|
||||
if sdl_window == nil {
|
||||
fmt.eprintln("Failed to create window:", sdl2.GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
state.sdl_renderer = sdl2.CreateRenderer(sdl_window, -1, {.ACCELERATED, .PRESENTVSYNC});
|
||||
defer if state.sdl_renderer != nil {
|
||||
sdl2.DestroyRenderer(state.sdl_renderer);
|
||||
}
|
||||
|
||||
if state.sdl_renderer == nil {
|
||||
fmt.eprintln("Failed to create renderer:", sdl2.GetError());
|
||||
return;
|
||||
}
|
||||
state.font_atlas = core.gen_font_atlas(&state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
|
||||
defer {
|
||||
if state.font_atlas.font != nil {
|
||||
ttf.CloseFont(state.font_atlas.font);
|
||||
}
|
||||
if state.font_atlas.texture != nil {
|
||||
sdl2.DestroyTexture(state.font_atlas.texture);
|
||||
}
|
||||
}
|
||||
|
||||
ui_context := ui.init(state.sdl_renderer);
|
||||
|
||||
sdl2.AddEventWatch(expose_event_watcher, &StateWithUi { &state, &ui_context });
|
||||
|
||||
// raylib.InitWindow(640, 480, "odin_editor - [now with more ui]");
|
||||
// raylib.SetWindowState({ .WINDOW_RESIZABLE, .VSYNC_HINT });
|
||||
// raylib.SetTargetFPS(144);
|
||||
// raylib.SetExitKey(.KEY_NULL);
|
||||
|
||||
// TODO: don't just hard code a MacOS font path
|
||||
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
|
||||
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
menu_bar_state := ui.MenuBarState{
|
||||
items = []ui.MenuBarItem {
|
||||
ui.MenuBarItem {
|
||||
text = "Buffers",
|
||||
sub_items = buffer_items[:],
|
||||
}
|
||||
}
|
||||
};
|
||||
// state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height), nil, 0);
|
||||
// raylib.SetTextureFilter(state.font.texture, .BILINEAR);
|
||||
|
||||
ui.init();
|
||||
|
||||
for !raylib.WindowShouldClose() && !state.should_close {
|
||||
state.screen_width = int(raylib.GetScreenWidth());
|
||||
state.screen_height = int(raylib.GetScreenHeight());
|
||||
mouse_pos := raylib.GetMousePosition();
|
||||
|
||||
buffer := &state.buffers[state.current_buffer];
|
||||
|
||||
buffer.glyph_buffer_height = math.min(256, int((state.screen_height - state.source_font_height*2) / state.source_font_height)) + 1;
|
||||
buffer.glyph_buffer_width = math.min(256, int((state.screen_width - state.source_font_width) / state.source_font_width));
|
||||
control_key_pressed: bool;
|
||||
|
||||
state.screen_width = 640; //int(raylib.GetScreenWidth());
|
||||
state.screen_height = 480; //int(raylib.GetScreenHeight());
|
||||
for !state.should_close {
|
||||
{
|
||||
raylib.BeginDrawing();
|
||||
defer raylib.EndDrawing();
|
||||
buffer := &state.buffers[state.current_buffer];
|
||||
|
||||
raylib.ClearBackground(theme.get_palette_raylib_color(.Background));
|
||||
|
||||
core.draw_file_buffer(&state, buffer, 32, state.source_font_height, state.font);
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "main", {}, .Vertical, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.PercentOfParent, 100)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
{
|
||||
ui.push_parent(ui.push_box("main", {}, .Vertical, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.PercentOfParent, 100)}));
|
||||
defer ui.pop_parent();
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "top_nav", {.DrawBackground}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Exact, state.source_font_height)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
{
|
||||
ui.push_parent(ui.push_box("top_nav", {.DrawBackground}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Exact, state.source_font_height)}));
|
||||
defer ui.pop_parent();
|
||||
|
||||
if ui.label("Editor").clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
|
||||
ui.push_box(
|
||||
"nav spacer",
|
||||
{.DrawBackground},
|
||||
semantic_size = {
|
||||
ui.make_semantic_size(.Exact, 16),
|
||||
ui.make_semantic_size(.Exact, state.source_font_height)
|
||||
}
|
||||
);
|
||||
|
||||
if ui.label("Buffers").clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
if ui.label(&ui_context, "Editor").clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
{
|
||||
ui.push_box("deezbuffer", {}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Fill, 0)});
|
||||
|
||||
ui.push_box(
|
||||
&ui_context,
|
||||
"nav spacer",
|
||||
{.DrawBackground},
|
||||
semantic_size = {
|
||||
ui.make_semantic_size(.Exact, 16),
|
||||
ui.make_semantic_size(.Exact, state.source_font_height)
|
||||
}
|
||||
);
|
||||
|
||||
if ui.label(&ui_context, "Buffers").clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
}
|
||||
{
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "deezbuffer", {}, .Horizontal, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Fill, 0)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
{
|
||||
ui.push_parent(ui.push_box("bottom stats", {.DrawBackground}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Exact, state.source_font_height)}));
|
||||
defer ui.pop_parent();
|
||||
|
||||
label := "";
|
||||
if state.mode == .Insert {
|
||||
label = "INSERT";
|
||||
} else if state.mode == .Normal {
|
||||
label = "NORMAL";
|
||||
}
|
||||
|
||||
if ui.button(label).clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
|
||||
ui.spacer("stats inbetween");
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "left side", {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Fill, 0)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
{
|
||||
ui.push_parent(ui.push_box("center info", {}, semantic_size = ui.ChildrenSum));
|
||||
defer ui.pop_parent();
|
||||
|
||||
line_info_text := raylib.TextFormat(
|
||||
//"Line: %d, Col: %d, Len: %d --- Slice Index: %d, Content Index: %d --- Frame Time: %fms",
|
||||
"Line: %d, Col: %d",
|
||||
buffer.cursor.line + 1,
|
||||
buffer.cursor.col + 1,
|
||||
//core.file_buffer_line_length(buffer, buffer.cursor.index),
|
||||
// buffer.cursor.index.slice_index,
|
||||
// buffer.cursor.index.content_index,
|
||||
);
|
||||
ui.label(string(line_info_text));
|
||||
if ui_file_buffer(&ui_context, &state.buffers[0]).clicked {
|
||||
state.current_buffer = 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
if ui_file_buffer(&ui_context, &state.buffers[0+1]).clicked {
|
||||
state.current_buffer = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
if ui_file_buffer(&ui_context, &state.buffers[0+2]).clicked {
|
||||
state.current_buffer = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "right side", {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Fill, 0)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
ui.spacer("frame time spacer");
|
||||
frame_time := (60.0/f32(raylib.GetFPS())) * 10;
|
||||
frame_time_text := raylib.TextFormat("frame time: %fms", frame_time);
|
||||
ui.label(string(frame_time_text));
|
||||
{
|
||||
if ui_file_buffer(&ui_context, &state.buffers[0+3]).clicked {
|
||||
state.current_buffer = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "bottom stats", {.DrawBackground}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 100), ui.make_semantic_size(.Exact, state.source_font_height)}));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
ui.compute_layout({ state.screen_width, state.screen_height }, state.source_font_width, state.source_font_height);
|
||||
label := "";
|
||||
if state.mode == .Insert {
|
||||
label = "INSERT";
|
||||
} else if state.mode == .Normal {
|
||||
label = "NORMAL";
|
||||
}
|
||||
|
||||
if ui.label(&ui_context, label).clicked {
|
||||
fmt.println("you clicked the button");
|
||||
}
|
||||
ui.spacer(&ui_context, "mode spacer", semantic_size = {ui.make_semantic_size(.Exact, 16), ui.make_semantic_size(.Fill)});
|
||||
|
||||
relative_file_path, _ := filepath.rel(state.directory, buffer.file_path, context.temp_allocator)
|
||||
ui.label(&ui_context, relative_file_path);
|
||||
|
||||
ui.draw(state.font, state.source_font_width, state.source_font_height);
|
||||
ui.prune();
|
||||
//ui.draw_menu_bar(&state, &menu_bar_state, 0, 0, i32(state.screen_width), i32(state.screen_height), state.source_font_height);
|
||||
ui.spacer(&ui_context, "stats inbetween");
|
||||
|
||||
//raylib.DrawRectangle(0, i32(state.screen_height - state.source_font_height), i32(state.screen_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Background2));
|
||||
{
|
||||
ui.push_parent(&ui_context, ui.push_box(&ui_context, "center info", {}, semantic_size = ui.ChildrenSum));
|
||||
defer ui.pop_parent(&ui_context);
|
||||
|
||||
line_info_text := raylib.TextFormat(
|
||||
// "Line: %d, Col: %d, Len: %d --- Slice Index: %d, Content Index: %d",
|
||||
"Line: %d, Col: %d",
|
||||
buffer.cursor.line + 1,
|
||||
buffer.cursor.col + 1,
|
||||
// core.file_buffer_line_length(buffer, buffer.cursor.index),
|
||||
// buffer.cursor.index.slice_index,
|
||||
// buffer.cursor.index.content_index
|
||||
);
|
||||
line_info_width := raylib.MeasureTextEx(state.font, line_info_text, f32(state.source_font_height), 0).x;
|
||||
line_info_text := fmt.tprintf(
|
||||
//"Line: %d, Col: %d, Len: %d --- Slice Index: %d, Content Index: %d",
|
||||
"Line: %d, Col: %d",
|
||||
buffer.cursor.line + 1,
|
||||
buffer.cursor.col + 1,
|
||||
//core.file_buffer_line_length(buffer, buffer.cursor.index),
|
||||
// buffer.cursor.index.slice_index,
|
||||
// buffer.cursor.index.content_index,
|
||||
);
|
||||
ui.label(&ui_context, line_info_text);
|
||||
|
||||
// switch state.mode {
|
||||
// case .Normal:
|
||||
// raylib.DrawRectangle(
|
||||
// 0,
|
||||
// i32(state.screen_height - state.source_font_height),
|
||||
// i32(8 + len("NORMAL")*state.source_font_width),
|
||||
// i32(state.source_font_height),
|
||||
// theme.get_palette_raylib_color(.Foreground4));
|
||||
// raylib.DrawRectangleV(
|
||||
// raylib.Vector2 { f32(state.screen_width) - line_info_width - 8, f32(state.screen_height - state.source_font_height) },
|
||||
// raylib.Vector2 { 8 + line_info_width, f32(state.source_font_height) },
|
||||
// theme.get_palette_raylib_color(.Foreground4));
|
||||
// raylib.DrawTextEx(
|
||||
// state.font,
|
||||
// "NORMAL",
|
||||
// raylib.Vector2 { 4, f32(state.screen_height - state.source_font_height) },
|
||||
// f32(state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Background1));
|
||||
// case .Insert:
|
||||
// raylib.DrawRectangle(
|
||||
// 0,
|
||||
// i32(state.screen_height - state.source_font_height),
|
||||
// i32(8 + len("INSERT")*state.source_font_width),
|
||||
// i32(state.source_font_height),
|
||||
// theme.get_palette_raylib_color(.Foreground2));
|
||||
// raylib.DrawRectangleV(
|
||||
// raylib.Vector2 { f32(state.screen_width) - line_info_width - 8, f32(state.screen_height - state.source_font_height) },
|
||||
// raylib.Vector2 { 8 + line_info_width, f32(state.source_font_height) },
|
||||
// theme.get_palette_raylib_color(.Foreground2));
|
||||
// raylib.DrawTextEx(
|
||||
// state.font,
|
||||
// "INSERT",
|
||||
// raylib.Vector2 { 4, f32(state.screen_height - state.source_font_height) },
|
||||
// f32(state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Background1));
|
||||
// }
|
||||
mouse_pos_str := fmt.tprintf("x,y: [%d,%d]", ui_context.mouse_x, ui_context.mouse_y);
|
||||
ui.label(&ui_context, mouse_pos_str);
|
||||
}
|
||||
|
||||
relative_file_path, _ := filepath.rel(state.directory, buffer.file_path)
|
||||
// raylib.DrawTextEx(
|
||||
// state.font,
|
||||
// raylib.TextFormat("%s", relative_file_path),
|
||||
// raylib.Vector2 { 8 + 4 + 6 * f32(state.source_font_width), f32(state.screen_height - state.source_font_height) },
|
||||
// f32(state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Foreground1));
|
||||
// raylib.DrawTextEx(
|
||||
// state.font,
|
||||
// line_info_text,
|
||||
// raylib.Vector2 { f32(state.screen_width) - line_info_width - 4, f32(state.screen_height - state.source_font_height) },
|
||||
// f32(state.source_font_height),
|
||||
// 0,
|
||||
// theme.get_palette_raylib_color(.Background1));
|
||||
|
||||
if state.window != nil && state.window.draw != nil {
|
||||
state.window.draw(state.plugin_vtable, state.window.user_data);
|
||||
//ui.spacer(&ui_context, "frame time spacer");
|
||||
//frame_time := (60.0/f32(raylib.GetFPS())) * 10;
|
||||
//frame_time_text := raylib.TextFormat("frame time: %fms", frame_time);
|
||||
//ui.label(&ui_context, "lol have to figure out how to get the frame time");
|
||||
}
|
||||
}
|
||||
|
||||
if state.current_input_map != &state.input_map {
|
||||
longest_description := 0;
|
||||
for key, action in state.current_input_map.key_actions {
|
||||
if len(action.description) > longest_description {
|
||||
longest_description = len(action.description);
|
||||
{
|
||||
ui_context.last_mouse_left_down = ui_context.mouse_left_down;
|
||||
ui_context.last_mouse_right_down = ui_context.mouse_right_down;
|
||||
|
||||
sdl_event: sdl2.Event;
|
||||
for(sdl2.PollEvent(&sdl_event)) {
|
||||
if sdl_event.type == .QUIT {
|
||||
state.should_close = true;
|
||||
}
|
||||
|
||||
if sdl_event.type == .MOUSEMOTION {
|
||||
ui_context.mouse_x = int(sdl_event.motion.x);
|
||||
ui_context.mouse_y = int(sdl_event.motion.y);
|
||||
}
|
||||
|
||||
if sdl_event.type == .MOUSEBUTTONDOWN || sdl_event.type == .MOUSEBUTTONUP {
|
||||
event := sdl_event.button;
|
||||
|
||||
if event.button == sdl2.BUTTON_LEFT {
|
||||
ui_context.mouse_left_down = sdl_event.type == .MOUSEBUTTONDOWN;
|
||||
}
|
||||
if event.button == sdl2.BUTTON_RIGHT {
|
||||
ui_context.mouse_left_down = sdl_event.type == .MOUSEBUTTONDOWN;
|
||||
}
|
||||
}
|
||||
for key, action in state.current_input_map.ctrl_key_actions {
|
||||
if len(action.description) > longest_description {
|
||||
longest_description = len(action.description);
|
||||
|
||||
if sdl_event.type == .KEYDOWN {
|
||||
key := plugin.Key(sdl_event.key.keysym.sym);
|
||||
if key == .LCTRL {
|
||||
control_key_pressed = true;
|
||||
} else if state.current_input_map != nil {
|
||||
if control_key_pressed {
|
||||
if action, exists := state.current_input_map.ctrl_key_actions[key]; exists {
|
||||
switch value in action.action {
|
||||
case core.PluginEditorAction:
|
||||
value(state.plugin_vtable);
|
||||
case core.EditorAction:
|
||||
value(&state);
|
||||
case core.InputMap:
|
||||
state.current_input_map = &(&state.current_input_map.ctrl_key_actions[key]).action.(core.InputMap)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if action, exists := state.current_input_map.key_actions[key]; exists {
|
||||
switch value in action.action {
|
||||
case core.PluginEditorAction:
|
||||
value(state.plugin_vtable);
|
||||
case core.EditorAction:
|
||||
value(&state);
|
||||
case core.InputMap:
|
||||
state.current_input_map = &(&state.current_input_map.key_actions[key]).action.(core.InputMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
longest_description += 8;
|
||||
|
||||
helper_height := state.source_font_height * (len(state.current_input_map.key_actions) + len(state.current_input_map.ctrl_key_actions));
|
||||
offset_from_bottom := state.source_font_height * 2;
|
||||
|
||||
raylib.DrawRectangle(
|
||||
i32(state.screen_width - longest_description * state.source_font_width),
|
||||
i32(state.screen_height - helper_height - offset_from_bottom),
|
||||
i32(longest_description*state.source_font_width),
|
||||
i32(helper_height),
|
||||
theme.get_palette_raylib_color(.Background2));
|
||||
|
||||
index := 0;
|
||||
for key, action in state.current_input_map.key_actions {
|
||||
raylib.DrawTextEx(
|
||||
state.font,
|
||||
raylib.TextFormat("%s - %s", key, action.description),
|
||||
raylib.Vector2 { f32(state.screen_width - longest_description * state.source_font_width), f32(state.screen_height - helper_height + index * state.source_font_height - offset_from_bottom) },
|
||||
f32(state.source_font_height),
|
||||
0,
|
||||
theme.get_palette_raylib_color(.Foreground1));
|
||||
index += 1;
|
||||
}
|
||||
for key, action in state.current_input_map.ctrl_key_actions {
|
||||
raylib.DrawTextEx(
|
||||
state.font,
|
||||
raylib.TextFormat("<C>-%s - %s", key, action.description),
|
||||
raylib.Vector2 { f32(state.screen_width - longest_description * state.source_font_width), f32(state.screen_height - helper_height + index * state.source_font_height - offset_from_bottom) },
|
||||
f32(state.source_font_height),
|
||||
0,
|
||||
theme.get_palette_raylib_color(.Foreground1));
|
||||
index += 1;
|
||||
if sdl_event.type == .KEYUP {
|
||||
key := plugin.Key(sdl_event.key.keysym.sym);
|
||||
if key == .LCTRL {
|
||||
control_key_pressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ui.debug_print();
|
||||
|
||||
draw(&StateWithUi { &state, &ui_context });
|
||||
|
||||
ui.prune(&ui_context);
|
||||
|
||||
switch state.mode {
|
||||
case .Normal:
|
||||
if state.window != nil && state.window.get_buffer != nil {
|
||||
buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data));
|
||||
do_normal_mode(&state, buffer);
|
||||
} else {
|
||||
buffer := &state.buffers[state.current_buffer];
|
||||
do_normal_mode(&state, buffer);
|
||||
}
|
||||
case .Insert:
|
||||
|
@ -996,6 +1150,7 @@ main :: proc() {
|
|||
buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data));
|
||||
do_insert_mode(&state, buffer);
|
||||
} else {
|
||||
buffer := &state.buffers[state.current_buffer];
|
||||
do_insert_mode(&state, buffer);
|
||||
}
|
||||
}
|
||||
|
@ -1005,8 +1160,6 @@ main :: proc() {
|
|||
core.close_window_and_free(&state);
|
||||
}
|
||||
|
||||
ui.test_menu_bar(&state, &menu_bar_state, 0,0, mouse_pos, raylib.IsMouseButtonReleased(.LEFT), state.source_font_height);
|
||||
|
||||
runtime.free_all(context.temp_allocator);
|
||||
}
|
||||
|
||||
|
@ -1015,4 +1168,6 @@ main :: proc() {
|
|||
plugin.on_exit();
|
||||
}
|
||||
}
|
||||
|
||||
sdl2.Quit();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package plugin;
|
|||
import "core:intrinsics"
|
||||
import "core:dynlib"
|
||||
import "core:fmt"
|
||||
import "vendor:raylib"
|
||||
|
||||
import "../theme"
|
||||
|
||||
|
@ -127,120 +126,246 @@ Hook :: enum {
|
|||
}
|
||||
|
||||
Key :: enum {
|
||||
KEY_NULL = 0, // Key: NULL, used for no key pressed
|
||||
// Alphanumeric keys
|
||||
APOSTROPHE = 39, // Key: '
|
||||
COMMA = 44, // Key: ,
|
||||
MINUS = 45, // Key: -
|
||||
PERIOD = 46, // Key: .
|
||||
SLASH = 47, // Key: /
|
||||
ZERO = 48, // Key: 0
|
||||
ONE = 49, // Key: 1
|
||||
TWO = 50, // Key: 2
|
||||
THREE = 51, // Key: 3
|
||||
FOUR = 52, // Key: 4
|
||||
FIVE = 53, // Key: 5
|
||||
SIX = 54, // Key: 6
|
||||
SEVEN = 55, // Key: 7
|
||||
EIGHT = 56, // Key: 8
|
||||
NINE = 57, // Key: 9
|
||||
SEMICOLON = 59, // Key: ;
|
||||
EQUAL = 61, // Key: =
|
||||
A = 65, // Key: A | a
|
||||
B = 66, // Key: B | b
|
||||
C = 67, // Key: C | c
|
||||
D = 68, // Key: D | d
|
||||
E = 69, // Key: E | e
|
||||
F = 70, // Key: F | f
|
||||
G = 71, // Key: G | g
|
||||
H = 72, // Key: H | h
|
||||
I = 73, // Key: I | i
|
||||
J = 74, // Key: J | j
|
||||
K = 75, // Key: K | k
|
||||
L = 76, // Key: L | l
|
||||
M = 77, // Key: M | m
|
||||
N = 78, // Key: N | n
|
||||
O = 79, // Key: O | o
|
||||
P = 80, // Key: P | p
|
||||
Q = 81, // Key: Q | q
|
||||
R = 82, // Key: R | r
|
||||
S = 83, // Key: S | s
|
||||
T = 84, // Key: T | t
|
||||
U = 85, // Key: U | u
|
||||
V = 86, // Key: V | v
|
||||
W = 87, // Key: W | w
|
||||
X = 88, // Key: X | x
|
||||
Y = 89, // Key: Y | y
|
||||
Z = 90, // Key: Z | z
|
||||
LEFT_BRACKET = 91, // Key: [
|
||||
BACKSLASH = 92, // Key: '\'
|
||||
RIGHT_BRACKET = 93, // Key: ]
|
||||
GRAVE = 96, // Key: `
|
||||
// Function keys
|
||||
SPACE = 32, // Key: Space
|
||||
ESCAPE = 256, // Key: Esc
|
||||
ENTER = 257, // Key: Enter
|
||||
TAB = 258, // Key: Tab
|
||||
BACKSPACE = 259, // Key: Backspace
|
||||
INSERT = 260, // Key: Ins
|
||||
DELETE = 261, // Key: Del
|
||||
RIGHT = 262, // Key: Cursor right
|
||||
LEFT = 263, // Key: Cursor left
|
||||
DOWN = 264, // Key: Cursor down
|
||||
UP = 265, // Key: Cursor up
|
||||
PAGE_UP = 266, // Key: Page up
|
||||
PAGE_DOWN = 267, // Key: Page down
|
||||
HOME = 268, // Key: Home
|
||||
END = 269, // Key: End
|
||||
CAPS_LOCK = 280, // Key: Caps lock
|
||||
SCROLL_LOCK = 281, // Key: Scroll down
|
||||
NUM_LOCK = 282, // Key: Num lock
|
||||
PRINT_SCREEN = 283, // Key: Print screen
|
||||
PAUSE = 284, // Key: Pause
|
||||
F1 = 290, // Key: F1
|
||||
F2 = 291, // Key: F2
|
||||
F3 = 292, // Key: F3
|
||||
F4 = 293, // Key: F4
|
||||
F5 = 294, // Key: F5
|
||||
F6 = 295, // Key: F6
|
||||
F7 = 296, // Key: F7
|
||||
F8 = 297, // Key: F8
|
||||
F9 = 298, // Key: F9
|
||||
F10 = 299, // Key: F10
|
||||
F11 = 300, // Key: F11
|
||||
F12 = 301, // Key: F12
|
||||
LEFT_SHIFT = 340, // Key: Shift left
|
||||
LEFT_CONTROL = 341, // Key: Control left
|
||||
LEFT_ALT = 342, // Key: Alt left
|
||||
LEFT_SUPER = 343, // Key: Super left
|
||||
RIGHT_SHIFT = 344, // Key: Shift right
|
||||
RIGHT_CONTROL = 345, // Key: Control right
|
||||
RIGHT_ALT = 346, // Key: Alt right
|
||||
RIGHT_SUPER = 347, // Key: Super right
|
||||
KB_MENU = 348, // Key: KB menu
|
||||
// Keypad keys
|
||||
KP_0 = 320, // Key: Keypad 0
|
||||
KP_1 = 321, // Key: Keypad 1
|
||||
KP_2 = 322, // Key: Keypad 2
|
||||
KP_3 = 323, // Key: Keypad 3
|
||||
KP_4 = 324, // Key: Keypad 4
|
||||
KP_5 = 325, // Key: Keypad 5
|
||||
KP_6 = 326, // Key: Keypad 6
|
||||
KP_7 = 327, // Key: Keypad 7
|
||||
KP_8 = 328, // Key: Keypad 8
|
||||
KP_9 = 329, // Key: Keypad 9
|
||||
KP_DECIMAL = 330, // Key: Keypad .
|
||||
KP_DIVIDE = 331, // Key: Keypad /
|
||||
KP_MULTIPLY = 332, // Key: Keypad *
|
||||
KP_SUBTRACT = 333, // Key: Keypad -
|
||||
KP_ADD = 334, // Key: Keypad +
|
||||
KP_ENTER = 335, // Key: Keypad Enter
|
||||
KP_EQUAL = 336, // Key: Keypad =
|
||||
// Android key buttons
|
||||
BACK = 4, // Key: Android back button
|
||||
MENU = 82, // Key: Android menu button
|
||||
VOLUME_UP = 24, // Key: Android volume up button
|
||||
VOLUME_DOWN = 25, // Key: Android volume down button
|
||||
UNKNOWN = 0,
|
||||
ENTER = 13,
|
||||
ESCAPE = 27,
|
||||
BACKSPACE = 8,
|
||||
TAB = 9,
|
||||
SPACE = 32,
|
||||
EXCLAIM = 33,
|
||||
QUOTEDBL = 34,
|
||||
HASH = 35,
|
||||
PERCENT = 37,
|
||||
DOLLAR = 36,
|
||||
AMPERSAND = 38,
|
||||
QUOTE = 39,
|
||||
LEFTPAREN = 40,
|
||||
RIGHTPAREN = 41,
|
||||
ASTERISK = 42,
|
||||
PLUS = 43,
|
||||
COMMA = 44,
|
||||
MINUS = 45,
|
||||
PERIOD = 46,
|
||||
SLASH = 47,
|
||||
NUM0 = 48,
|
||||
NUM1 = 49,
|
||||
NUM2 = 50,
|
||||
NUM3 = 51,
|
||||
NUM4 = 52,
|
||||
NUM5 = 53,
|
||||
NUM6 = 54,
|
||||
NUM7 = 55,
|
||||
NUM8 = 56,
|
||||
NUM9 = 57,
|
||||
COLON = 58,
|
||||
SEMICOLON = 59,
|
||||
LESS = 60,
|
||||
EQUAL = 61,
|
||||
GREATER = 62,
|
||||
QUESTION = 63,
|
||||
AT = 64,
|
||||
LEFTBRACKET = 91,
|
||||
BACKSLASH = 92,
|
||||
RIGHTBRACKET = 93,
|
||||
CARET = 94,
|
||||
UNDERSCORE = 95,
|
||||
BACKQUOTE = 96,
|
||||
A = 97,
|
||||
B = 98,
|
||||
C = 99,
|
||||
D = 100,
|
||||
E = 101,
|
||||
F = 102,
|
||||
G = 103,
|
||||
H = 104,
|
||||
I = 105,
|
||||
J = 106,
|
||||
K = 107,
|
||||
L = 108,
|
||||
M = 109,
|
||||
N = 110,
|
||||
O = 111,
|
||||
P = 112,
|
||||
Q = 113,
|
||||
R = 114,
|
||||
S = 115,
|
||||
T = 116,
|
||||
U = 117,
|
||||
V = 118,
|
||||
W = 119,
|
||||
X = 120,
|
||||
Y = 121,
|
||||
Z = 122,
|
||||
CAPSLOCK = 1073741881,
|
||||
F1 = 1073741882,
|
||||
F2 = 1073741883,
|
||||
F3 = 1073741884,
|
||||
F4 = 1073741885,
|
||||
F5 = 1073741886,
|
||||
F6 = 1073741887,
|
||||
F7 = 1073741888,
|
||||
F8 = 1073741889,
|
||||
F9 = 1073741890,
|
||||
F10 = 1073741891,
|
||||
F11 = 1073741892,
|
||||
F12 = 1073741893,
|
||||
PRINTSCREEN = 1073741894,
|
||||
SCROLLLOCK = 1073741895,
|
||||
PAUSE = 1073741896,
|
||||
INSERT = 1073741897,
|
||||
HOME = 1073741898,
|
||||
PAGEUP = 1073741899,
|
||||
DELETE = 127,
|
||||
END = 1073741901,
|
||||
PAGEDOWN = 1073741902,
|
||||
RIGHT = 1073741903,
|
||||
LEFT = 1073741904,
|
||||
DOWN = 1073741905,
|
||||
UP = 1073741906,
|
||||
NUMLOCKCLEAR = 1073741907,
|
||||
KP_DIVIDE = 1073741908,
|
||||
KP_MULTIPLY = 1073741909,
|
||||
KP_MINUS = 1073741910,
|
||||
KP_PLUS = 1073741911,
|
||||
KP_ENTER = 1073741912,
|
||||
KP_1 = 1073741913,
|
||||
KP_2 = 1073741914,
|
||||
KP_3 = 1073741915,
|
||||
KP_4 = 1073741916,
|
||||
KP_5 = 1073741917,
|
||||
KP_6 = 1073741918,
|
||||
KP_7 = 1073741919,
|
||||
KP_8 = 1073741920,
|
||||
KP_9 = 1073741921,
|
||||
KP_0 = 1073741922,
|
||||
KP_PERIOD = 1073741923,
|
||||
APPLICATION = 1073741925,
|
||||
POWER = 1073741926,
|
||||
KP_EQUALS = 1073741927,
|
||||
F13 = 1073741928,
|
||||
F14 = 1073741929,
|
||||
F15 = 1073741930,
|
||||
F16 = 1073741931,
|
||||
F17 = 1073741932,
|
||||
F18 = 1073741933,
|
||||
F19 = 1073741934,
|
||||
F20 = 1073741935,
|
||||
F21 = 1073741936,
|
||||
F22 = 1073741937,
|
||||
F23 = 1073741938,
|
||||
F24 = 1073741939,
|
||||
EXECUTE = 1073741940,
|
||||
HELP = 1073741941,
|
||||
MENU = 1073741942,
|
||||
SELECT = 1073741943,
|
||||
STOP = 1073741944,
|
||||
AGAIN = 1073741945,
|
||||
UNDO = 1073741946,
|
||||
CUT = 1073741947,
|
||||
COPY = 1073741948,
|
||||
PASTE = 1073741949,
|
||||
FIND = 1073741950,
|
||||
MUTE = 1073741951,
|
||||
VOLUMEUP = 1073741952,
|
||||
VOLUMEDOWN = 1073741953,
|
||||
KP_COMMA = 1073741957,
|
||||
KP_EQUALSAS400 = 1073741958,
|
||||
ALTERASE = 1073741977,
|
||||
SYSREQ = 1073741978,
|
||||
CANCEL = 1073741979,
|
||||
CLEAR = 1073741980,
|
||||
PRIOR = 1073741981,
|
||||
RETURN2 = 1073741982,
|
||||
SEPARATOR = 1073741983,
|
||||
OUT = 1073741984,
|
||||
OPER = 1073741985,
|
||||
CLEARAGAIN = 1073741986,
|
||||
CRSEL = 1073741987,
|
||||
EXSEL = 1073741988,
|
||||
KP_00 = 1073742000,
|
||||
KP_000 = 1073742001,
|
||||
THOUSANDSSEPARATOR = 1073742002,
|
||||
DECIMALSEPARATOR = 1073742003,
|
||||
CURRENCYUNIT = 1073742004,
|
||||
CURRENCYSUBUNIT = 1073742005,
|
||||
KP_LEFTPAREN = 1073742006,
|
||||
KP_RIGHTPAREN = 1073742007,
|
||||
KP_LEFTBRACE = 1073742008,
|
||||
KP_RIGHTBRACE = 1073742009,
|
||||
KP_TAB = 1073742010,
|
||||
KP_BACKSPACE = 1073742011,
|
||||
KP_A = 1073742012,
|
||||
KP_B = 1073742013,
|
||||
KP_C = 1073742014,
|
||||
KP_D = 1073742015,
|
||||
KP_E = 1073742016,
|
||||
KP_F = 1073742017,
|
||||
KP_XOR = 1073742018,
|
||||
KP_POWER = 1073742019,
|
||||
KP_PERCENT = 1073742020,
|
||||
KP_LESS = 1073742021,
|
||||
KP_GREATER = 1073742022,
|
||||
KP_AMPERSAND = 1073742023,
|
||||
KP_DBLAMPERSAND = 1073742024,
|
||||
KP_VERTICALBAR = 1073742025,
|
||||
KP_DBLVERTICALBAR = 1073742026,
|
||||
KP_COLON = 1073742027,
|
||||
KP_HASH = 1073742028,
|
||||
KP_SPACE = 1073742029,
|
||||
KP_AT = 1073742030,
|
||||
KP_EXCLAM = 1073742031,
|
||||
KP_MEMSTORE = 1073742032,
|
||||
KP_MEMRECALL = 1073742033,
|
||||
KP_MEMCLEAR = 1073742034,
|
||||
KP_MEMADD = 1073742035,
|
||||
KP_MEMSUBTRACT = 1073742036,
|
||||
KP_MEMMULTIPLY = 1073742037,
|
||||
KP_MEMDIVIDE = 1073742038,
|
||||
KP_PLUSMINUS = 1073742039,
|
||||
KP_CLEAR = 1073742040,
|
||||
KP_CLEARENTRY = 1073742041,
|
||||
KP_BINARY = 1073742042,
|
||||
KP_OCTAL = 1073742043,
|
||||
KP_DECIMAL = 1073742044,
|
||||
KP_HEXADECIMAL = 1073742045,
|
||||
LCTRL = 1073742048,
|
||||
LSHIFT = 1073742049,
|
||||
LALT = 1073742050,
|
||||
LGUI = 1073742051,
|
||||
RCTRL = 1073742052,
|
||||
RSHIFT = 1073742053,
|
||||
RALT = 1073742054,
|
||||
RGUI = 1073742055,
|
||||
MODE = 1073742081,
|
||||
AUDIONEXT = 1073742082,
|
||||
AUDIOPREV = 1073742083,
|
||||
AUDIOSTOP = 1073742084,
|
||||
AUDIOPLAY = 1073742085,
|
||||
AUDIOMUTE = 1073742086,
|
||||
MEDIASELECT = 1073742087,
|
||||
WWW = 1073742088,
|
||||
MAIL = 1073742089,
|
||||
CALCULATOR = 1073742090,
|
||||
COMPUTER = 1073742091,
|
||||
AC_SEARCH = 1073742092,
|
||||
AC_HOME = 1073742093,
|
||||
AC_BACK = 1073742094,
|
||||
AC_FORWARD = 1073742095,
|
||||
AC_STOP = 1073742096,
|
||||
AC_REFRESH = 1073742097,
|
||||
AC_BOOKMARKS = 1073742098,
|
||||
BRIGHTNESSDOWN = 1073742099,
|
||||
BRIGHTNESSUP = 1073742100,
|
||||
DISPLAYSWITCH = 1073742101,
|
||||
KBDILLUMTOGGLE = 1073742102,
|
||||
KBDILLUMDOWN = 1073742103,
|
||||
KBDILLUMUP = 1073742104,
|
||||
EJECT = 1073742105,
|
||||
SLEEP = 1073742106,
|
||||
APP1 = 1073742107,
|
||||
APP2 = 1073742108,
|
||||
AUDIOREWIND = 1073742109,
|
||||
AUDIOFASTFORWARD = 1073742110,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package theme
|
||||
|
||||
import "vendor:raylib"
|
||||
|
||||
PaletteColor :: enum {
|
||||
Background,
|
||||
Foreground,
|
||||
|
@ -97,7 +95,14 @@ light_palette := []u32 {
|
|||
0x928374ff,
|
||||
};
|
||||
|
||||
get_palette_raylib_color :: proc(palette_color: PaletteColor) -> raylib.Color {
|
||||
return raylib.GetColor(palette[palette_color]);
|
||||
get_palette_color :: proc(palette_color: PaletteColor) -> [4]u8 {
|
||||
color: [4]u8;
|
||||
|
||||
c := palette[palette_color];
|
||||
for i in 0..<4 {
|
||||
color[i] = u8((c >> (8*u32(3-i)))&0xff);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
479
src/ui/imm.odin
479
src/ui/imm.odin
|
@ -3,22 +3,30 @@ package ui
|
|||
import "core:fmt"
|
||||
import "core:strings"
|
||||
import "core:math"
|
||||
import "vendor:raylib"
|
||||
import "vendor:sdl2"
|
||||
|
||||
import "../core"
|
||||
import "../theme"
|
||||
|
||||
Context :: struct {
|
||||
text_width: proc() -> i32,
|
||||
text_height: proc() -> i32,
|
||||
root: ^Box,
|
||||
current_parent: ^Box,
|
||||
persistent: map[Key]^Box,
|
||||
current_interaction_index: int,
|
||||
|
||||
clips: [dynamic]Rect,
|
||||
renderer: ^sdl2.Renderer,
|
||||
|
||||
mouse_x: int,
|
||||
mouse_y: int,
|
||||
|
||||
mouse_left_down: bool,
|
||||
last_mouse_left_down: bool,
|
||||
|
||||
mouse_right_down: bool,
|
||||
last_mouse_right_down: bool,
|
||||
}
|
||||
|
||||
root: ^Box = nil;
|
||||
current_parent: ^Box = nil;
|
||||
persistent: map[Key]^Box = nil;
|
||||
current_interaction_index: int = 0;
|
||||
|
||||
clips: [dynamic]Rect = nil;
|
||||
|
||||
Rect :: struct {
|
||||
pos: [2]int,
|
||||
size: [2]int,
|
||||
|
@ -30,6 +38,7 @@ Key :: struct {
|
|||
}
|
||||
|
||||
Interaction :: struct {
|
||||
hovering: bool,
|
||||
clicked: bool,
|
||||
}
|
||||
|
||||
|
@ -40,6 +49,7 @@ Flag :: enum {
|
|||
DrawText,
|
||||
DrawBorder,
|
||||
DrawBackground,
|
||||
CustomDrawFunc,
|
||||
}
|
||||
|
||||
SemanticSizeKind :: enum {
|
||||
|
@ -60,6 +70,7 @@ Axis :: enum {
|
|||
Vertical = 1,
|
||||
}
|
||||
|
||||
CustomDrawFunc :: proc(state: ^core.State, box: ^Box, user_data: rawptr);
|
||||
Box :: struct {
|
||||
first: ^Box,
|
||||
last: ^Box,
|
||||
|
@ -77,30 +88,36 @@ Box :: struct {
|
|||
axis: Axis,
|
||||
semantic_size: [2]SemanticSize,
|
||||
computed_size: [2]int,
|
||||
computed_pos: [2]int,
|
||||
|
||||
computed_pos: [2]int
|
||||
hot: int,
|
||||
active: int,
|
||||
|
||||
custom_draw_func: CustomDrawFunc,
|
||||
user_data: rawptr,
|
||||
}
|
||||
|
||||
init :: proc() {
|
||||
if persistent == nil {
|
||||
persistent = make(map[Key]^Box);
|
||||
}
|
||||
init :: proc(renderer: ^sdl2.Renderer) -> Context {
|
||||
root := new(Box);
|
||||
root.key = gen_key(nil, "root", 69);
|
||||
|
||||
if clips == nil {
|
||||
clips = make([dynamic]Rect);
|
||||
}
|
||||
|
||||
root = new(Box);
|
||||
root.key = gen_key("root", 69);
|
||||
current_parent = root;
|
||||
return Context {
|
||||
root = root,
|
||||
current_parent = root,
|
||||
persistent = make(map[Key]^Box),
|
||||
clips = make([dynamic]Rect),
|
||||
renderer = renderer,
|
||||
};
|
||||
}
|
||||
|
||||
gen_key :: proc(label: string, value: int) -> Key {
|
||||
gen_key :: proc(ctx: ^Context, label: string, value: int) -> Key {
|
||||
key_label := ""
|
||||
if current_parent == nil || len(current_parent.key.label) < 1 {
|
||||
if ctx != nil && (ctx.current_parent == nil || len(ctx.current_parent.key.label) < 1) {
|
||||
key_label = strings.clone(label);
|
||||
} else if ctx != nil {
|
||||
key_label = fmt.aprintf("%s:%s", ctx.current_parent.key.label, label);
|
||||
} else {
|
||||
key_label = fmt.aprintf("%s:%s", current_parent.key.label, label);
|
||||
key_label = fmt.aprintf("%s",label);
|
||||
}
|
||||
|
||||
return Key {
|
||||
|
@ -109,22 +126,22 @@ gen_key :: proc(label: string, value: int) -> Key {
|
|||
};
|
||||
}
|
||||
|
||||
make_box :: proc(key: Key, label: string, flags: bit_set[Flag], axis: Axis, semantic_size: [2]SemanticSize) -> ^Box {
|
||||
make_box :: proc(ctx: ^Context, key: Key, label: string, flags: bit_set[Flag], axis: Axis, semantic_size: [2]SemanticSize) -> ^Box {
|
||||
box: ^Box = nil;
|
||||
|
||||
if cached_box, exists := persistent[key]; exists {
|
||||
if cached_box.last_interacted_index < current_interaction_index {
|
||||
old_cached_box := persistent[key];
|
||||
if cached_box, exists := ctx.persistent[key]; exists {
|
||||
if cached_box.last_interacted_index < ctx.current_interaction_index {
|
||||
old_cached_box := ctx.persistent[key];
|
||||
free(old_cached_box);
|
||||
box = new(Box);
|
||||
|
||||
persistent[key] = box;
|
||||
ctx.persistent[key] = box;
|
||||
} else {
|
||||
box = cached_box;
|
||||
}
|
||||
} else {
|
||||
box = new(Box);
|
||||
persistent[key] = box;
|
||||
ctx.persistent[key] = box;
|
||||
}
|
||||
|
||||
box.key = key;
|
||||
|
@ -133,22 +150,20 @@ make_box :: proc(key: Key, label: string, flags: bit_set[Flag], axis: Axis, sema
|
|||
box.first = nil;
|
||||
box.last = nil;
|
||||
box.next = nil;
|
||||
box.prev = current_parent.last;
|
||||
box.parent = current_parent;
|
||||
box.prev = ctx.current_parent.last;
|
||||
box.parent = ctx.current_parent;
|
||||
box.flags = flags;
|
||||
box.axis = axis;
|
||||
box.semantic_size = semantic_size;
|
||||
box.computed_pos = {};
|
||||
box.computed_size = {};
|
||||
|
||||
if current_parent.last != nil {
|
||||
current_parent.last.next = box;
|
||||
if ctx.current_parent.last != nil {
|
||||
ctx.current_parent.last.next = box;
|
||||
}
|
||||
if current_parent.first == nil {
|
||||
current_parent.first = box;
|
||||
if ctx.current_parent.first == nil {
|
||||
ctx.current_parent.first = box;
|
||||
}
|
||||
|
||||
current_parent.last = box;
|
||||
ctx.current_parent.last = box;
|
||||
|
||||
return box;
|
||||
}
|
||||
|
@ -178,67 +193,89 @@ ChildrenSum :[2]SemanticSize: {
|
|||
}
|
||||
};
|
||||
|
||||
push_box :: proc(label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText, value: int = 0) -> ^Box {
|
||||
key := gen_key(label, value);
|
||||
box := make_box(key, label, flags, axis, semantic_size);
|
||||
push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText, value: int = 0) -> ^Box {
|
||||
key := gen_key(ctx, label, value);
|
||||
box := make_box(ctx, key, label, flags, axis, semantic_size);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
push_parent :: proc(box: ^Box) {
|
||||
current_parent = box;
|
||||
push_parent :: proc(ctx: ^Context, box: ^Box) {
|
||||
ctx.current_parent = box;
|
||||
}
|
||||
|
||||
pop_parent :: proc() {
|
||||
if current_parent.parent != nil {
|
||||
current_parent = current_parent.parent;
|
||||
pop_parent :: proc(ctx: ^Context) {
|
||||
if ctx.current_parent.parent != nil {
|
||||
ctx.current_parent = ctx.current_parent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
test_box :: proc(box: ^Box) -> Interaction {
|
||||
test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction {
|
||||
hovering: bool;
|
||||
|
||||
mouse_is_clicked := !ctx.last_mouse_left_down && ctx.mouse_left_down;
|
||||
|
||||
if ctx.mouse_x >= box.computed_pos.x && ctx.mouse_x <= box.computed_pos.x + box.computed_size.x &&
|
||||
ctx.mouse_y >= box.computed_pos.y && ctx.mouse_y <= box.computed_pos.y + box.computed_size.y
|
||||
{
|
||||
hovering = true;
|
||||
}
|
||||
|
||||
if hovering {
|
||||
box.hot += 1;
|
||||
} else {
|
||||
box.hot = 0;
|
||||
}
|
||||
|
||||
if hovering && mouse_is_clicked {
|
||||
fmt.println("hot", box.hot);
|
||||
}
|
||||
|
||||
return Interaction {
|
||||
clicked = false,
|
||||
hovering = hovering,
|
||||
clicked = hovering && mouse_is_clicked,
|
||||
};
|
||||
}
|
||||
|
||||
delete_box_children :: proc(box: ^Box, keep_persistent: bool = true) {
|
||||
delete_box_children :: proc(ctx: ^Context, box: ^Box, keep_persistent: bool = true) {
|
||||
iter := BoxIter { box.first, 0 };
|
||||
|
||||
for box in iterate_box(&iter) {
|
||||
delete_box(box, keep_persistent);
|
||||
delete_box(ctx, box, keep_persistent);
|
||||
}
|
||||
}
|
||||
|
||||
delete_box :: proc(box: ^Box, keep_persistent: bool = true) {
|
||||
delete_box_children(box, keep_persistent);
|
||||
delete_box :: proc(ctx: ^Context, box: ^Box, keep_persistent: bool = true) {
|
||||
delete_box_children(ctx, box, keep_persistent);
|
||||
|
||||
if !(box.key in persistent) || !keep_persistent {
|
||||
if !(box.key in ctx.persistent) || !keep_persistent {
|
||||
delete(box.key.label);
|
||||
free(box);
|
||||
}
|
||||
}
|
||||
|
||||
prune :: proc() {
|
||||
iter := BoxIter { root.first, 0 };
|
||||
prune :: proc(ctx: ^Context) {
|
||||
iter := BoxIter { ctx.root.first, 0 };
|
||||
|
||||
for box in iterate_box(&iter) {
|
||||
delete_box_children(box);
|
||||
delete_box_children(ctx, box);
|
||||
|
||||
if !(box.key in persistent) {
|
||||
if !(box.key in ctx.persistent) {
|
||||
free(box);
|
||||
}
|
||||
}
|
||||
|
||||
root_key := root.key;
|
||||
root^ = {
|
||||
root_key := ctx.root.key;
|
||||
ctx.root^ = {
|
||||
key = root_key,
|
||||
};
|
||||
current_parent = root;
|
||||
ctx.current_parent = ctx.root;
|
||||
}
|
||||
|
||||
ancestor_size :: proc(box: ^Box, axis: Axis) -> int {
|
||||
// TODO: consider not using `ctx` here
|
||||
ancestor_size :: proc(ctx: ^Context, box: ^Box, axis: Axis) -> int {
|
||||
if box == nil || box.parent == nil {
|
||||
return root.computed_size[axis];
|
||||
return ctx.root.computed_size[axis];
|
||||
}
|
||||
|
||||
switch box.parent.semantic_size[axis].kind {
|
||||
|
@ -249,13 +286,13 @@ ancestor_size :: proc(box: ^Box, axis: Axis) -> int {
|
|||
return box.parent.computed_size[axis];
|
||||
|
||||
case .ChildrenSum:
|
||||
return ancestor_size(box.parent, axis);
|
||||
return ancestor_size(ctx, box.parent, axis);
|
||||
}
|
||||
|
||||
return 1337;
|
||||
}
|
||||
|
||||
compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, box: ^Box = root) {
|
||||
compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font_height: int, box: ^Box) {
|
||||
if box == nil { return; }
|
||||
|
||||
axis := Axis.Horizontal;
|
||||
|
@ -268,8 +305,9 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
box.computed_pos[axis] = box.prev.computed_pos[axis] + box.prev.computed_size[axis];
|
||||
}
|
||||
|
||||
post_compute_size := [2]bool { false, false };
|
||||
compute_children := true;
|
||||
if box == root {
|
||||
if box == ctx.root {
|
||||
box.computed_size = canvas_size;
|
||||
} else {
|
||||
switch box.semantic_size.x.kind {
|
||||
|
@ -281,29 +319,30 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
box.computed_size.x = box.semantic_size.x.value;
|
||||
}
|
||||
case .ChildrenSum: {
|
||||
compute_children = false;
|
||||
box.computed_size.x = 0;
|
||||
//compute_children = false;
|
||||
post_compute_size[int(Axis.Horizontal)] = true;
|
||||
// box.computed_size.x = 0;
|
||||
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
compute_layout(canvas_size, font_width, font_height, child);
|
||||
// iter := BoxIter { box.first, 0 };
|
||||
// for child in iterate_box(&iter) {
|
||||
// compute_layout(canvas_size, font_width, font_height, child);
|
||||
|
||||
switch box.axis {
|
||||
case .Horizontal: {
|
||||
box.computed_size.x += child.computed_size.x;
|
||||
}
|
||||
case .Vertical: {
|
||||
if child.computed_size.x > box.computed_size.x {
|
||||
box.computed_size.x = child.computed_size.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// switch box.axis {
|
||||
// case .Horizontal: {
|
||||
// box.computed_size.x += child.computed_size.x;
|
||||
// }
|
||||
// case .Vertical: {
|
||||
// if child.computed_size.x > box.computed_size.x {
|
||||
// box.computed_size.x = child.computed_size.x;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
case .Fill: {
|
||||
}
|
||||
case .PercentOfParent: {
|
||||
box.computed_size.x = int(f32(ancestor_size(box, .Horizontal))*(f32(box.semantic_size.x.value)/100.0));
|
||||
box.computed_size.x = int(f32(ancestor_size(ctx, box, .Horizontal))*(f32(box.semantic_size.x.value)/100.0));
|
||||
}
|
||||
}
|
||||
switch box.semantic_size.y.kind {
|
||||
|
@ -315,32 +354,34 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
box.computed_size.y = box.semantic_size.y.value;
|
||||
}
|
||||
case .ChildrenSum: {
|
||||
compute_children = false;
|
||||
should_post_compute := false;
|
||||
number_of_fills := 0;
|
||||
box.computed_size.y = 0;
|
||||
parent_size := ancestor_size(box, .Vertical);
|
||||
//compute_children = false;
|
||||
post_compute_size[Axis.Vertical] = true;
|
||||
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
compute_layout(canvas_size, font_width, font_height, child);
|
||||
// should_post_compute := false;
|
||||
// number_of_fills := 0;
|
||||
// box.computed_size.y = 0;
|
||||
// parent_size := ancestor_size(box, .Vertical);
|
||||
|
||||
if child.semantic_size.y.kind == .Fill {
|
||||
number_of_fills += 1;
|
||||
should_post_compute := true;
|
||||
}
|
||||
// iter := BoxIter { box.first, 0 };
|
||||
// for child in iterate_box(&iter) {
|
||||
// compute_layout(canvas_size, font_width, font_height, child);
|
||||
|
||||
switch box.axis {
|
||||
case .Horizontal: {
|
||||
if child.computed_size.y > box.computed_size.y {
|
||||
box.computed_size.y = child.computed_size.y;
|
||||
}
|
||||
}
|
||||
case .Vertical: {
|
||||
box.computed_size.y += child.computed_size.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if child.semantic_size.y.kind == .Fill {
|
||||
// number_of_fills += 1;
|
||||
// should_post_compute := true;
|
||||
// }
|
||||
|
||||
// switch box.axis {
|
||||
// case .Horizontal: {
|
||||
// if child.computed_size.y > box.computed_size.y {
|
||||
// box.computed_size.y = child.computed_size.y;
|
||||
// }
|
||||
// }
|
||||
// case .Vertical: {
|
||||
// box.computed_size.y += child.computed_size.y;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if should_post_compute {
|
||||
// iter := BoxIter { box.first, 0 };
|
||||
|
@ -354,7 +395,7 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
case .Fill: {
|
||||
}
|
||||
case .PercentOfParent: {
|
||||
box.computed_size.y = int(f32(ancestor_size(box, .Vertical))*(f32(box.semantic_size.y.value)/100.0));
|
||||
box.computed_size.y = int(f32(ancestor_size(ctx, box, .Vertical))*(f32(box.semantic_size.y.value)/100.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,7 +415,7 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
our_size := box.computed_size;
|
||||
|
||||
for child in iterate_box(&iter) {
|
||||
compute_layout(canvas_size, font_width, font_height, child);
|
||||
compute_layout(ctx, canvas_size, font_width, font_height, child);
|
||||
if child.semantic_size[box.axis].kind == .Fill {
|
||||
number_of_fills[box.axis] += 1;
|
||||
should_post_compute = true;
|
||||
|
@ -383,12 +424,12 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
}
|
||||
}
|
||||
|
||||
if should_post_compute {
|
||||
if true || should_post_compute {
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
for axis in 0..<2 {
|
||||
if child.semantic_size[axis].kind == .Fill {
|
||||
if child_size[axis] >= our_size[axis] {
|
||||
if false && child_size[axis] >= our_size[axis] {
|
||||
child.computed_size[axis] = our_size[axis] / number_of_fills[axis];
|
||||
} else {
|
||||
child.computed_size[axis] = (our_size[axis] - child_size[axis]) / number_of_fills[axis];
|
||||
|
@ -396,17 +437,56 @@ compute_layout :: proc(canvas_size: [2]int, font_width: int, font_height: int, b
|
|||
}
|
||||
}
|
||||
|
||||
compute_layout(canvas_size, font_width, font_height, child);
|
||||
compute_layout(ctx, canvas_size, font_width, font_height, child);
|
||||
|
||||
if child.label == "2" {
|
||||
fmt.println(child.label, child.computed_size, box.label, our_size, child_size, number_of_fills);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if post_compute_size[Axis.Horizontal] {
|
||||
box.computed_size[Axis.Horizontal] = 0;
|
||||
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
switch box.axis {
|
||||
case .Horizontal: {
|
||||
box.computed_size[Axis.Horizontal] += child.computed_size[Axis.Horizontal];
|
||||
}
|
||||
case .Vertical: {
|
||||
if child.computed_size[Axis.Horizontal] > box.computed_size[Axis.Horizontal] {
|
||||
box.computed_size[Axis.Horizontal] = child.computed_size[Axis.Horizontal];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if post_compute_size[Axis.Vertical] {
|
||||
box.computed_size[Axis.Vertical] = 0;
|
||||
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
switch box.axis {
|
||||
case .Horizontal: {
|
||||
if child.computed_size[Axis.Vertical] > box.computed_size[Axis.Vertical] {
|
||||
box.computed_size[Axis.Vertical] = child.computed_size[Axis.Vertical];
|
||||
}
|
||||
}
|
||||
case .Vertical: {
|
||||
box.computed_size[Axis.Vertical] += child.computed_size[Axis.Vertical];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push_clip :: proc(pos: [2]int, size: [2]int) {
|
||||
push_clip :: proc(ctx: ^Context, pos: [2]int, size: [2]int) {
|
||||
rect := Rect { pos, size };
|
||||
|
||||
if len(clips) > 0 {
|
||||
parent_rect := clips[len(clips)-1];
|
||||
if len(ctx.clips) > 0 {
|
||||
parent_rect := ctx.clips[len(ctx.clips)-1];
|
||||
|
||||
if rect.pos.x >= parent_rect.pos.x &&
|
||||
rect.pos.y >= parent_rect.pos.y &&
|
||||
|
@ -426,72 +506,96 @@ push_clip :: proc(pos: [2]int, size: [2]int) {
|
|||
}
|
||||
}
|
||||
|
||||
raylib.BeginScissorMode(
|
||||
sdl2.RenderSetClipRect(ctx.renderer, &sdl2.Rect {
|
||||
i32(rect.pos.x),
|
||||
i32(rect.pos.y),
|
||||
i32(rect.size.x),
|
||||
i32(rect.size.y)
|
||||
);
|
||||
});
|
||||
|
||||
append(&clips, rect);
|
||||
// raylib.BeginScissorMode(
|
||||
// i32(rect.pos.x),
|
||||
// i32(rect.pos.y),
|
||||
// i32(rect.size.x),
|
||||
// i32(rect.size.y)
|
||||
// );
|
||||
|
||||
append(&ctx.clips, rect);
|
||||
}
|
||||
|
||||
pop_clip :: proc() {
|
||||
raylib.EndScissorMode();
|
||||
pop_clip :: proc(ctx: ^Context) {
|
||||
//raylib.EndScissorMode();
|
||||
|
||||
if len(clips) > 0 {
|
||||
rect := pop(&clips);
|
||||
if len(ctx.clips) > 0 {
|
||||
rect := pop(&ctx.clips);
|
||||
|
||||
raylib.BeginScissorMode(
|
||||
sdl2.RenderSetClipRect(ctx.renderer, &sdl2.Rect {
|
||||
i32(rect.pos.x),
|
||||
i32(rect.pos.y),
|
||||
i32(rect.size.x),
|
||||
i32(rect.size.y)
|
||||
);
|
||||
});
|
||||
// raylib.BeginScissorMode(
|
||||
// i32(rect.pos.x),
|
||||
// i32(rect.pos.y),
|
||||
// i32(rect.size.x),
|
||||
// i32(rect.size.y)
|
||||
// );
|
||||
} else {
|
||||
sdl2.RenderSetClipRect(ctx.renderer, nil);
|
||||
}
|
||||
}
|
||||
|
||||
draw :: proc(font: raylib.Font, font_width: int, font_height: int, box: ^Box = root) {
|
||||
draw :: proc(ctx: ^Context, state: ^core.State, font_width: int, font_height: int, box: ^Box) {
|
||||
if box == nil { return; }
|
||||
|
||||
// NOTE: for some reason if you place this right before the
|
||||
// for loop, the clipping only works for the first child. Compiler bug?
|
||||
push_clip(box.computed_pos, box.computed_size);
|
||||
defer pop_clip();
|
||||
push_clip(ctx, box.computed_pos, box.computed_size);
|
||||
defer pop_clip(ctx);
|
||||
|
||||
if .DrawBackground in box.flags {
|
||||
raylib.DrawRectangle(
|
||||
i32(box.computed_pos.x),
|
||||
i32(box.computed_pos.y),
|
||||
i32(box.computed_size.x),
|
||||
i32(box.computed_size.y),
|
||||
theme.get_palette_raylib_color(.Background1)
|
||||
if .Hoverable in box.flags && box.hot > 0 {
|
||||
core.draw_rect(
|
||||
state,
|
||||
box.computed_pos.x,
|
||||
box.computed_pos.y,
|
||||
box.computed_size.x,
|
||||
box.computed_size.y,
|
||||
.Background2
|
||||
);
|
||||
}
|
||||
else if .DrawBackground in box.flags {
|
||||
core.draw_rect(
|
||||
state,
|
||||
box.computed_pos.x,
|
||||
box.computed_pos.y,
|
||||
box.computed_size.x,
|
||||
box.computed_size.y,
|
||||
.Background1
|
||||
);
|
||||
}
|
||||
|
||||
if .DrawBorder in box.flags {
|
||||
raylib.DrawRectangleLines(
|
||||
i32(box.computed_pos.x),
|
||||
i32(box.computed_pos.y),
|
||||
i32(box.computed_size.x),
|
||||
i32(box.computed_size.y),
|
||||
theme.get_palette_raylib_color(.Background4)
|
||||
core.draw_rect_outline(
|
||||
state,
|
||||
box.computed_pos.x,
|
||||
box.computed_pos.y,
|
||||
box.computed_size.x,
|
||||
box.computed_size.y,
|
||||
.Background4
|
||||
);
|
||||
}
|
||||
if .DrawText in box.flags {
|
||||
for codepoint, index in box.label {
|
||||
raylib.DrawTextCodepoint(
|
||||
font,
|
||||
rune(codepoint),
|
||||
raylib.Vector2 { f32(box.computed_pos.x + index * font_width), f32(box.computed_pos.y) },
|
||||
f32(font_height),
|
||||
theme.get_palette_raylib_color(.Foreground1)
|
||||
);
|
||||
}
|
||||
core.draw_text(state, box.label, box.computed_pos.x, box.computed_pos.y);
|
||||
}
|
||||
|
||||
if .CustomDrawFunc in box.flags && box.custom_draw_func != nil {
|
||||
box.custom_draw_func(state, box, box.user_data);
|
||||
}
|
||||
|
||||
iter := BoxIter { box.first, 0 };
|
||||
for child in iterate_box(&iter) {
|
||||
draw(font, font_width, font_height, child);
|
||||
draw(ctx, state, font_width, font_height, child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,7 +618,7 @@ iterate_box :: proc(iter: ^BoxIter, print: bool = false) -> (box: ^Box, idx: int
|
|||
return box, iter.index, true;
|
||||
}
|
||||
|
||||
debug_print :: proc(box: ^Box, depth: int = 0) {
|
||||
debug_print :: proc(ctx: ^Context, box: ^Box, depth: int = 0) {
|
||||
iter := BoxIter { box.first, 0 };
|
||||
|
||||
for box, idx in iterate_box(&iter, true) {
|
||||
|
@ -525,56 +629,69 @@ debug_print :: proc(box: ^Box, depth: int = 0) {
|
|||
fmt.print(">");
|
||||
}
|
||||
fmt.println(idx, "Box", box.label, "#", box.key.label, "first", transmute(rawptr)box.first, "parent", transmute(rawptr)box.parent, box.computed_size);
|
||||
debug_print(box, depth+1);
|
||||
debug_print(ctx, box, depth+1);
|
||||
}
|
||||
|
||||
if depth == 0 {
|
||||
fmt.println("persistent");
|
||||
for p in persistent {
|
||||
for p in ctx.persistent {
|
||||
fmt.println(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spacer :: proc(label: string) -> ^Box {
|
||||
return push_box(label, {}, semantic_size = {make_semantic_size(.Fill, 0), make_semantic_size(.Fill, 0)});
|
||||
spacer :: proc(ctx: ^Context, label: string, flags: bit_set[Flag] = {}, semantic_size: [2]SemanticSize = {{.Fill, 0}, {.Fill,0}}) -> ^Box {
|
||||
return push_box(ctx, label, flags, semantic_size = semantic_size);
|
||||
}
|
||||
|
||||
label :: proc(label: string) -> Interaction {
|
||||
box := push_box(label, {.DrawText});
|
||||
label :: proc(ctx: ^Context, label: string) -> Interaction {
|
||||
box := push_box(ctx, label, {.DrawText, .Hoverable});
|
||||
|
||||
return test_box(box);
|
||||
return test_box(ctx, box);
|
||||
}
|
||||
|
||||
button :: proc(label: string) -> Interaction {
|
||||
box := push_box(label, {.Clickable, .Hoverable, .DrawText, .DrawBorder, .DrawBackground});
|
||||
button :: proc(ctx: ^Context, label: string) -> Interaction {
|
||||
box := push_box(ctx, label, {.Clickable, .Hoverable, .DrawText, .DrawBorder, .DrawBackground});
|
||||
|
||||
return test_box(box);
|
||||
return test_box(ctx, box);
|
||||
}
|
||||
|
||||
two_buttons_test :: proc(label1: string, label2: string) {
|
||||
push_parent(push_box("two_button_container", {.DrawBorder}, .Vertical, semantic_size = ChildrenSum));
|
||||
custom :: proc(ctx: ^Context, label: string, draw_func: CustomDrawFunc, user_data: rawptr) -> Interaction {
|
||||
box := push_box(ctx, label, {.DrawBorder, .CustomDrawFunc}, semantic_size = { make_semantic_size(.Fill), make_semantic_size(.Fill) });
|
||||
box.custom_draw_func = draw_func;
|
||||
box.user_data = user_data;
|
||||
|
||||
button("1");
|
||||
button("2");
|
||||
button(label1);
|
||||
button(label2);
|
||||
button("5");
|
||||
button("6");
|
||||
return test_box(ctx, box);
|
||||
}
|
||||
|
||||
two_buttons_test :: proc(ctx: ^Context, label1: string, label2: string) {
|
||||
push_parent(ctx, push_box(ctx, "TWO BUTTONS TEST", {.DrawBorder}, .Vertical, semantic_size = {make_semantic_size(.PercentOfParent, 100), { .Fill, 256}}));
|
||||
|
||||
button(ctx, "Row 1");
|
||||
button(ctx, "Row 2");
|
||||
button(ctx, label1);
|
||||
button(ctx, label2);
|
||||
button(ctx, "Row 5");
|
||||
button(ctx, "Row 6");
|
||||
|
||||
push_parent(push_box("two_button_container_inner", {.DrawBorder}, semantic_size = ChildrenSum));
|
||||
button("second first button");
|
||||
{
|
||||
push_parent(push_box("two_button_container_inner", {.DrawBorder}, .Vertical, semantic_size = {make_semantic_size(.PercentOfParent, 50), { .Exact, 256}}));
|
||||
defer pop_parent();
|
||||
push_parent(ctx, push_box(ctx, "two_button_container_inner", {.DrawBorder}, semantic_size = {make_semantic_size(.Fill, 0), { .Fill, 64}}));
|
||||
defer pop_parent(ctx);
|
||||
|
||||
button("first inner most button");
|
||||
button("inner_button2");
|
||||
button("inner_button3");
|
||||
push_box(ctx, "1", {.DrawText, .DrawBackground, .DrawBorder}, semantic_size = {make_semantic_size(.Fill, 100), { .FitText, 256}})
|
||||
push_box(ctx, "2", {.DrawText, .DrawBackground, .DrawBorder}, semantic_size = {make_semantic_size(.Fill, 100), { .FitText, 256}})
|
||||
|
||||
{
|
||||
push_parent(ctx, push_box(ctx, "two_button_container_inner_inner", {.DrawBorder}, .Vertical, semantic_size = {make_semantic_size(.Fill, 50), { .ChildrenSum, 256}}));
|
||||
defer pop_parent(ctx);
|
||||
|
||||
button(ctx, "this is a test button");
|
||||
button(ctx, "me in the middle");
|
||||
button(ctx, "look at me, I'm a test button too");
|
||||
}
|
||||
|
||||
push_box(ctx, "End", {.DrawBorder, .DrawBackground, .DrawText}, .Horizontal, semantic_size = {make_semantic_size(.Fill, 0), { .FitText, 0}})
|
||||
}
|
||||
button("inner_button3");
|
||||
|
||||
pop_parent();
|
||||
button("Help me I'm falling");
|
||||
pop_parent();
|
||||
button(ctx, "Help me I'm falling");
|
||||
pop_parent(ctx);
|
||||
}
|
||||
|
|
289
src/ui/ui.odin
289
src/ui/ui.odin
|
@ -1,152 +1,151 @@
|
|||
package ui
|
||||
|
||||
import "core:math"
|
||||
import "vendor:raylib"
|
||||
|
||||
import "../core"
|
||||
import "../theme"
|
||||
|
||||
MenuBarItemOnClick :: proc(state: ^core.State, item: ^MenuBarItem);
|
||||
|
||||
text_padding :: 4;
|
||||
|
||||
MenuBarItem :: struct {
|
||||
text: string,
|
||||
selected: bool,
|
||||
sub_items: []MenuBarItem,
|
||||
on_click: MenuBarItemOnClick,
|
||||
}
|
||||
|
||||
MenuBarState :: struct {
|
||||
items: []MenuBarItem,
|
||||
}
|
||||
|
||||
draw_menu_bar_item :: proc(state: ^core.State, item: ^MenuBarItem, x, y: i32, parent_width, parent_height: i32, font_height: int, horizontal: bool = false) {
|
||||
foreground_color := theme.PaletteColor.Foreground3;
|
||||
if horizontal {
|
||||
if item.selected {
|
||||
foreground_color = theme.PaletteColor.Background4;
|
||||
} else {
|
||||
foreground_color = theme.PaletteColor.Foreground4;
|
||||
}
|
||||
}
|
||||
|
||||
item_text := raylib.TextFormat("%s", item.text);
|
||||
item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
|
||||
raylib.DrawRectangle(x, y, parent_width, i32(font_height), theme.get_palette_raylib_color(foreground_color));
|
||||
raylib.DrawTextEx(state.font, item_text, raylib.Vector2 { f32(x + text_padding), f32(y) }, f32(font_height), 0, theme.get_palette_raylib_color(.Background1));
|
||||
|
||||
if item.selected {
|
||||
// TODO: change to parent_width
|
||||
largest_sub_item: int
|
||||
for sub_item in item.sub_items {
|
||||
largest_sub_item = math.max(len(sub_item.text), largest_sub_item);
|
||||
}
|
||||
|
||||
this_width := i32(largest_sub_item * state.source_font_width + text_padding*2);
|
||||
sub_list_x := x;
|
||||
if horizontal {
|
||||
sub_list_x += parent_width;
|
||||
}
|
||||
for _, index in item.sub_items {
|
||||
sub_item := &item.sub_items[index];
|
||||
item_text := raylib.TextFormat("%s", sub_item.text);
|
||||
item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
|
||||
index_offset := 1;
|
||||
if horizontal {
|
||||
index_offset = 0;
|
||||
}
|
||||
item_y := y + i32(font_height * (index+index_offset));
|
||||
draw_menu_bar_item(state, sub_item, sub_list_x, item_y, this_width, 0, font_height, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_menu_bar :: proc(state: ^core.State, data: ^MenuBarState, x, y: i32, parent_width, parent_height: i32, font_height: int) {
|
||||
raylib.DrawRectangle(x, y, parent_width, i32(font_height), theme.get_palette_raylib_color(.Background3));
|
||||
|
||||
raylib.DrawTextEx(state.font, "Editor", raylib.Vector2 { f32(x), f32(y) }, f32(font_height), 0, theme.get_palette_raylib_color(.Foreground1));
|
||||
|
||||
x := x + i32((len("Editor") + 4) * state.source_font_width);
|
||||
|
||||
for _, index in data.items {
|
||||
item := &data.items[index];
|
||||
item_text := raylib.TextFormat("%s", item.text);
|
||||
item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
|
||||
item_x := x + (i32(item_width) + text_padding*2) * i32(index);
|
||||
draw_menu_bar_item(state, item, item_x, y, i32(item_width + text_padding*2), i32(font_height), font_height);
|
||||
}
|
||||
}
|
||||
|
||||
test_menu_item :: proc(state: ^core.State, item: ^MenuBarItem, rect: raylib.Rectangle, mouse_pos: raylib.Vector2, mouse_has_clicked: bool, font_height: int, horizontal: bool) -> bool {
|
||||
if raylib.CheckCollisionPointRec(mouse_pos, rect) {
|
||||
item.selected = true;
|
||||
|
||||
if item.on_click != nil && mouse_has_clicked {
|
||||
item.on_click(state, item);
|
||||
}
|
||||
} else if item.selected {
|
||||
largest_sub_item: int
|
||||
for sub_item in item.sub_items {
|
||||
largest_sub_item = math.max(len(sub_item.text), largest_sub_item);
|
||||
}
|
||||
|
||||
this_width := i32(largest_sub_item * state.source_font_width + text_padding*2);
|
||||
sub_list_x := rect.x;
|
||||
if horizontal {
|
||||
sub_list_x += rect.width;
|
||||
}
|
||||
|
||||
has_sub_item_selected := false;
|
||||
for _, index in item.sub_items {
|
||||
sub_item := &item.sub_items[index];
|
||||
item_text := raylib.TextFormat("%s", sub_item.text);
|
||||
item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
|
||||
index_offset := 1;
|
||||
if horizontal {
|
||||
index_offset = 0;
|
||||
}
|
||||
item_y := rect.y + f32(font_height * (index+index_offset));
|
||||
|
||||
sub_rec := raylib.Rectangle {
|
||||
x = sub_list_x,
|
||||
y = item_y,
|
||||
width = f32(this_width),
|
||||
height = f32(font_height),
|
||||
};
|
||||
|
||||
if test_menu_item(state, sub_item, sub_rec, mouse_pos, mouse_has_clicked, font_height, true) {
|
||||
has_sub_item_selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
item.selected = has_sub_item_selected;
|
||||
} else {
|
||||
item.selected = false;
|
||||
}
|
||||
|
||||
return item.selected;
|
||||
}
|
||||
|
||||
test_menu_bar :: proc(state: ^core.State, menu_bar: ^MenuBarState, x, y: i32, mouse_pos: raylib.Vector2, mouse_has_clicked: bool, font_height: int) {
|
||||
x := x + i32((len("Editor") + 4) * state.source_font_width);
|
||||
|
||||
for _, index in menu_bar.items {
|
||||
item := &menu_bar.items[index];
|
||||
item_text := raylib.TextFormat("%s", item.text);
|
||||
item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
|
||||
item_rec := raylib.Rectangle {
|
||||
x = f32(x) + (item_width + f32(text_padding*2)) * f32(index),
|
||||
y = f32(y),
|
||||
width = f32(item_width + text_padding*2),
|
||||
height = f32(font_height),
|
||||
};
|
||||
|
||||
test_menu_item(state, item, item_rec, mouse_pos, mouse_has_clicked, font_height, false);
|
||||
}
|
||||
}
|
||||
// MenuBarItemOnClick :: proc(state: ^core.State, item: ^MenuBarItem);
|
||||
//
|
||||
// text_padding :: 4;
|
||||
//
|
||||
// MenuBarItem :: struct {
|
||||
// text: string,
|
||||
// selected: bool,
|
||||
// sub_items: []MenuBarItem,
|
||||
// on_click: MenuBarItemOnClick,
|
||||
// }
|
||||
//
|
||||
// MenuBarState :: struct {
|
||||
// items: []MenuBarItem,
|
||||
// }
|
||||
//
|
||||
// draw_menu_bar_item :: proc(state: ^core.State, item: ^MenuBarItem, x, y: i32, parent_width, parent_height: i32, font_height: int, horizontal: bool = false) {
|
||||
// foreground_color := theme.PaletteColor.Foreground3;
|
||||
// if horizontal {
|
||||
// if item.selected {
|
||||
// foreground_color = theme.PaletteColor.Background4;
|
||||
// } else {
|
||||
// foreground_color = theme.PaletteColor.Foreground4;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// item_text := raylib.TextFormat("%s", item.text);
|
||||
// item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
//
|
||||
// raylib.DrawRectangle(x, y, parent_width, i32(font_height), theme.get_palette_raylib_color(foreground_color));
|
||||
// raylib.DrawTextEx(state.font, item_text, raylib.Vector2 { f32(x + text_padding), f32(y) }, f32(font_height), 0, theme.get_palette_raylib_color(.Background1));
|
||||
//
|
||||
// if item.selected {
|
||||
// // TODO: change to parent_width
|
||||
// largest_sub_item: int
|
||||
// for sub_item in item.sub_items {
|
||||
// largest_sub_item = math.max(len(sub_item.text), largest_sub_item);
|
||||
// }
|
||||
//
|
||||
// this_width := i32(largest_sub_item * state.source_font_width + text_padding*2);
|
||||
// sub_list_x := x;
|
||||
// if horizontal {
|
||||
// sub_list_x += parent_width;
|
||||
// }
|
||||
// for _, index in item.sub_items {
|
||||
// sub_item := &item.sub_items[index];
|
||||
// item_text := raylib.TextFormat("%s", sub_item.text);
|
||||
// item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
//
|
||||
// index_offset := 1;
|
||||
// if horizontal {
|
||||
// index_offset = 0;
|
||||
// }
|
||||
// item_y := y + i32(font_height * (index+index_offset));
|
||||
// draw_menu_bar_item(state, sub_item, sub_list_x, item_y, this_width, 0, font_height, true);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// draw_menu_bar :: proc(state: ^core.State, data: ^MenuBarState, x, y: i32, parent_width, parent_height: i32, font_height: int) {
|
||||
// raylib.DrawRectangle(x, y, parent_width, i32(font_height), theme.get_palette_raylib_color(.Background3));
|
||||
//
|
||||
// raylib.DrawTextEx(state.font, "Editor", raylib.Vector2 { f32(x), f32(y) }, f32(font_height), 0, theme.get_palette_raylib_color(.Foreground1));
|
||||
//
|
||||
// x := x + i32((len("Editor") + 4) * state.source_font_width);
|
||||
//
|
||||
// for _, index in data.items {
|
||||
// item := &data.items[index];
|
||||
// item_text := raylib.TextFormat("%s", item.text);
|
||||
// item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
//
|
||||
// item_x := x + (i32(item_width) + text_padding*2) * i32(index);
|
||||
// draw_menu_bar_item(state, item, item_x, y, i32(item_width + text_padding*2), i32(font_height), font_height);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// test_menu_item :: proc(state: ^core.State, item: ^MenuBarItem, rect: raylib.Rectangle, mouse_pos: raylib.Vector2, mouse_has_clicked: bool, font_height: int, horizontal: bool) -> bool {
|
||||
// if raylib.CheckCollisionPointRec(mouse_pos, rect) {
|
||||
// item.selected = true;
|
||||
//
|
||||
// if item.on_click != nil && mouse_has_clicked {
|
||||
// item.on_click(state, item);
|
||||
// }
|
||||
// } else if item.selected {
|
||||
// largest_sub_item: int
|
||||
// for sub_item in item.sub_items {
|
||||
// largest_sub_item = math.max(len(sub_item.text), largest_sub_item);
|
||||
// }
|
||||
//
|
||||
// this_width := i32(largest_sub_item * state.source_font_width + text_padding*2);
|
||||
// sub_list_x := rect.x;
|
||||
// if horizontal {
|
||||
// sub_list_x += rect.width;
|
||||
// }
|
||||
//
|
||||
// has_sub_item_selected := false;
|
||||
// for _, index in item.sub_items {
|
||||
// sub_item := &item.sub_items[index];
|
||||
// item_text := raylib.TextFormat("%s", sub_item.text);
|
||||
// item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
//
|
||||
// index_offset := 1;
|
||||
// if horizontal {
|
||||
// index_offset = 0;
|
||||
// }
|
||||
// item_y := rect.y + f32(font_height * (index+index_offset));
|
||||
//
|
||||
// sub_rec := raylib.Rectangle {
|
||||
// x = sub_list_x,
|
||||
// y = item_y,
|
||||
// width = f32(this_width),
|
||||
// height = f32(font_height),
|
||||
// };
|
||||
//
|
||||
// if test_menu_item(state, sub_item, sub_rec, mouse_pos, mouse_has_clicked, font_height, true) {
|
||||
// has_sub_item_selected = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// item.selected = has_sub_item_selected;
|
||||
// } else {
|
||||
// item.selected = false;
|
||||
// }
|
||||
//
|
||||
// return item.selected;
|
||||
// }
|
||||
//
|
||||
// test_menu_bar :: proc(state: ^core.State, menu_bar: ^MenuBarState, x, y: i32, mouse_pos: raylib.Vector2, mouse_has_clicked: bool, font_height: int) {
|
||||
// x := x + i32((len("Editor") + 4) * state.source_font_width);
|
||||
//
|
||||
// for _, index in menu_bar.items {
|
||||
// item := &menu_bar.items[index];
|
||||
// item_text := raylib.TextFormat("%s", item.text);
|
||||
// item_width := raylib.MeasureTextEx(state.font, item_text, f32(font_height), 0).x;
|
||||
//
|
||||
// item_rec := raylib.Rectangle {
|
||||
// x = f32(x) + (item_width + f32(text_padding*2)) * f32(index),
|
||||
// y = f32(y),
|
||||
// width = f32(item_width + text_padding*2),
|
||||
// height = f32(font_height),
|
||||
// };
|
||||
//
|
||||
// test_menu_item(state, item, item_rec, mouse_pos, mouse_has_clicked, font_height, false);
|
||||
// }
|
||||
// }
|
||||
|
|
Loading…
Reference in New Issue