diff --git a/.build/.added_strings_w3.jai b/.build/.added_strings_w3.jai index 38c74d8..03e7ad2 100644 --- a/.build/.added_strings_w3.jai +++ b/.build/.added_strings_w3.jai @@ -6,7 +6,7 @@ NAME :: "mexplore"; VERSION :: "0.1"; JAI_VERSION :: "beta 0.2.014, built on 24 May 2025"; - RELEASE_DATE :: "16 July 2025, 20:47:28"; + RELEASE_DATE :: "19 July 2025, 16:47:42"; GIT_BRANCH :: "main"; - GIT_REVISION :: "68096796dc50c0bfe4e9d687ce4e9563e0bbf4bb"; + GIT_REVISION :: "3520906f2803cf5baf5d52dcb05daf94d8edadd1"; DEBUG :: true; diff --git a/.build/mexplore-debug.lib b/.build/mexplore-debug.lib index 954e25b..f547c8c 100644 Binary files a/.build/mexplore-debug.lib and b/.build/mexplore-debug.lib differ diff --git a/.build/mexplore-debug_0_w3.obj b/.build/mexplore-debug_0_w3.obj index 38b681a..9bdb7fd 100644 Binary files a/.build/mexplore-debug_0_w3.obj and b/.build/mexplore-debug_0_w3.obj differ diff --git a/.build/mexplore-debug_1_w3.obj b/.build/mexplore-debug_1_w3.obj index 0b51b1a..8f20d5d 100644 Binary files a/.build/mexplore-debug_1_w3.obj and b/.build/mexplore-debug_1_w3.obj differ diff --git a/.build/mexplore-debug_2_w3.obj b/.build/mexplore-debug_2_w3.obj index a84bc1d..734ef4d 100644 Binary files a/.build/mexplore-debug_2_w3.obj and b/.build/mexplore-debug_2_w3.obj differ diff --git a/.build/mexplore-debug_3_w3.obj b/.build/mexplore-debug_3_w3.obj index aaf25f0..4207122 100644 Binary files a/.build/mexplore-debug_3_w3.obj and b/.build/mexplore-debug_3_w3.obj differ diff --git a/bin/mexplore-debug.exe b/bin/mexplore-debug.exe index 5524d62..4d5fc8e 100644 Binary files a/bin/mexplore-debug.exe and b/bin/mexplore-debug.exe differ diff --git a/bin/mexplore-debug.pdb b/bin/mexplore-debug.pdb index 17dc2d3..df7bf4f 100644 Binary files a/bin/mexplore-debug.pdb and b/bin/mexplore-debug.pdb differ diff --git a/bin/mexplore-debug.rdi b/bin/mexplore-debug.rdi index 323db38..ca009d6 100644 Binary files a/bin/mexplore-debug.rdi and b/bin/mexplore-debug.rdi differ diff --git a/src/main.jai b/src/main.jai index c09caa4..e29e9bd 100644 --- a/src/main.jai +++ b/src/main.jai @@ -77,8 +77,14 @@ main :: () { running = false; case SDL_EVENT_KEY_DOWN; - if event.key.key == SDLK_ESCAPE - running = false; + if event.key.key == { + case SDLK_ESCAPE; + running = false; + + case SDLK_RETURN; + log("pressing enter"); + input_state.last_char = STB_TEXTEDIT_NEWLINE; + } case SDL_EVENT_MOUSE_MOTION; transition.motion_delta = .{event.motion.xrel, event.motion.yrel}; @@ -152,7 +158,7 @@ main :: () { ui_context.sizing_x = .FIT; ui_context.sizing_y = .FIT; //ui_label("Hello, World! How's it going?"); - ui_label("Hello, World!"); + //ui_label("Hello, World!"); ui_text_input("Name"); // ui_begin_container("Picture-Name-Settings"); // { diff --git a/src/stb_textedit.jai b/src/stb_textedit.jai index 2a14336..4263eeb 100644 --- a/src/stb_textedit.jai +++ b/src/stb_textedit.jai @@ -283,7 +283,7 @@ STB_TEXTEDIT_STRINGLEN :: (obj: *STB_TEXTEDIT_STRING) -> s32 { } STB_TEXTEDIT_KEYTOTEXT :: (k: STB_TEXTEDIT_KEYTYPE) -> s32 #expand { - return ifx k >= 32 then k else -1; + return ifx k >= 0 then k else -1; } STB_TEXTEDIT_DELETECHARS :: (obj: *STB_TEXTEDIT_STRING, i: s32, n: s32) { @@ -321,33 +321,31 @@ STB_TEXTEDIT_INSERTCHARS :: (obj: *STB_TEXTEDIT_STRING, i: s32, c: *STB_TEXTEDIT } STB_TEXTEDIT_LAYOUTROW :: (row: *StbTexteditRow, obj: *STB_TEXTEDIT_STRING, n: s32) { - // text : *u8 = obj.text.data; - // line_start : *u8 = text + n; - // len := obj.text.count - (line_start - text); - - // text_utf32 : [..]u32; - // defer array_free(text_utf32); - - // StringAt : u64; - // while StringAt < xx len { - // Decode : kbts_decode = kbts_DecodeUtf8(line_start, xx len - StringAt); - // StringAt += Decode.SourceCharactersConsumed; - // if Decode.Valid { - // array_add(*text_utf32, Decode.Codepoint); - // } - // } - - //size, max_descent, read := SegmentText(obj.font, text_utf32.data, xx text_utf32.count); idx : s32; - while word := n + idx < obj.text.count && row.x1 < obj.max_size.x { - size, max_descent, read := next_word_size(obj.font, obj.text, n + idx, obj.max_size.x); + if n + idx < obj.text.count && row.x1 < obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding) { + size, max_descent, read := next_line_size(obj.font, obj.text, n + idx, obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding)); - if row.x1 + size.x > obj.max_size.x { - while grapheme := idx < obj.text.count { - size, max_descent, read := next_grapheme_size(obj.font, obj.text, n + idx, obj.max_size.x); + if row.x1 + size.x > obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding) { - if row.x1 + size.x > obj.max_size.x { - break word; + while word := n + idx < obj.text.count && row.x1 < obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding) { + size, max_descent, read := next_word_size(obj.font, obj.text, n + idx, obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding)); + + if row.x1 + size.x > obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding) { + while grapheme := idx < obj.text.count { + size, max_descent, read := next_grapheme_size(obj.font, obj.text, n + idx, obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding)); + + if row.x1 + size.x > obj.max_size.x - (2 * obj.margin + 2 * obj.border_size + 2 * obj.padding) { + //break word; + return; + } + + row.x1 += size.x; + row.baseline_y_delta = max(row.baseline_y_delta, size.y); + row.ymin = max(row.ymin, max_descent); + row.ymax = max(row.ymax, size.y - row.ymin); + row.num_chars += read; + idx += read; + } } row.x1 += size.x; @@ -368,153 +366,6 @@ STB_TEXTEDIT_LAYOUTROW :: (row: *StbTexteditRow, obj: *STB_TEXTEDIT_STRING, n: s } row.x0 = 0.0; - - // words := split(.{len, line_start}, " "); - - // for *word : words { - // if word.* != "" && word.data - line_start + word.count < len { - // if text[word.data - line_start + len] == " " { - // word.count += 1; - // } - // } - // } - - //total_size : Vector2; - //lines : [..]Line; - - // if !text { - // //return .{}, 0.0, 0.0, lines; - // } - - // if words.count == 0 { - // return .{}, 0.0, 0.0, lines; - // } - - //line : Line; - - // for word : words { - // started_a_line : bool; - // if line.text.count == 0 { - // line.text.data = word.data; - // line.text.count = word.count; - // started_a_line = true; - // } - - // buf : *hb_buffer_t = hb_buffer_create(); - // hb_buffer_add_utf8(buf, word.data, xx word.count, 0, -1); - - // hb_buffer_set_direction(buf, hb_direction_t.LTR); - // hb_buffer_set_script(buf, hb_script_t.HB_SCRIPT_LATIN); - // hb_buffer_set_language(buf, hb_language_from_string("en", -1)); - - // features : [1]hb_feature_t; - // features[0].tag = HB_TAG(#char "c", #char "a", #char "l", #char "t"); - // features[0].value = 1; - // features[0].start = HB_FEATURE_GLOBAL_START; - // features[0].end = HB_FEATURE_GLOBAL_END; - - // hb_shape(obj.font.hb, buf, features.data, features.count); - // glyph_count_u : u32; - // glyph_info : *hb_glyph_info_t = hb_buffer_get_glyph_infos(buf, *glyph_count_u); - // glyph_pos : *hb_glyph_position_t = hb_buffer_get_glyph_positions(buf, *glyph_count_u); - - // glyph_count : s32 = xx glyph_count_u; - - // word_size : Vector2; - - // for i : 0..glyph_count - 1 { - // glyphid : hb_codepoint_t = glyph_info[i].codepoint; - // x_offset : hb_position_t = glyph_pos[i].x_offset; - // y_offset : hb_position_t = glyph_pos[i].y_offset; - // x_advance : hb_position_t = glyph_pos[i].x_advance; - // y_advance : hb_position_t = glyph_pos[i].y_advance; - - // glyph : *Glyph = table_find_pointer(*obj.font.glyphs, glyphid); - - // if glyph { - // word_size.y = max(word_size.y, xx (glyph.height + glyph.descent)); - // word_size.x += x_advance / 64.0; - // line.max_descent = max(line.max_descent, cast(float) glyph.descent); - // line.max_ascent = max(line.max_ascent, cast(float) glyph.ascent); - // } - // } - - // if !started_a_line { - // line.text.count += word.count; - // } - - // if obj.max_size.x > 0.0 { - // if line.size.x + word_size.x > obj.max_size.x { - // line.size.x = obj.max_size.x; - // line.size.y = max(line.size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // array_add(*lines, line); - // line = .{}; - // } else { - // line.size.y = max(total_size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // line.size.x += word_size.x; - // // } else { - // // line.text.data = word.data; - // // line.text.count = word.count; - // // } - // } - // } else if obj.max_size.x == 0.0 { - // line.size.y = max(total_size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // line.size.x += word_size.x; - // // if include_descent - // // size.y = max_ascent + max_descent; - // } - - // hb_buffer_destroy(buf); - // } - - // if line.text.count > 0 { - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // array_add(*lines, line); - // line = .{}; - // } - - // for line : lines { - // total_size.x = max(total_size.x, line.size.x); - // total_size.y += line.size.y; - // } - - // // determine how many characters to shape (until newline or wrap) - // // for simplicity, shape a chunk of ~256 characters or to newline - // p := line_start; - // len : s32 = 0; - // while p.* && p.* != #char "\n" && len < 256 { - // p += 1; - // len += 1; - // } - - // // shape the text - // buf : *hb_buffer_t = hb_buffer_create(); - // hb_buffer_add_utf8(buf, line_start, len, 0, len); - // hb_buffer_guess_segment_properties(buf); - // hb_shape(hb_font, buf, NULL, 0); - - // glyph_count : u32; - // glyph_info : *hb_glyph_info_t = hb_buffer_get_glyph_infos(buf, *glyph_count); - // pos : *hb_glyph_position_t = hb_buffer_get_glyph_positions(buf, *glyph_count); - - // // iterate through glyphs, accumulate width - // x : float = 0.0; - // num_chars : s32 = 0; - // for i : 0..glyph_count - 1 { - // x += pos[i].x_advance / 64.0; // HarfBuzz uses 26.6 fixed-point - // num_chars += 1; - // // optional: if you have a max line width, break here - // } - - // 4. Use FreeType or your line layout logic for line height - // line_height : float = obj->font->height; // or extract from FT_Size_Metrics - // ymin : float = -obj->font->ascent; - // ymax : float = obj->font->descent; - - //hb_buffer_destroy(buf); } STB_TEXTEDIT_GETWIDTH :: (obj: *STB_TEXTEDIT_STRING, n: s32, i: s32) -> float { diff --git a/src/text.jai b/src/text.jai index b9020e3..e713dc6 100644 --- a/src/text.jai +++ b/src/text.jai @@ -85,7 +85,6 @@ init_font :: (using font: *Font, filename: string, size: s32) { charcode = FT_Get_First_Char(face, *gindex); while gindex != 0 { - log("Reading index: % - Charcode: %", gindex, charcode); error = FT_Load_Glyph(face, gindex, FT_LOAD_RENDER); if error log("%", to_string(FT_Error_String(error))); @@ -280,9 +279,9 @@ render_text :: (font: *Font, text: []u32, pos: Vector2, size: Vector2, window_sp glyph : *Glyph = table_find_pointer(*font.glyphs, kglyph.Id); if !glyph { - log("[Error] Panic! Didn't find the glyph!"); - for font.glyphs - log("%", it); + //log("[Error] Panic! Didn't find the glyph!"); + GlyphIndex += 1; + continue; } v0 : Vector2; @@ -649,23 +648,6 @@ next_grapheme_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) Codepoints : *u32 = textp + n; CodepointCount : u64 = xx (text.count - (Codepoints - textp)); - // text_utf32 : [..]u32; - // defer array_free(text_utf32); - - // StringAt : u64; - // while StringAt < xx len { - // Decode : kbts_decode = kbts_DecodeUtf8(line_start + StringAt, xx len - StringAt); - // StringAt += Decode.SourceCharactersConsumed; - // if Decode.Valid { - // array_add(*text_utf32, Decode.Codepoint); - // } - // } - - //size, max_descent, read := SegmentText(font, line_start, len); - - //return size, max_descent, read; - - Cursor : kbts_cursor; Direction : kbts_direction = .NONE; Script : kbts_script = .DONT_KNOW; @@ -673,29 +655,12 @@ next_grapheme_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) BreakState : kbts_break_state; kbts_BeginBreak(*BreakState, .NONE, .NORMAL); - // size : Vector2; - // max_descent : float; - CodepointIndex : u64; while CodepointIndex < xx CodepointCount { kbts_BreakAddCodepoint(*BreakState, Codepoints[CodepointIndex], 1, xx ((CodepointIndex + 1) == xx CodepointCount)); Break : kbts_break; while kbts_Break(*BreakState, *Break) { - // if (Break.Position > RunStart) && (Break.Flags & (.DIRECTION | .SCRIPT | .LINE_HARD)) { - // RunLength : u64 = Break.Position - RunStart; - // size, max_descent := ShapeText(font, *Cursor, Codepoints + RunStart, RunLength, BreakState.MainDirection, Direction, Script); - - // return size, max_descent, Break.Position; - // } - - // if (Break.Position > RunStart) && (Break.Flags & (.DIRECTION | .SCRIPT | .LINE_HARD)) { - // RunLength : u64 = Break.Position - RunStart; - // size, max_descent := ShapeText(font, *Cursor, Codepoints + RunStart, RunLength, BreakState.MainDirection, Direction, Script); - - // return size, max_descent, xx CodepointIndex; - // } - if Break.Flags & .DIRECTION { Direction = Break.Direction; if(!Cursor.Direction) Cursor = kbts_Cursor(BreakState.MainDirection); @@ -709,182 +674,14 @@ next_grapheme_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) RunLength : u64 = Break.Position - RunStart; size, max_descent := ShapeText(font, *Cursor, Codepoints + RunStart, RunLength, BreakState.MainDirection, Direction, Script); - //if max_width > 0.0 && size.x + word_size.x > max_width { - return size, max_descent, xx Break.Position; - //} - - // size.x += word_size.x; - // size.y = max(word_size.y); - - // max_descent = max(max_descent, word_max_descent); + return size, max_descent, xx Break.Position; } - - // if (Break.Position > RunStart) && Break.Flags & .LINE_HARD { - // RunLength : u64 = Break.Position - RunStart; - // word_size, word_max_descent := ShapeText(font, *Cursor, Codepoints + RunStart, RunLength, BreakState.MainDirection, Direction, Script); - // return size, max_descent, Break.Position; - // } } CodepointIndex += 1; } return .{}, 0, 0; - - // words := split(text, " "); - - // for *word : words { - // if word.* != "" && word.data - text.data + word.count < text.count { - // if text[word.data - text.data + word.count] == " " { - // word.count += 1; - // } - // } - // } - - //total_size : Vector2; - // lines : [..]Line; - - // if !text { - // return .{}, 0.0, 0.0, lines; - // } - - // if words.count == 0 { - // return .{}, 0.0, 0.0, lines; - // } - - // text_utf32 : [..]u32; - // defer array_free(text_utf32); - - // StringAt : u64; - // while StringAt < text.count { - // Decode : kbts_decode = kbts_DecodeUtf8(text.data, text.count - StringAt); - // StringAt += Decode.SourceCharactersConsumed; - // if Decode.Valid { - // array_add(*text_utf32, Decode.Codepoint); - // } - // } - - // String : *u8 = text_utf32.data; - // Length : u64 = text_utf32.count; - - // // Make some glyphs - // kbts_glyph *Glyphs = cast(*kbts_glyph, alloc(size_of(kbts_glyph) * Length)); - // GlyphCount : u32 = 0; - // Script : kbts_script = KBTS_SCRIPT_DONT_KNOW; - // Direction : kbts_direction = KBTS_DIRECTION_NONE; - // StringAt : u64; - // while StringAt < Length { - // Decode : kbts_decode = kbts_DecodeUtf8(String, Length - StringAt); - // StringAt += Decode.SourceCharactersConsumed; - // if(Decode.Valid) { - // Glyph : kbts_glyph = kbts_CodepointToGlyph(*Font, Decode.Codepoint); - // // Easy script inference for simple cases. (This is similar to hb_buffer_guess_segment_properties.) - // // If you have already segmented String with our API, you already have a script! - // // So no need to pass it in that case. - // // Only use this as a shorthand, when you are pretty sure String is a single - // // script. - // kbts_InferScript(*Direction, *Script, Glyph.Script); - // Glyphs[GlyphCount] = Glyph; - // GlyphCount += 1; - // } - // } - - - // void SegmentText(uint32_t *Codepoints, size_t CodepointCount) - - // line : Line; - - // for word : words { - // started_a_line : bool; - // if line.text.count == 0 { - // line.text.data = word.data; - // line.text.count = word.count; - // started_a_line = true; - // } - - // buf : *hb_buffer_t = hb_buffer_create(); - // hb_buffer_add_utf8(buf, word.data, xx word.count, 0, -1); - - // hb_buffer_set_direction(buf, hb_direction_t.LTR); - // hb_buffer_set_script(buf, hb_script_t.HB_SCRIPT_LATIN); - // hb_buffer_set_language(buf, hb_language_from_string("en", -1)); - - // features : [1]hb_feature_t; - // features[0].tag = HB_TAG(#char "c", #char "a", #char "l", #char "t"); - // features[0].value = 1; - // features[0].start = HB_FEATURE_GLOBAL_START; - // features[0].end = HB_FEATURE_GLOBAL_END; - - // hb_shape(font.hb, buf, features.data, features.count); - // glyph_count_u : u32; - // glyph_info : *hb_glyph_info_t = hb_buffer_get_glyph_infos(buf, *glyph_count_u); - // glyph_pos : *hb_glyph_position_t = hb_buffer_get_glyph_positions(buf, *glyph_count_u); - - // glyph_count : s32 = xx glyph_count_u; - - // word_size : Vector2; - - // for i : 0..glyph_count - 1 { - // glyphid : hb_codepoint_t = glyph_info[i].codepoint; - // x_offset : hb_position_t = glyph_pos[i].x_offset; - // y_offset : hb_position_t = glyph_pos[i].y_offset; - // x_advance : hb_position_t = glyph_pos[i].x_advance; - // y_advance : hb_position_t = glyph_pos[i].y_advance; - - // glyph : *Glyph = table_find_pointer(*font.glyphs, glyphid); - - // if glyph { - // word_size.y = max(word_size.y, xx (glyph.height + glyph.descent)); - // word_size.x += x_advance / 64.0; - // line.max_descent = max(line.max_descent, cast(float) glyph.descent); - // line.max_ascent = max(line.max_ascent, cast(float) glyph.ascent); - // } - // } - - // if !started_a_line { - // line.text.count += word.count; - // } - - // if max_width > 0.0 { - // if line.size.x + word_size.x > max_width { - // line.size.x = max_width; - // line.size.y = max(line.size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // array_add(*lines, line); - // line = .{}; - // } else { - // line.size.y = max(total_size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // line.size.x += word_size.x; - // // } else { - // // line.text.data = word.data; - // // line.text.count = word.count; - // // } - // } - // } else if max_width == 0.0 { - // line.size.y = max(total_size.y, word_size.y); - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // line.size.x += word_size.x; - // // if include_descent - // // size.y = max_ascent + max_descent; - // } - - // hb_buffer_destroy(buf); - // } - - // if line.text.count > 0 { - // line.size.y = max(line.size.y, line.max_ascent + line.max_descent); - // array_add(*lines, line); - // line = .{}; - // } - - // for line : lines { - // total_size.x = max(total_size.x, line.size.x); - // total_size.y += line.size.y; - // } - - - //return total_size, 0, 0; } next_word_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) -> Vector2, float, s32 { @@ -1065,6 +862,48 @@ next_word_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) -> //return total_size, 0, 0; } +next_line_size :: (font: *Font, text: []u32, n: s32, max_width: float = 0.0) -> Vector2, float, s32 { + + textp : *u32 = text.data; + Codepoints : *u32 = textp + n; + CodepointCount : u64 = xx (text.count - (Codepoints - textp)); + + Cursor : kbts_cursor; + Direction : kbts_direction = .NONE; + Script : kbts_script = .DONT_KNOW; + RunStart : u64 = 0; + BreakState : kbts_break_state; + kbts_BeginBreak(*BreakState, .NONE, .NORMAL); + + CodepointIndex : u64; + while CodepointIndex < xx CodepointCount { + kbts_BreakAddCodepoint(*BreakState, Codepoints[CodepointIndex], 1, xx ((CodepointIndex + 1) == xx CodepointCount)); + Break : kbts_break; + while kbts_Break(*BreakState, *Break) { + + if Break.Flags & .DIRECTION { + Direction = Break.Direction; + if(!Cursor.Direction) Cursor = kbts_Cursor(BreakState.MainDirection); + } + + if Break.Flags & .SCRIPT { + Script = Break.Script; + } + + if (Break.Position > RunStart) && (Break.Flags & .LINE_HARD) { + RunLength : u64 = Break.Position - RunStart; + size, max_descent := ShapeText(font, *Cursor, Codepoints + RunStart, RunLength, BreakState.MainDirection, Direction, Script); + + return size, max_descent, xx Break.Position; + } + } + + CodepointIndex += 1; + } + + return .{}, 0, 0; +} + make_texture_from_data :: (data: *u8, width: s32, height: s32) -> Texture { if !data { log("[Error] Could not load the texture."); @@ -1102,7 +941,7 @@ PRIMITIVE_TYPE :: enum u8 { render_batch :: (primitive_type: PRIMITIVE_TYPE, vertices: []$T, shader: *_Shader, texture: *Texture, view: Matrix4, proj: Matrix4) { if !vertices { - log("[Error] The batch has no vertices."); + //log("[Error] The batch has no vertices."); return; } diff --git a/src/ui.jai b/src/ui.jai index c3b0187..2c22696 100644 --- a/src/ui.jai +++ b/src/ui.jai @@ -899,39 +899,50 @@ ui_text_input :: (s: string, font_colour := Vector4.{1, 1, 1, 1}) { //text_input.frame = get_texture("panel-border-000"); text_input.font = ui_context.font; - stb_textedit_initialize_state(*text_input.textedit_state, 1); + stb_textedit_initialize_state(*text_input.textedit_state, 0); } ui_append_to_parent(text_input); if text_input.active && input_state.last_char > 0 { stb_textedit_key(text_input, *text_input.textedit_state, input_state.last_char); + log("adding char %", input_state.last_char); // log("Adding % to builder.", to_string(*input_state.last_char, 1)); // append(*text_input.input_buffer, input_state.last_char); } text_size : Vector2; - text_size.y = xx text_input.font.face.size.metrics.height >> 6; + //text_size.y = xx text_input.font.face.size.metrics.height >> 6; //str := builder_to_string(*text_input.input_buffer, 0, false); // if str.count > 0 { // defer free(str); // textsize = Vector2.{xx Simp.prepare_text(text_input.font, str), xx text_input.font.character_height}; // } max_descent : float; - idx : s32; - while idx < text_input.text.count { - word_size, word_descent, read := next_word_size(text_input.font, text_input.text, idx, 0.0); + // idx : s32; + // while idx < text_input.text.count { + // word_size, word_descent, read := next_word_size(text_input.font, text_input.text, idx, 0.0); - text_size.x += word_size.x; - text_size.y = max(text_size.y, word_size.y); - max_descent = max(max_descent, word_descent); + // text_size.x += word_size.x; + // text_size.y = max(text_size.y, word_size.y); + // max_descent = max(max_descent, word_descent); - idx += read; + // idx += read; + // } + + i : s32; + while i < text_input.text.count { + row : StbTexteditRow; + STB_TEXTEDIT_LAYOUTROW(*row, text_input, i); + + text_size.x = max(text_size.x, row.x1); + text_size.y += text_input.font.face.size.metrics.height >> 6; + + i += xx row.num_chars; } - text_input.min_size = v2(2 * text_input.margin + 2 * text_input.border_size + 2 * text_input.padding) + text_size; + text_input.min_size = v2(2 * text_input.margin + 2 * text_input.border_size + 2 * text_input.padding) + max(text_size, .{xx text_input.font.face.size.metrics.max_advance >> 6, xx text_input.font.face.size.metrics.height >> 6}); text_input.size = text_input.min_size; - text_input.size = max(text_input.size, .{40.0, 20.0}); text_input.max_size = text_input.size; text_input.anchor = ui_context.anchor; @@ -984,7 +995,7 @@ ui_draw_text_input :: (using text_input: *TextInput) { if text_input.text.count > 0 { //midline : Vector2 = pos + Vector2.{cast(float, margin + border_size + padding), xx (size.y / 2.0)}; - draw_pos : Vector2 = pos + v2(margin); + draw_pos : Vector2 = pos + .{0.0, size.y - font.face.size.metrics.height >> 6 - (margin + border_size + padding)} + v2(margin) + v2(border_size) + v2(padding); i : s32; diff --git a/ui.rad b/ui.rad index 78ddb2c..72806a8 100644 --- a/ui.rad +++ b/ui.rad @@ -1,41 +1,51 @@ // raddbg 0.9.20 project file -recent_file: path: "src/text.jai" +recent_file: path: "../jai_test/j.jai" recent_file: path: "src/ui.jai" recent_file: path: "src/stb_textedit.jai" -recent_file: path: "../../../../jai/modules/runtime_support.jai" recent_file: path: "modules/kb_text_shape/kb_text_shape.h" +recent_file: path: "src/text.jai" +recent_file: path: "modules/SDL3/src/SDL-release-3.2.16/src/events/sdl_keyboard.c" +recent_file: path: "modules/SDL3/src/SDL-release-3.2.16/src/video/windows/SDL_windowsevents.c" recent_file: path: "src/main.jai" -recent_file: path: "../../../../jai/modules/math/module.jai" recent_file: path: "../../../../jai/modules/basic/array.jai" +recent_file: path: "../../../../jai/modules/math/module.jai" +recent_file: path: "src/math/math.jai" +recent_file: path: "../../../../jai/modules/runtime_support.jai" recent_file: path: "../../../../jai/modules/basic/module.jai" recent_file: path: "../../../../jai/modules/default_allocator/module.jai" +breakpoint: +{ + source_location: "src/text.jai:516:1" + hit_count: 0 + enabled: 0 +} +breakpoint: +{ + source_location: "src/ui.jai:935:1" + hit_count: 0 + enabled: 0 +} +breakpoint: +{ + source_location: "src/text.jai:944:1" + hit_count: 0 + enabled: 0 +} +breakpoint: +{ + source_location: "src/ui.jai:908:1" + hit_count: 0 + enabled: 0 +} target: { - executable: "bin/mexplore-debug.exe" - working_directory: bin + executable: "../jai_test/j.exe" + working_directory: "../jai_test/" enabled: 1 } breakpoint: { - source_location: "src/ui.jai:1588:1" - hit_count: 0 - enabled: 0 -} -breakpoint: -{ - source_location: "src/ui.jai:262:1" - hit_count: 0 - enabled: 0 -} -breakpoint: -{ - source_location: "src/stb_textedit.jai:346:1" - hit_count: 0 - enabled: 0 -} -breakpoint: -{ - source_location: "src/text.jai:282:1" - hit_count: 8 + source_location: "../jai_test/j.jai:44:1" + hit_count: 1 }