diff --git a/code/collision.odin b/code/collision.odin index c93d74d..cf6b3d8 100644 --- a/code/collision.odin +++ b/code/collision.odin @@ -3,8 +3,8 @@ package sectr import "core:math/linalg" pos_within_range2 :: proc( pos : Vec2, range : Range2 ) -> b32 { - within_x := pos.x > range.p0.x && pos.x < range.p1.x - within_y := pos.y < range.p0.y && pos.y > range.p1.y + within_x := pos.x > range.min.x && pos.x < range.max.x + within_y := pos.y > range.min.y && pos.y < range.max.y return b32(within_x && within_y) } diff --git a/code/math.odin b/code/math.odin index d3c3873..2176af8 100644 --- a/code/math.odin +++ b/code/math.odin @@ -70,4 +70,4 @@ equal_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> b32 { size_range2 :: #force_inline proc "contextless" ( value : Range2 ) -> Vec2 { return { value.p1.x - value.p0.x, value.p0.y - value.p1.y } -} \ No newline at end of file +} diff --git a/code/tick_render.odin b/code/tick_render.odin index 2295774..f812312 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -150,16 +150,16 @@ render_mode_2d :: proc() computed_size := computed.bounds.p1 - computed.bounds.p0 if ! within_range2( view_bounds, computed.bounds ) { - continue + // continue } // TODO(Ed) : Render Borders // profile_begin("Calculating Raylib rectangles") - render_bounds := Range2 { pts = { + render_bounds := range2( world_to_screen_pos(computed.bounds.min), world_to_screen_pos(computed.bounds.max), - }} + ) render_padding := range2( world_to_screen_pos(computed.padding.min), @@ -172,21 +172,21 @@ render_mode_2d :: proc() rect_bounds := rl.Rectangle { render_bounds.min.x, - render_bounds.min.y, - render_bounds.max.x - render_bounds.min.x, - render_bounds.max.y - render_bounds.min.y, + render_bounds.max.y, + abs(render_bounds.max.x - render_bounds.min.x), + abs(render_bounds.max.y - render_bounds.min.y), } rect_padding := rl.Rectangle { render_padding.min.x, - render_padding.min.y, - render_padding.max.x - render_padding.min.x, - render_padding.max.y - render_padding.min.y, + render_padding.max.y, + abs(render_padding.max.x - render_padding.min.x), + abs(render_padding.max.y - render_padding.min.y), } rect_content := rl.Rectangle { render_content.min.x, - render_content.min.y, - render_content.max.x - render_content.min.x, - render_content.max.y - render_content.min.y, + render_content.max.y, + abs(render_content.max.x - render_content.min.x), + abs(render_content.max.y - render_content.min.y), } // profile_end() @@ -222,7 +222,7 @@ render_mode_2d :: proc() draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Padding_Bounds, line_thickness ) } else { - draw_rectangle_lines( rect_padding, style, Color_Debug_UI_Content_Bounds, line_thickness ) + draw_rectangle_lines( rect_content, style, Color_Debug_UI_Content_Bounds, line_thickness ) } // profile_end() diff --git a/code/tick_update.odin b/code/tick_update.odin index 1d275a3..2b8f1fd 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -231,7 +231,7 @@ update :: proc( delta_time : f64 ) -> b32 frame_style_default, }} frame_theme.disabled.bg_color = Color_Frame_Disabled - // frame_theme.hot.bg_color = Color_Frame_Hover + frame_theme.hot.bg_color = Color_Frame_Hover frame_theme.active.bg_color = Color_Frame_Select ui_style_theme( frame_theme ) @@ -240,20 +240,22 @@ update :: proc( delta_time : f64 ) -> b32 // test_text_box() // test_parenting() - if true + if false { frame := ui_widget( "Frame", {} ) ui_parent(frame) parent_layout := default_layout parent_layout.size = range2( { 300, 300 }, {} ) - parent_layout.alignment = { 0.0, 0.0 } + parent_layout.alignment = { 0.5, 0.5 } + parent_layout.margins = { 100, 100, 100, 100 } parent_layout.padding = {} parent_layout.pos = { 0, 0 } parent_theme := frame_style_default parent_theme.layout = parent_layout parent_theme.flags = { + // .Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, } ui_theme_via_style(parent_theme) @@ -262,7 +264,7 @@ update :: proc( delta_time : f64 ) -> b32 ui_parent(parent) { if parent.first_frame { - debug.draggable_box_pos = parent.style.layout.pos + { 0, 0 } + debug.draggable_box_pos = parent.style.layout.pos debug.draggable_box_size = parent.style.layout.size.min } @@ -285,19 +287,20 @@ update :: proc( delta_time : f64 ) -> b32 parent.style.bg_color = Color_Blue } - parent.style.layout.pos = debug.draggable_box_pos + parent.style.layout.pos = debug.draggable_box_pos parent.style.layout.size.min = debug.draggable_box_size } child_layout := default_layout - child_layout.size = range2({ 50, 50 }, { 200, 200 }) - child_layout.alignment = { 0.0, 0.0 } - child_layout.margins = { 00, 00, 00, 00 } + child_layout.size = range2({ 75, 75 }, { 0, 0 }) + child_layout.alignment = { 0.5, 0.0 } + child_layout.margins = { 20, 20, 20, 20 } child_layout.padding = {} - child_layout.anchor = range2({ 0.0, 0.0 }, { 0.0, 0.0 }) + child_layout.anchor = range2({ 0.0, 0.0 }, { 0.0, 1.0 }) child_layout.pos = { 0, 0 } child_theme := frame_style_default + child_theme.bg_color = Color_GreyRed child_theme.flags = { // .Fixed_Width, .Fixed_Height, } @@ -307,7 +310,7 @@ update :: proc( delta_time : f64 ) -> b32 } // Whitespace AST test - if false + if true { profile("Whitespace AST test") diff --git a/code/ui.odin b/code/ui.odin index 8dcd981..45a0c4f 100644 --- a/code/ui.odin +++ b/code/ui.odin @@ -77,11 +77,13 @@ UI_BoxFlag_Scroll :: UI_BoxFlags { .Scroll_X, .Scroll_Y } // The UI_Box's actual positioning and sizing // There is an excess of rectangles here for debug puproses. UI_Computed :: struct { - bounds : Range2, - padding : Range2, - content : Range2, - text_pos : Vec2, - text_size : Vec2, + anchors : Range2, // Bounds for anchors within parent + margins : Range2, // Bounds for margins within parent + bounds : Range2, // Bounds for box itself + padding : Range2, // Bounds for padding's starting bounds (will be offset by border if there is one) + content : Range2, // Bounds for content (text or children) + text_pos : Vec2, // Position of text within content + text_size : Vec2, // Size of text within content } UI_LayoutSide :: struct { @@ -111,12 +113,6 @@ UI_Key :: distinct u64 UI_Scalar :: f32 -// TODO(Ed): I'm not sure if Percentage is needed or if this would over complicate things... -// UI_Scalar :: struct { -// VPixels : f32, -// Percentage : f32, -// } - UI_ScalarConstraint :: struct { min, max : UI_Scalar, } @@ -125,10 +121,6 @@ UI_Scalar2 :: [Axis2.Count]UI_Scalar // Desiered constraints on the UI_Box. UI_Layout :: struct { - // TODO(Ed) : Should layout have its own flags (separate from the style flags) - // flags : UI_LayoutFlags - - // TODO(Ed) : Make sure this is all we need to represent an anchor. anchor : Range2, alignment : Vec2, text_alignment : Vec2, @@ -145,7 +137,6 @@ UI_Layout :: struct { // If the box's flags has Fixed_Position, then this will be its aboslute position in the relative coordinate space pos : Vec2, - // TODO(Ed): Support a min/max range for the size of a box size : Range2, // TODO(Ed) : Should thsi just always be WS_Pos for workspace UI? @@ -178,16 +169,21 @@ UI_StyleFlag :: enum u32 { // (Specified in the parent) Clip_Children_To_Bounds, - // Enforces the widget will always remain in a specific position relative to the parent. + // Enforces the box will always remain in a specific position relative to the parent. // Overriding the anchors and margins. Fixed_Position_X, Fixed_Position_Y, + // Enforces box will always be within the bounds of the parent box. + Clamp_Position_X, + Clamp_Position_Y, + // Enroces the widget will maintain its size reguardless of any constraints // Will override parent constraints Fixed_Width, Fixed_Height, + // Will size the box to its text. (Padding & Margins will thicken ) Size_To_Text, Text_Wrap, @@ -266,8 +262,8 @@ UI_Box :: struct { // prev_computed : UI_Computed, // prev_style : UI_Style,v - mouse : UI_InteractState, - keyboard : UI_InteractState, + // mouse : UI_InteractState, + // keyboard : UI_InteractState, } // UI_BoxFlags_Stack_Size :: 512 diff --git a/code/ui_layout.odin b/code/ui_layout.odin index 3d0e683..95a9489 100644 --- a/code/ui_layout.odin +++ b/code/ui_layout.odin @@ -11,28 +11,18 @@ ui_compute_layout :: proc() root := state.project.workspace.ui.root { computed := & root.computed - bounds := & computed.bounds style := root.style layout := & style.layout - - bounds.min = layout.pos - bounds.max = layout.size.min - - computed.content = bounds^ - computed.padding = {} + computed.bounds.min = layout.pos + computed.bounds.max = layout.size.min + computed.content = computed.bounds } current := root.first for ; current != nil; { profile("Layout Box") - parent := current.parent - parent_content := parent.computed.content - computed := & current.computed - style := current.style - layout := & style.layout - // These are used to choose via multiplication weather to apply // position & size constraints of the parent. @@ -46,51 +36,23 @@ ui_compute_layout :: proc() size_to_text : bool = .Size_To_Text in style.flags + parent := current.parent + computed := & current.computed - margins := range2( - { layout.margins.left, -layout.margins.top }, - { -layout.margins.right, layout.margins.bottom }, - ) - margined_bounds := range2( - parent_content.p0 + margins.p0, - parent_content.p1 + margins.p1, - ) - margined_size := linalg.abs(margined_bounds.p1 - margined_bounds.p0) - - anchor := & layout.anchor - // Margins + Anchors Applied - adjusted_bounds := range2( - { margined_bounds.p0.x + margined_size.x * anchor.p0.x, margined_bounds.p0.y + margined_size.y * anchor.p0.y }, - { margined_bounds.p1.x + margined_size.x * anchor.p1.x, margined_bounds.p1.y + margined_size.y * anchor.p1.y }, - ) - adjusted_bounds_size := linalg.abs(adjusted_bounds.p1 - adjusted_bounds.p0) - - // Resolves final constrained bounds of the parent for the child box - // Will be applied to the box after the child's positon is resolved. - - fixed_pos := Vec2 { fixed_pos_x, fixed_pos_y } - constraint_min := adjusted_bounds.min //* (1 - fixed_pos) + parent_content.min * fixed_pos - constraint_max := adjusted_bounds.max //* (1 - fixed_pos) + parent_content.max * fixed_pos - - // constraint_min_x := adjusted_bounds.min.x //* (1 - fixed_pos_x) + parent_content.min.x * fixed_pos_x - // constraint_min_y := adjusted_bounds.min.y //* (1 - fixed_pos_y) + parent_content.min.y * fixed_pos_y - // constraint_max_x := adjusted_bounds.max.x //* (1 - fixed_pos_x) + parent_content.max.x * fixed_pos_x - // constraint_max_y := adjusted_bounds.max.y //* (1 - fixed_pos_y) + parent_content.max.y * fixed_pos_y - - constrained_bounds := range2( - constraint_min, - constraint_max, - // { constraint_min_x, constraint_min_y }, - // { constraint_max_x, constraint_max_y }, - ) - constrained_size := linalg.abs(constrained_bounds.p1 - constrained_bounds.p0) + parent_content := parent.computed.content + parent_content_size := parent_content.max - parent_content.min + parent_center := parent_content.min + parent_content_size * 0.5 + layout := & style.layout /* If fixed position (X or Y): * Ignore Margins * Ignore Anchors + If clampped position (X or Y): + * Positon cannot exceed the anchors/margins bounds. + If fixed size (X or Y): * Ignore Parent constraints (can only be clipped) @@ -102,118 +64,53 @@ ui_compute_layout :: proc() If size.min is not 0: * Ignore parent constraints if the bounds go below that value. - If size.max is not 0: - * Allow the child box to spread to entire adjusted content bounds. + If size.max is 0: + * Allow the child box to spread to entire adjusted content bounds, otherwise clampped to max size. */ - size_unit_bounds := range2( - { 0.0, 0.0 }, - { 1.0, -1.0 }, + // 1. Anchors + anchor := & layout.anchor + // anchored_pos := parent_content.min + parent_content_size * anchor.min + // anchored_size := parent_content_size * linalg.abs( anchor.p1 - anchor.p0 ) + anchored_bounds := range2( + { + parent_content.min.x + parent_content_size.x * anchor.min.x, + parent_content.min.y + parent_content_size.y * anchor.min.y, + }, + { + parent_content.max.x - parent_content_size.x * anchor.max.x, + parent_content.max.y - parent_content_size.y * anchor.max.y, + } ) + anchored_bounds_origin := (anchored_bounds.min + anchored_bounds.max) * 0.5 - alignment := layout.alignment - aligned_unit_bounds := range2( - size_unit_bounds.p0 + { -alignment.x, alignment.y }, - size_unit_bounds.p1 - { alignment.x, -alignment.y }, + // 2. Apply Margins + margins := range2( + { layout.margins.left, layout.margins.bottom }, + { layout.margins.right, layout.margins.top }, ) - - wtf := range2( - { constrained_bounds.p0.x, constrained_bounds.p0.y }, - { constrained_bounds.p1.x, constrained_bounds.p1.y }, + margined_bounds := range2( + anchored_bounds.min + margins.min, + anchored_bounds.max - margins.max, ) + margined_bounds_origin := (margined_bounds.min + margined_bounds.max) * 0.5 + margined_size := margined_bounds.max - margined_bounds.min - // projected_bounds := range2( - // aligned_unit_bounds.p0 * wtf.p0, - // aligned_unit_bounds.p1 * wtf.p1, - // ) + // 3. Enforce Min/Max Size Constraints + adjusted_max_size_x := layout.size.max.x > 0 ? min( margined_size.x, layout.size.max.x ) : margined_size.x + adjusted_max_size_y := layout.size.max.y > 0 ? min( margined_size.y, layout.size.max.y ) : margined_size.y + adjusted_size : Vec2 + adjusted_size.x = max( adjusted_max_size_x, layout.size.min.x) + adjusted_size.y = max( adjusted_max_size_y, layout.size.min.y) - constrained_half_size := constrained_size * 0.5 - min_half_size := layout.size.min * 0.5 - max_half_size := layout.size.max * 0.5 - half_size := linalg.max( constrained_half_size, min_half_size ) - half_size = linalg.min( half_size, max_half_size ) - - projected_bounds := range2( - aligned_unit_bounds.p0 * half_size, - aligned_unit_bounds.p1 * half_size, - ) - - rel_projected_bounds := range2( - layout.pos + projected_bounds.p0, - layout.pos + projected_bounds.p1, - ) - - bounds : Range2 - - // Resolve and apply the size constraint based off of positon of box and the constrained bounds - - // Check to see if left or right side is over - if ! (.Fixed_Width in style.flags) - { - bounds.p0.x = rel_projected_bounds.p0.x < constrained_bounds.p0.x ? constrained_bounds.p0.x : rel_projected_bounds.p0.x - bounds.p1.x = rel_projected_bounds.p1.x > constrained_bounds.p1.x ? constrained_bounds.p1.x : rel_projected_bounds.p1.x + if .Fixed_Width in style.flags { + adjusted_size.x = layout.size.min.x } - else { - size_unit_bounds := range2( - { 0.0, 0.0 }, - { 1.0, -1.0 }, - ) - - alignment := layout.alignment - aligned_unit_bounds := range2( - size_unit_bounds.p0 + { -alignment.x, alignment.y }, - size_unit_bounds.p1 - { alignment.x, -alignment.y }, - ) - - // Apply size.p0.x directly - bounds.p0.x = aligned_unit_bounds.p0.x * layout.size.min.x - bounds.p1.x = aligned_unit_bounds.p1.x * layout.size.min.x - - bounds.p0.x += constrained_bounds.p0.x - bounds.p1.x += constrained_bounds.p0.x - - bounds.p0.x += layout.pos.x - bounds.p1.x += layout.pos.x + if .Fixed_Height in style.flags { + adjusted_size.y = layout.size.min.y } - if ! (.Fixed_Height in style.flags) - { - bounds.p0.y = rel_projected_bounds.p0.y > constrained_bounds.p0.y ? constrained_bounds.p0.y : rel_projected_bounds.p0.y - bounds.p1.y = rel_projected_bounds.p1.y < constrained_bounds.p1.y ? constrained_bounds.p1.y : rel_projected_bounds.p1.y - } - else { - size_unit_bounds := range2( - { 0.0, 0.0 }, - { 1.0, -1.0 }, - ) - - alignment := layout.alignment - aligned_unit_bounds := range2( - size_unit_bounds.p0 + { -alignment.x, alignment.y }, - size_unit_bounds.p1 - { alignment.x, -alignment.y }, - ) - - // Apply size.p0.y directly - bounds.p0.y = aligned_unit_bounds.p0.y * layout.size.min.y - bounds.p1.y = aligned_unit_bounds.p1.y * layout.size.min.y - - bounds.p0.y += constrained_bounds.p0.y //+ aligned_unit_bounds - bounds.p1.y += constrained_bounds.p0.y //+ aligned_unit_bounds - - bounds.p0.y += layout.pos.y - bounds.p1.y += layout.pos.y - } - - // Enforce the min/max size - bounds_size := bounds.p1 - bounds.p0 - // if bounds_size > layout.size.max { - // Enforce max - - - // } - - text_size : Vec2 // If the computed matches, we already have the size, don't bother. if current.first_frame || ! size_to_text || computed.text_size.y != size_range2(computed.bounds).y { @@ -222,36 +119,65 @@ ui_compute_layout :: proc() else { text_size = computed.text_size } - if size_to_text { - // size = text_size + + // 4. Adjust Alignment of pivot position + alignment := layout.alignment + alignment_offset := Vec2 { + // adjusted_size.x * (alignment.x - 0.5), + // adjusted_size.y * (alignment.y - 0.5), } + // 5. Determine relative position - computed.bounds = bounds + // TODO(Ed): Let the user determine the coordinate space origin? + // rel_pos := margined_bounds_origin + alignment_offset + layout.pos + rel_pos := margined_bounds_origin + layout.pos - border_offset := Vec2 { layout.border_width, layout.border_width } - padding := & computed.padding - (padding^) = range2( - bounds.p0 + border_offset, - bounds.p1 + border_offset, + if .Fixed_Position_X in style.flags { + rel_pos.x = parent_center.x + layout.pos.x + } + if .Fixed_Position_Y in style.flags { + rel_pos.y = parent_center.y + layout.pos.y + } + + vec2_one := Vec2 { 1, 1 } + + // Determine the box bounds + bounds := range2( + rel_pos - adjusted_size * alignment, + rel_pos + adjusted_size * (vec2_one - alignment), ) - content := & computed.content - (content^) = range2( - bounds.p0 + { layout.padding.left, -layout.padding.top }, - bounds.p1 + { -layout.padding.right, layout.padding.bottom }, + // Determine Padding's outer bounds + border_offset := Vec2 { layout.border_width, layout.border_width } + + padding_bounds := range2( + bounds.min + border_offset, + bounds.min - border_offset, ) - // Text + // Determine Content Bounds + content_bounds := range2( + bounds.min + { layout.padding.left, layout.padding.bottom }, + bounds.max - { layout.padding.right, layout.padding.top }, + ) + + computed.anchors = anchored_bounds + computed.margins = margined_bounds + computed.bounds = bounds + computed.padding = padding_bounds + computed.content = content_bounds + + // TODO(Ed): Needs a rework based on changes to rest of layout above being changed + // Text if len(current.text.str) > 0 { - // profile("Text") - top_left := content.p0 - bottom_right := content.p1 + bottom_left := content_bounds.min + top_right := content_bounds.max - content_size := Vec2 { top_left.x - bottom_right.x, top_left.y - bottom_right.y } + content_size := Vec2 { top_right.x - bottom_left.x, top_right.y - bottom_left.y } text_pos : Vec2 - text_pos = top_left + text_pos = top_right text_pos.x += (-content_size.x - text_size.x) * layout.text_alignment.x text_pos.y += (-content_size.y + text_size.y) * layout.text_alignment.y diff --git a/code/ui_tests.odin b/code/ui_tests.odin index 5795a6a..a12f728 100644 --- a/code/ui_tests.odin +++ b/code/ui_tests.odin @@ -89,4 +89,4 @@ test_text_box :: proc() } text_box.style.layout.pos = pos -} \ No newline at end of file +} diff --git a/examples/Lorem Ipsum.txt b/examples/Lorem Ipsum.txt index 9fdaacf..96238d2 100644 --- a/examples/Lorem Ipsum.txt +++ b/examples/Lorem Ipsum.txt @@ -60,199 +60,3 @@ Curabitur egestas laoreet mauris sed cursus. Duis nec purus vel nibh venenatis dignissim. Nam eget aliquam eros, vitae pellentesque neque. Praesent mollis augue risus, ut commodo arcu auctor vel. - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. -Aenean ut elementum leo, eu luctus lorem. -Sed sit amet dapibus odio, at porttitor magna. -Cras id justo et risus porta eleifend. -Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. -Maecenas faucibus odio nisl, non posuere felis laoreet et. -Nullam tincidunt varius lacus sit amet laoreet. -Proin sodales vestibulum dolor, non condimentum arcu sodales nec. -Sed a tortor pharetra ante vehicula porta. -Maecenas congue venenatis euismod. -Suspendisse dapibus id lorem efficitur faucibus. -Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. - -Cras a semper metus, et porttitor tortor. -Aenean ac nisi consectetur, fermentum leo et, elementum odio. -Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. -Maecenas vel luctus nibh. Morbi eget nisl justo. -Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. -Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. -Vivamus mollis ligula a ligula commodo ultrices. -Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. -Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. - -Integer urna ligula, auctor ac sapien et, volutpat elementum leo. -Ut commodo arcu a turpis tempor, id semper justo egestas. -Aliquam erat volutpat. -Sed placerat malesuada eros. -Suspendisse egestas auctor magna a aliquam. -Pellentesque interdum pretium hendrerit. -Sed eget libero massa. -Nam egestas viverra odio, et ultrices risus scelerisque vel. -Nunc sodales laoreet elementum. -Mauris et risus nec erat placerat lobortis. -Donec ultrices eleifend mi. -Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. -Phasellus et ligula nisl. - -Sed dui enim, efficitur quis viverra nec, facilisis sed est. -Proin eget lectus diam. -Nullam in purus elementum, pharetra eros sed, volutpat metus. -Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. -Aliquam sit amet dolor id justo aliquam cursus. -Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. -Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. -Nam nec condimentum lacus, at pellentesque sem. -Pellentesque tristique pulvinar aliquet. -Sed varius dolor in sapien varius, sed blandit ipsum viverra. -Duis consectetur lacus dolor, non pellentesque enim pulvinar a. - -Proin id leo vel ligula hendrerit facilisis. -Sed fringilla tellus est, non pretium sem consectetur fermentum. -Nam a tellus augue. -Suspendisse quis odio nibh. -Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. -Phasellus purus ex, mollis at ante at, convallis interdum tellus. -Proin at porttitor mauris, ut egestas ligula. -Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. -Curabitur egestas laoreet mauris sed cursus. -Duis nec purus vel nibh venenatis dignissim. -Nam eget aliquam eros, vitae pellentesque neque. -Praesent mollis augue risus, ut commodo arcu auctor vel. - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. -Aenean ut elementum leo, eu luctus lorem. -Sed sit amet dapibus odio, at porttitor magna. -Cras id justo et risus porta eleifend. -Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. -Maecenas faucibus odio nisl, non posuere felis laoreet et. -Nullam tincidunt varius lacus sit amet laoreet. -Proin sodales vestibulum dolor, non condimentum arcu sodales nec. -Sed a tortor pharetra ante vehicula porta. -Maecenas congue venenatis euismod. -Suspendisse dapibus id lorem efficitur faucibus. -Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. - -Cras a semper metus, et porttitor tortor. -Aenean ac nisi consectetur, fermentum leo et, elementum odio. -Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. -Maecenas vel luctus nibh. Morbi eget nisl justo. -Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. -Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. -Vivamus mollis ligula a ligula commodo ultrices. -Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. -Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. - -Integer urna ligula, auctor ac sapien et, volutpat elementum leo. -Ut commodo arcu a turpis tempor, id semper justo egestas. -Aliquam erat volutpat. -Sed placerat malesuada eros. -Suspendisse egestas auctor magna a aliquam. -Pellentesque interdum pretium hendrerit. -Sed eget libero massa. -Nam egestas viverra odio, et ultrices risus scelerisque vel. -Nunc sodales laoreet elementum. -Mauris et risus nec erat placerat lobortis. -Donec ultrices eleifend mi. -Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. -Phasellus et ligula nisl. - -Sed dui enim, efficitur quis viverra nec, facilisis sed est. -Proin eget lectus diam. -Nullam in purus elementum, pharetra eros sed, volutpat metus. -Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. -Aliquam sit amet dolor id justo aliquam cursus. -Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. -Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. -Nam nec condimentum lacus, at pellentesque sem. -Pellentesque tristique pulvinar aliquet. -Sed varius dolor in sapien varius, sed blandit ipsum viverra. -Duis consectetur lacus dolor, non pellentesque enim pulvinar a. - -Proin id leo vel ligula hendrerit facilisis. -Sed fringilla tellus est, non pretium sem consectetur fermentum. -Nam a tellus augue. -Suspendisse quis odio nibh. -Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. -Phasellus purus ex, mollis at ante at, convallis interdum tellus. -Proin at porttitor mauris, ut egestas ligula. -Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. -Curabitur egestas laoreet mauris sed cursus. -Duis nec purus vel nibh venenatis dignissim. -Nam eget aliquam eros, vitae pellentesque neque. -Praesent mollis augue risus, ut commodo arcu auctor vel. - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. -Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. -Aenean ut elementum leo, eu luctus lorem. -Sed sit amet dapibus odio, at porttitor magna. -Cras id justo et risus porta eleifend. -Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. -Maecenas faucibus odio nisl, non posuere felis laoreet et. -Nullam tincidunt varius lacus sit amet laoreet. -Proin sodales vestibulum dolor, non condimentum arcu sodales nec. -Sed a tortor pharetra ante vehicula porta. -Maecenas congue venenatis euismod. -Suspendisse dapibus id lorem efficitur faucibus. -Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. - -Cras a semper metus, et porttitor tortor. -Aenean ac nisi consectetur, fermentum leo et, elementum odio. -Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. -Maecenas vel luctus nibh. Morbi eget nisl justo. -Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. -Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. -Vivamus mollis ligula a ligula commodo ultrices. -Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. -Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. - -Integer urna ligula, auctor ac sapien et, volutpat elementum leo. -Ut commodo arcu a turpis tempor, id semper justo egestas. -Aliquam erat volutpat. -Sed placerat malesuada eros. -Suspendisse egestas auctor magna a aliquam. -Pellentesque interdum pretium hendrerit. -Sed eget libero massa. -Nam egestas viverra odio, et ultrices risus scelerisque vel. -Nunc sodales laoreet elementum. -Mauris et risus nec erat placerat lobortis. -Donec ultrices eleifend mi. -Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. -Phasellus et ligula nisl. - -Sed dui enim, efficitur quis viverra nec, facilisis sed est. -Proin eget lectus diam. -Nullam in purus elementum, pharetra eros sed, volutpat metus. -Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. -Aliquam sit amet dolor id justo aliquam cursus. -Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. -Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. -Nam nec condimentum lacus, at pellentesque sem. -Pellentesque tristique pulvinar aliquet. -Sed varius dolor in sapien varius, sed blandit ipsum viverra. -Duis consectetur lacus dolor, non pellentesque enim pulvinar a. - -Proin id leo vel ligula hendrerit facilisis. -Sed fringilla tellus est, non pretium sem consectetur fermentum. -Nam a tellus augue. -Suspendisse quis odio nibh. -Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. -Phasellus purus ex, mollis at ante at, convallis interdum tellus. -Proin at porttitor mauris, ut egestas ligula. -Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. -Curabitur egestas laoreet mauris sed cursus. -Duis nec purus vel nibh venenatis dignissim. -Nam eget aliquam eros, vitae pellentesque neque. -Praesent mollis augue risus, ut commodo arcu auctor vel. - - - - diff --git a/examples/temp.txt b/examples/temp.txt new file mode 100644 index 0000000..6b1b5ba --- /dev/null +++ b/examples/temp.txt @@ -0,0 +1,196 @@ + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Aenean ut elementum leo, eu luctus lorem. +Sed sit amet dapibus odio, at porttitor magna. +Cras id justo et risus porta eleifend. +Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. +Maecenas faucibus odio nisl, non posuere felis laoreet et. +Nullam tincidunt varius lacus sit amet laoreet. +Proin sodales vestibulum dolor, non condimentum arcu sodales nec. +Sed a tortor pharetra ante vehicula porta. +Maecenas congue venenatis euismod. +Suspendisse dapibus id lorem efficitur faucibus. +Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. + +Cras a semper metus, et porttitor tortor. +Aenean ac nisi consectetur, fermentum leo et, elementum odio. +Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. +Maecenas vel luctus nibh. Morbi eget nisl justo. +Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. +Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. +Vivamus mollis ligula a ligula commodo ultrices. +Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. +Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. + +Integer urna ligula, auctor ac sapien et, volutpat elementum leo. +Ut commodo arcu a turpis tempor, id semper justo egestas. +Aliquam erat volutpat. +Sed placerat malesuada eros. +Suspendisse egestas auctor magna a aliquam. +Pellentesque interdum pretium hendrerit. +Sed eget libero massa. +Nam egestas viverra odio, et ultrices risus scelerisque vel. +Nunc sodales laoreet elementum. +Mauris et risus nec erat placerat lobortis. +Donec ultrices eleifend mi. +Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. +Phasellus et ligula nisl. + +Sed dui enim, efficitur quis viverra nec, facilisis sed est. +Proin eget lectus diam. +Nullam in purus elementum, pharetra eros sed, volutpat metus. +Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. +Aliquam sit amet dolor id justo aliquam cursus. +Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. +Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. +Nam nec condimentum lacus, at pellentesque sem. +Pellentesque tristique pulvinar aliquet. +Sed varius dolor in sapien varius, sed blandit ipsum viverra. +Duis consectetur lacus dolor, non pellentesque enim pulvinar a. + +Proin id leo vel ligula hendrerit facilisis. +Sed fringilla tellus est, non pretium sem consectetur fermentum. +Nam a tellus augue. +Suspendisse quis odio nibh. +Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. +Phasellus purus ex, mollis at ante at, convallis interdum tellus. +Proin at porttitor mauris, ut egestas ligula. +Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. +Curabitur egestas laoreet mauris sed cursus. +Duis nec purus vel nibh venenatis dignissim. +Nam eget aliquam eros, vitae pellentesque neque. +Praesent mollis augue risus, ut commodo arcu auctor vel. + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Aenean ut elementum leo, eu luctus lorem. +Sed sit amet dapibus odio, at porttitor magna. +Cras id justo et risus porta eleifend. +Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. +Maecenas faucibus odio nisl, non posuere felis laoreet et. +Nullam tincidunt varius lacus sit amet laoreet. +Proin sodales vestibulum dolor, non condimentum arcu sodales nec. +Sed a tortor pharetra ante vehicula porta. +Maecenas congue venenatis euismod. +Suspendisse dapibus id lorem efficitur faucibus. +Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. + +Cras a semper metus, et porttitor tortor. +Aenean ac nisi consectetur, fermentum leo et, elementum odio. +Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. +Maecenas vel luctus nibh. Morbi eget nisl justo. +Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. +Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. +Vivamus mollis ligula a ligula commodo ultrices. +Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. +Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. + +Integer urna ligula, auctor ac sapien et, volutpat elementum leo. +Ut commodo arcu a turpis tempor, id semper justo egestas. +Aliquam erat volutpat. +Sed placerat malesuada eros. +Suspendisse egestas auctor magna a aliquam. +Pellentesque interdum pretium hendrerit. +Sed eget libero massa. +Nam egestas viverra odio, et ultrices risus scelerisque vel. +Nunc sodales laoreet elementum. +Mauris et risus nec erat placerat lobortis. +Donec ultrices eleifend mi. +Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. +Phasellus et ligula nisl. + +Sed dui enim, efficitur quis viverra nec, facilisis sed est. +Proin eget lectus diam. +Nullam in purus elementum, pharetra eros sed, volutpat metus. +Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. +Aliquam sit amet dolor id justo aliquam cursus. +Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. +Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. +Nam nec condimentum lacus, at pellentesque sem. +Pellentesque tristique pulvinar aliquet. +Sed varius dolor in sapien varius, sed blandit ipsum viverra. +Duis consectetur lacus dolor, non pellentesque enim pulvinar a. + +Proin id leo vel ligula hendrerit facilisis. +Sed fringilla tellus est, non pretium sem consectetur fermentum. +Nam a tellus augue. +Suspendisse quis odio nibh. +Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. +Phasellus purus ex, mollis at ante at, convallis interdum tellus. +Proin at porttitor mauris, ut egestas ligula. +Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. +Curabitur egestas laoreet mauris sed cursus. +Duis nec purus vel nibh venenatis dignissim. +Nam eget aliquam eros, vitae pellentesque neque. +Praesent mollis augue risus, ut commodo arcu auctor vel. + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi laoreet bibendum finibus. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Aenean ut elementum leo, eu luctus lorem. +Sed sit amet dapibus odio, at porttitor magna. +Cras id justo et risus porta eleifend. +Donec fringilla porta faucibus. Maecenas metus dolor, ornare eu justo sed, mattis porta ante. +Maecenas faucibus odio nisl, non posuere felis laoreet et. +Nullam tincidunt varius lacus sit amet laoreet. +Proin sodales vestibulum dolor, non condimentum arcu sodales nec. +Sed a tortor pharetra ante vehicula porta. +Maecenas congue venenatis euismod. +Suspendisse dapibus id lorem efficitur faucibus. +Aliquam consectetur urna in turpis consectetur, eu vehicula diam egestas. + +Cras a semper metus, et porttitor tortor. +Aenean ac nisi consectetur, fermentum leo et, elementum odio. +Etiam imperdiet quam tellus, non suscipit lectus mattis ut. Nulla egestas urna vitae ex consectetur aliquam. +Maecenas vel luctus nibh. Morbi eget nisl justo. +Donec condimentum dolor id quam lacinia, vel ullamcorper mauris gravida. +Aliquam erat volutpat. Aliquam vitae neque venenatis, ultrices dui non, ornare velit. +Vivamus mollis ligula a ligula commodo ultrices. +Pellentesque ante felis, ultrices in risus eu, faucibus tincidunt ante. +Suspendisse potenti. Sed eget ligula mauris. Donec lorem est, porttitor auctor varius sed, lobortis nec eros. + +Integer urna ligula, auctor ac sapien et, volutpat elementum leo. +Ut commodo arcu a turpis tempor, id semper justo egestas. +Aliquam erat volutpat. +Sed placerat malesuada eros. +Suspendisse egestas auctor magna a aliquam. +Pellentesque interdum pretium hendrerit. +Sed eget libero massa. +Nam egestas viverra odio, et ultrices risus scelerisque vel. +Nunc sodales laoreet elementum. +Mauris et risus nec erat placerat lobortis. +Donec ultrices eleifend mi. +Nullam tempus, felis at sodales finibus, libero mauris luctus sem, vehicula dictum lectus quam et lectus. +Phasellus et ligula nisl. + +Sed dui enim, efficitur quis viverra nec, facilisis sed est. +Proin eget lectus diam. +Nullam in purus elementum, pharetra eros sed, volutpat metus. +Vestibulum pellentesque efficitur mauris, ut iaculis purus vehicula imperdiet. +Aliquam sit amet dolor id justo aliquam cursus. +Etiam mollis, tellus ut iaculis molestie, nunc libero feugiat arcu, vitae mattis neque leo a erat. +Pellentesque non ex interdum nulla faucibus tincidunt in vel magna. +Nam nec condimentum lacus, at pellentesque sem. +Pellentesque tristique pulvinar aliquet. +Sed varius dolor in sapien varius, sed blandit ipsum viverra. +Duis consectetur lacus dolor, non pellentesque enim pulvinar a. + +Proin id leo vel ligula hendrerit facilisis. +Sed fringilla tellus est, non pretium sem consectetur fermentum. +Nam a tellus augue. +Suspendisse quis odio nibh. +Cras pellentesque turpis a mauris euismod, vel posuere enim eleifend. +Phasellus purus ex, mollis at ante at, convallis interdum tellus. +Proin at porttitor mauris, ut egestas ligula. +Suspendisse ultricies commodo lorem, quis auctor turpis efficitur ut. +Curabitur egestas laoreet mauris sed cursus. +Duis nec purus vel nibh venenatis dignissim. +Nam eget aliquam eros, vitae pellentesque neque. +Praesent mollis augue risus, ut commodo arcu auctor vel. + + + + diff --git a/thirdparty/Odin b/thirdparty/Odin index f117910..2949802 160000 --- a/thirdparty/Odin +++ b/thirdparty/Odin @@ -1 +1 @@ -Subproject commit f1179108350444082586504328ae55b989062c45 +Subproject commit 2949802070036a5971fa6d286a3f1f280d9eaa4b