Add future dependencies
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# Local build outputs
|
||||
game_msan
|
||||
game
|
||||
*.bin
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "odin-imgui"]
|
||||
path = odin-imgui
|
||||
url = https://github.com/Capati/odin-imgui.git
|
||||
@@ -0,0 +1,601 @@
|
||||
package clay
|
||||
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import Clay "windows/clay.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import Clay "linux/clay.a"
|
||||
} else when ODIN_OS == .Darwin {
|
||||
when ODIN_ARCH == .arm64 {
|
||||
foreign import Clay "macos-arm64/clay.a"
|
||||
} else {
|
||||
foreign import Clay "macos/clay.a"
|
||||
}
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
foreign import Clay "wasm/clay.o"
|
||||
}
|
||||
|
||||
String :: struct {
|
||||
isStaticallyAllocated: c.bool,
|
||||
length: c.int32_t,
|
||||
chars: [^]c.char,
|
||||
}
|
||||
|
||||
StringSlice :: struct {
|
||||
length: c.int32_t,
|
||||
chars: [^]c.char,
|
||||
baseChars: [^]c.char,
|
||||
}
|
||||
|
||||
Vector2 :: [2]c.float
|
||||
|
||||
Dimensions :: struct {
|
||||
width: c.float,
|
||||
height: c.float,
|
||||
}
|
||||
|
||||
Arena :: struct {
|
||||
nextAllocation: uintptr,
|
||||
capacity: c.size_t,
|
||||
memory: [^]c.char,
|
||||
}
|
||||
|
||||
BoundingBox :: struct {
|
||||
x: c.float,
|
||||
y: c.float,
|
||||
width: c.float,
|
||||
height: c.float,
|
||||
}
|
||||
|
||||
Color :: [4]c.float
|
||||
|
||||
CornerRadius :: struct {
|
||||
topLeft: c.float,
|
||||
topRight: c.float,
|
||||
bottomLeft: c.float,
|
||||
bottomRight: c.float,
|
||||
}
|
||||
|
||||
ElementId :: struct {
|
||||
id: u32,
|
||||
offset: u32,
|
||||
baseId: u32,
|
||||
stringId: String,
|
||||
}
|
||||
|
||||
ElementIdArray :: struct {
|
||||
capacity: i32,
|
||||
length: i32,
|
||||
internalArray: [^]ElementId,
|
||||
}
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
EnumBackingType :: u32
|
||||
} else {
|
||||
EnumBackingType :: u8
|
||||
}
|
||||
|
||||
RenderCommandType :: enum EnumBackingType {
|
||||
None,
|
||||
Rectangle,
|
||||
Border,
|
||||
Text,
|
||||
Image,
|
||||
ScissorStart,
|
||||
ScissorEnd,
|
||||
OverlayColorStart,
|
||||
OverlayColorEnd,
|
||||
Custom,
|
||||
}
|
||||
|
||||
RectangleElementConfig :: struct {
|
||||
color: Color,
|
||||
}
|
||||
|
||||
TextWrapMode :: enum EnumBackingType {
|
||||
Words,
|
||||
Newlines,
|
||||
None,
|
||||
}
|
||||
|
||||
TextAlignment :: enum EnumBackingType {
|
||||
Left,
|
||||
Center,
|
||||
Right,
|
||||
}
|
||||
|
||||
TextElementConfig :: struct {
|
||||
userData: rawptr,
|
||||
textColor: Color,
|
||||
fontId: u16,
|
||||
fontSize: u16,
|
||||
letterSpacing: u16,
|
||||
lineHeight: u16,
|
||||
wrapMode: TextWrapMode,
|
||||
textAlignment: TextAlignment,
|
||||
}
|
||||
|
||||
AspectRatioElementConfig :: struct {
|
||||
aspectRatio: f32,
|
||||
}
|
||||
|
||||
ImageElementConfig :: struct {
|
||||
imageData: rawptr,
|
||||
}
|
||||
|
||||
CustomElementConfig :: struct {
|
||||
customData: rawptr,
|
||||
}
|
||||
|
||||
BorderWidth :: struct {
|
||||
left: u16,
|
||||
right: u16,
|
||||
top: u16,
|
||||
bottom: u16,
|
||||
betweenChildren: u16,
|
||||
}
|
||||
|
||||
BorderElementConfig :: struct {
|
||||
color: Color,
|
||||
width: BorderWidth,
|
||||
}
|
||||
|
||||
TransitionData :: struct {
|
||||
boundingBox: BoundingBox,
|
||||
backgroundColor: Color,
|
||||
overlayColor: Color,
|
||||
borderColor: Color,
|
||||
borderWidth: BorderWidth,
|
||||
}
|
||||
|
||||
TransitionState :: enum c.int {
|
||||
Idle,
|
||||
Entering,
|
||||
Transitioning,
|
||||
Exiting,
|
||||
}
|
||||
|
||||
TransitionProperty :: enum c.int {
|
||||
X,
|
||||
Y,
|
||||
Width,
|
||||
Height,
|
||||
BackgroundColor,
|
||||
OverlayColor,
|
||||
CornerRadius,
|
||||
BorderColor,
|
||||
BorderWidth,
|
||||
}
|
||||
|
||||
TransitionPropertyFlags :: bit_set[TransitionProperty;c.int]
|
||||
TransitionPropertyPosition :: TransitionPropertyFlags{.X, .Y}
|
||||
TransitionPropertyDimensions :: TransitionPropertyFlags{.Width, .Height}
|
||||
TransitionPropertyBoundingBox :: TransitionPropertyPosition + TransitionPropertyDimensions
|
||||
TransitionPropertyBorder :: TransitionPropertyFlags{.BorderColor, .BorderWidth}
|
||||
|
||||
TransitionCallbackArguments :: struct {
|
||||
transitionState: TransitionState,
|
||||
initial: TransitionData,
|
||||
current: ^TransitionData,
|
||||
target: TransitionData,
|
||||
elapsedTime: f32,
|
||||
duration: f32,
|
||||
properties: TransitionPropertyFlags,
|
||||
}
|
||||
|
||||
TransitionEnterTriggerType :: enum EnumBackingType {
|
||||
SkipOnFirstParentFrame,
|
||||
TriggerOnFirstParentFrame,
|
||||
}
|
||||
|
||||
TransitionExitTriggerType :: enum EnumBackingType {
|
||||
SkipWhenParentExits,
|
||||
TriggerWhenParentExits,
|
||||
}
|
||||
|
||||
TransitionInteractionHandlingType :: enum EnumBackingType {
|
||||
DisableInteractionsWhileTransitioningPosition,
|
||||
AllowInteractionsWhileTransitioningPosition,
|
||||
}
|
||||
|
||||
ExitTransitionSiblingOrdering :: enum EnumBackingType {
|
||||
UnderneathSiblings,
|
||||
NaturalOrder,
|
||||
AboveSiblings,
|
||||
}
|
||||
|
||||
TransitionElementConfig :: struct {
|
||||
handler: proc "c" (args: TransitionCallbackArguments) -> bool,
|
||||
duration: f32,
|
||||
properties: TransitionPropertyFlags,
|
||||
interactionHandling: TransitionInteractionHandlingType,
|
||||
enter: struct {
|
||||
setInitialState: proc "c" (initialState: TransitionData, properties: TransitionPropertyFlags) -> TransitionData,
|
||||
trigger: TransitionEnterTriggerType,
|
||||
},
|
||||
exit: struct {
|
||||
setFinalState: proc "c" (finalState: TransitionData, properties: TransitionPropertyFlags) -> TransitionData,
|
||||
trigger: TransitionExitTriggerType,
|
||||
siblingOrdering: ExitTransitionSiblingOrdering,
|
||||
},
|
||||
}
|
||||
|
||||
ClipElementConfig :: struct {
|
||||
horizontal: bool, // clip overflowing elements on the "X" axis
|
||||
vertical: bool, // clip overflowing elements on the "Y" axis
|
||||
childOffset: Vector2, // offsets the [X,Y] positions of all child elements, primarily for scrolling containers
|
||||
}
|
||||
|
||||
FloatingAttachPointType :: enum EnumBackingType {
|
||||
LeftTop,
|
||||
LeftCenter,
|
||||
LeftBottom,
|
||||
CenterTop,
|
||||
CenterCenter,
|
||||
CenterBottom,
|
||||
RightTop,
|
||||
RightCenter,
|
||||
RightBottom,
|
||||
}
|
||||
|
||||
FloatingAttachPoints :: struct {
|
||||
element: FloatingAttachPointType,
|
||||
parent: FloatingAttachPointType,
|
||||
}
|
||||
|
||||
PointerCaptureMode :: enum EnumBackingType {
|
||||
Capture,
|
||||
Passthrough,
|
||||
}
|
||||
|
||||
FloatingAttachToElement :: enum EnumBackingType {
|
||||
None,
|
||||
Parent,
|
||||
ElementWithId,
|
||||
Root,
|
||||
}
|
||||
|
||||
FloatingClipToElement :: enum EnumBackingType {
|
||||
None,
|
||||
AttachedParent,
|
||||
}
|
||||
|
||||
FloatingElementConfig :: struct {
|
||||
offset: Vector2,
|
||||
expand: Dimensions,
|
||||
parentId: u32,
|
||||
zIndex: i16,
|
||||
attachment: FloatingAttachPoints,
|
||||
pointerCaptureMode: PointerCaptureMode,
|
||||
attachTo: FloatingAttachToElement,
|
||||
clipTo: FloatingClipToElement,
|
||||
}
|
||||
|
||||
TextRenderData :: struct {
|
||||
stringContents: StringSlice,
|
||||
textColor: Color,
|
||||
fontId: u16,
|
||||
fontSize: u16,
|
||||
letterSpacing: u16,
|
||||
lineHeight: u16,
|
||||
}
|
||||
|
||||
RectangleRenderData :: struct {
|
||||
backgroundColor: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
}
|
||||
|
||||
ImageRenderData :: struct {
|
||||
backgroundColor: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
imageData: rawptr,
|
||||
}
|
||||
|
||||
CustomRenderData :: struct {
|
||||
backgroundColor: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
customData: rawptr,
|
||||
}
|
||||
|
||||
ClipRenderData :: struct {
|
||||
horizontal: bool,
|
||||
vertical: bool,
|
||||
}
|
||||
|
||||
OverlayColorRenderData :: struct {
|
||||
color: Color,
|
||||
}
|
||||
|
||||
BorderRenderData :: struct {
|
||||
color: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
width: BorderWidth,
|
||||
}
|
||||
|
||||
RenderCommandData :: struct #raw_union {
|
||||
rectangle: RectangleRenderData,
|
||||
text: TextRenderData,
|
||||
image: ImageRenderData,
|
||||
custom: CustomRenderData,
|
||||
border: BorderRenderData,
|
||||
clip: ClipRenderData,
|
||||
overlayColor: OverlayColorRenderData,
|
||||
}
|
||||
|
||||
RenderCommand :: struct {
|
||||
boundingBox: BoundingBox,
|
||||
renderData: RenderCommandData,
|
||||
userData: rawptr,
|
||||
id: u32,
|
||||
zIndex: i16,
|
||||
commandType: RenderCommandType,
|
||||
}
|
||||
|
||||
ScrollContainerData :: struct {
|
||||
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
|
||||
// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
|
||||
scrollPosition: ^Vector2,
|
||||
scrollContainerDimensions: Dimensions,
|
||||
contentDimensions: Dimensions,
|
||||
config: ClipElementConfig,
|
||||
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
|
||||
found: bool,
|
||||
}
|
||||
|
||||
ElementData :: struct {
|
||||
boundingBox: BoundingBox,
|
||||
found: bool,
|
||||
}
|
||||
|
||||
PointerDataInteractionState :: enum EnumBackingType {
|
||||
PressedThisFrame,
|
||||
Pressed,
|
||||
ReleasedThisFrame,
|
||||
Released,
|
||||
}
|
||||
|
||||
PointerData :: struct {
|
||||
position: Vector2,
|
||||
state: PointerDataInteractionState,
|
||||
}
|
||||
|
||||
SizingType :: enum EnumBackingType {
|
||||
Fit,
|
||||
Grow,
|
||||
Percent,
|
||||
Fixed,
|
||||
}
|
||||
|
||||
SizingConstraintsMinMax :: struct {
|
||||
min: c.float,
|
||||
max: c.float,
|
||||
}
|
||||
|
||||
SizingConstraints :: struct #raw_union {
|
||||
sizeMinMax: SizingConstraintsMinMax,
|
||||
sizePercent: c.float,
|
||||
}
|
||||
|
||||
SizingAxis :: struct {
|
||||
// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
|
||||
constraints: SizingConstraints,
|
||||
type: SizingType,
|
||||
}
|
||||
|
||||
Sizing :: struct {
|
||||
width: SizingAxis,
|
||||
height: SizingAxis,
|
||||
}
|
||||
|
||||
Padding :: struct {
|
||||
left: u16,
|
||||
right: u16,
|
||||
top: u16,
|
||||
bottom: u16,
|
||||
}
|
||||
|
||||
LayoutDirection :: enum EnumBackingType {
|
||||
LeftToRight,
|
||||
TopToBottom,
|
||||
}
|
||||
|
||||
LayoutAlignmentX :: enum EnumBackingType {
|
||||
Left,
|
||||
Right,
|
||||
Center,
|
||||
}
|
||||
|
||||
LayoutAlignmentY :: enum EnumBackingType {
|
||||
Top,
|
||||
Bottom,
|
||||
Center,
|
||||
}
|
||||
|
||||
ChildAlignment :: struct {
|
||||
x: LayoutAlignmentX,
|
||||
y: LayoutAlignmentY,
|
||||
}
|
||||
|
||||
LayoutConfig :: struct {
|
||||
sizing: Sizing,
|
||||
padding: Padding,
|
||||
childGap: u16,
|
||||
childAlignment: ChildAlignment,
|
||||
layoutDirection: LayoutDirection,
|
||||
}
|
||||
|
||||
ClayArray :: struct($type: typeid) {
|
||||
capacity: i32,
|
||||
length: i32,
|
||||
internalArray: [^]type,
|
||||
}
|
||||
|
||||
ElementDeclaration :: struct {
|
||||
layout: LayoutConfig,
|
||||
backgroundColor: Color,
|
||||
overlayColor: Color,
|
||||
cornerRadius: CornerRadius,
|
||||
aspectRatio: AspectRatioElementConfig,
|
||||
image: ImageElementConfig,
|
||||
floating: FloatingElementConfig,
|
||||
custom: CustomElementConfig,
|
||||
clip: ClipElementConfig,
|
||||
border: BorderElementConfig,
|
||||
transition: TransitionElementConfig,
|
||||
userData: rawptr,
|
||||
}
|
||||
|
||||
ErrorType :: enum EnumBackingType {
|
||||
TextMeasurementFunctionNotProvided,
|
||||
ArenaCapacityExceeded,
|
||||
ElementsCapacityExceeded,
|
||||
TextMeasurementCapacityExceeded,
|
||||
DuplicateId,
|
||||
FloatingContainerParentNotFound,
|
||||
PercentageOver1,
|
||||
InternalError,
|
||||
UnbalancedOpenClose,
|
||||
}
|
||||
|
||||
ErrorData :: struct {
|
||||
errorType: ErrorType,
|
||||
errorText: String,
|
||||
userData: rawptr,
|
||||
}
|
||||
|
||||
ErrorHandler :: struct {
|
||||
handler: proc "c" (errorData: ErrorData),
|
||||
userData: rawptr,
|
||||
}
|
||||
|
||||
Context :: struct {} // opaque structure, only use as a pointer
|
||||
|
||||
@(link_prefix = "Clay_", default_calling_convention = "c")
|
||||
foreign Clay {
|
||||
_OpenElement :: proc() ---
|
||||
_OpenElementWithId :: proc(id: ElementId) ---
|
||||
_CloseElement :: proc() ---
|
||||
MinMemorySize :: proc() -> u32 ---
|
||||
CreateArenaWithCapacityAndMemory :: proc(capacity: c.size_t, offset: [^]u8) -> Arena ---
|
||||
SetPointerState :: proc(position: Vector2, pointerDown: bool) ---
|
||||
GetPointerState :: proc() -> PointerData ---
|
||||
Initialize :: proc(arena: Arena, layoutDimensions: Dimensions, errorHandler: ErrorHandler) -> ^Context ---
|
||||
GetCurrentContext :: proc() -> ^Context ---
|
||||
SetCurrentContext :: proc(ctx: ^Context) ---
|
||||
UpdateScrollContainers :: proc(enableDragScrolling: bool, scrollDelta: Vector2, deltaTime: c.float) ---
|
||||
SetLayoutDimensions :: proc(dimensions: Dimensions) ---
|
||||
BeginLayout :: proc() ---
|
||||
EndLayout :: proc(deltaTime: c.float) -> ClayArray(RenderCommand) ---
|
||||
GetOpenElementId :: proc() -> u32 ---
|
||||
GetElementId :: proc(id: String) -> ElementId ---
|
||||
GetElementIdWithIndex :: proc(id: String, index: u32) -> ElementId ---
|
||||
GetElementData :: proc(id: ElementId) -> ElementData ---
|
||||
Hovered :: proc() -> bool ---
|
||||
OnHover :: proc(onHoverFunction: proc "c" (id: ElementId, pointerData: PointerData, userData: rawptr), userData: rawptr) ---
|
||||
PointerOver :: proc(id: ElementId) -> bool ---
|
||||
GetPointerOverIds :: proc() -> ElementIdArray ---
|
||||
GetScrollOffset :: proc() -> Vector2 ---
|
||||
GetScrollContainerData :: proc(id: ElementId) -> ScrollContainerData ---
|
||||
SetMeasureTextFunction :: proc(measureTextFunction: proc "c" (text: StringSlice, config: ^TextElementConfig, userData: rawptr) -> Dimensions, userData: rawptr) ---
|
||||
SetQueryScrollOffsetFunction :: proc(queryScrollOffsetFunction: proc "c" (elementId: u32, userData: rawptr) -> Vector2, userData: rawptr) ---
|
||||
RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: i32) -> ^RenderCommand ---
|
||||
SetDebugModeEnabled :: proc(enabled: bool) ---
|
||||
IsDebugModeEnabled :: proc() -> bool ---
|
||||
SetCullingEnabled :: proc(enabled: bool) ---
|
||||
GetMaxElementCount :: proc() -> i32 ---
|
||||
SetMaxElementCount :: proc(maxElementCount: i32) ---
|
||||
GetMaxMeasureTextCacheWordCount :: proc() -> i32 ---
|
||||
SetMaxMeasureTextCacheWordCount :: proc(maxMeasureTextCacheWordCount: i32) ---
|
||||
ResetMeasureTextCache :: proc() ---
|
||||
EaseOut :: proc(arguments: TransitionCallbackArguments) -> bool ---
|
||||
}
|
||||
|
||||
@(link_prefix = "Clay_", default_calling_convention = "c", private)
|
||||
foreign Clay {
|
||||
_ConfigureOpenElement :: proc(config: ElementDeclaration) ---
|
||||
_HashString :: proc(key: String, seed: u32) -> ElementId ---
|
||||
_HashStringWithOffset :: proc(key: String, index: u32, seed: u32) -> ElementId ---
|
||||
_OpenTextElement :: proc(text: String, textConfig: TextElementConfig) ---
|
||||
}
|
||||
|
||||
ConfigureOpenElement :: proc(config: ElementDeclaration) -> bool {
|
||||
_ConfigureOpenElement(config)
|
||||
return true
|
||||
}
|
||||
|
||||
@(deferred_none = _CloseElement)
|
||||
UI_WithId :: proc(id: ElementId) -> proc(config: ElementDeclaration) -> bool {
|
||||
_OpenElementWithId(id)
|
||||
return ConfigureOpenElement
|
||||
}
|
||||
|
||||
@(deferred_none = _CloseElement)
|
||||
UI_AutoId :: proc() -> proc(config: ElementDeclaration) -> bool {
|
||||
_OpenElement()
|
||||
return ConfigureOpenElement
|
||||
}
|
||||
|
||||
UI :: proc {
|
||||
UI_WithId,
|
||||
UI_AutoId,
|
||||
}
|
||||
|
||||
Text :: proc {
|
||||
TextStatic,
|
||||
TextDynamic,
|
||||
}
|
||||
|
||||
TextStatic :: proc($text: string, config: TextElementConfig) {
|
||||
wrapped := MakeString(text)
|
||||
wrapped.isStaticallyAllocated = true
|
||||
_OpenTextElement(wrapped, config)
|
||||
}
|
||||
|
||||
TextDynamic :: proc(text: string, config: TextElementConfig) {
|
||||
_OpenTextElement(MakeString(text), config)
|
||||
}
|
||||
|
||||
PaddingAll :: proc(allPadding: u16) -> Padding {
|
||||
return {left = allPadding, right = allPadding, top = allPadding, bottom = allPadding}
|
||||
}
|
||||
|
||||
BorderOutside :: proc(width: u16) -> BorderWidth {
|
||||
return {width, width, width, width, 0}
|
||||
}
|
||||
|
||||
BorderAll :: proc(width: u16) -> BorderWidth {
|
||||
return {width, width, width, width, width}
|
||||
}
|
||||
|
||||
CornerRadiusAll :: proc(radius: f32) -> CornerRadius {
|
||||
return CornerRadius{radius, radius, radius, radius}
|
||||
}
|
||||
|
||||
SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax = {}) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Fit, constraints = {sizeMinMax = sizeMinMax}}
|
||||
}
|
||||
|
||||
SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax = {}) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Grow, constraints = {sizeMinMax = sizeMinMax}}
|
||||
}
|
||||
|
||||
SizingFixed :: proc(size: c.float) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Fixed, constraints = {sizeMinMax = {size, size}}}
|
||||
}
|
||||
|
||||
SizingPercent :: proc(sizePercent: c.float) -> SizingAxis {
|
||||
return SizingAxis{type = SizingType.Percent, constraints = {sizePercent = sizePercent}}
|
||||
}
|
||||
|
||||
MakeString :: proc(label: string) -> String {
|
||||
return String{chars = raw_data(label), length = cast(c.int)len(label)}
|
||||
}
|
||||
|
||||
ID :: proc(label: string, index: u32 = 0) -> ElementId {
|
||||
return _HashString(MakeString(label), index)
|
||||
}
|
||||
|
||||
ID_LOCAL :: proc(label: string, index: u32 = 0) -> ElementId {
|
||||
return _HashStringWithOffset(MakeString(label), index, GetOpenElementId())
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,470 @@
|
||||
package imgui_impl_raylib
|
||||
|
||||
// Based on the raylib extras rlImGui: https://github.com/raylib-extras/rlImGui/blob/main/rlImGui.cpp
|
||||
/* Usage:
|
||||
|
||||
import imgui_rl "imgui_impl_raylib"
|
||||
import imgui "../../odin-imgui"
|
||||
|
||||
main :: proc() {
|
||||
rl.SetConfigFlags({ rl.ConfigFlag.WINDOW_RESIZABLE })
|
||||
rl.InitWindow(800, 600, "raylib basic window")
|
||||
defer rl.CloseWindow()
|
||||
|
||||
imgui.CreateContext(nil)
|
||||
defer imgui.DestroyContext(nil)
|
||||
|
||||
imgui_rl.init()
|
||||
defer imgui_rl.shutdown()
|
||||
|
||||
imgui_rl.build_font_atlas()
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
imgui_rl.process_events()
|
||||
imgui_rl.new_frame()
|
||||
imgui.NewFrame()
|
||||
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.RAYWHITE)
|
||||
|
||||
imgui.ShowDemoWindow(nil)
|
||||
|
||||
imgui.Render()
|
||||
imgui_rl.render_draw_data(imgui.GetDrawData())
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
import "core:c"
|
||||
import "core:mem"
|
||||
import "core:math"
|
||||
|
||||
// Follow build instruction for imgui bindings in: https://gitlab.com/L-4/odin-imgui
|
||||
import imgui "../odin-imgui"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
current_mouse_cursor: imgui.MouseCursor = imgui.MouseCursor.COUNT
|
||||
mouse_cursor_map: [imgui.MouseCursor.COUNT]rl.MouseCursor
|
||||
|
||||
last_frame_focused := false
|
||||
last_control_pressed := false
|
||||
last_shift_pressed := false
|
||||
last_alt_pressed := false
|
||||
last_super_pressed := false
|
||||
|
||||
raylib_key_map: map[rl.KeyboardKey]imgui.Key = {}
|
||||
|
||||
init :: proc() -> bool {
|
||||
setup_globals()
|
||||
setup_keymap()
|
||||
setup_mouse_cursor()
|
||||
setup_backend()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
build_font_atlas :: proc() -> mem.Allocator_Error {
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
|
||||
pixels: ^c.uchar
|
||||
width, height: c.int
|
||||
imgui.FontAtlas_GetTexDataAsRGBA32(io.Fonts, &pixels, &width, &height, nil)
|
||||
image: rl.Image = rl.GenImageColor(width, height, rl.BLANK)
|
||||
mem.copy(image.data, pixels, int(width * height * 4))
|
||||
|
||||
font_texture: ^rl.Texture2D = transmute(^rl.Texture)io.Fonts.TexID
|
||||
if font_texture != nil && font_texture.id != 0 {
|
||||
rl.UnloadTexture(font_texture^)
|
||||
mem.free(font_texture)
|
||||
}
|
||||
|
||||
font_texture = cast(^rl.Texture2D)(mem.alloc(size_of(rl.Texture2D), align_of(rl.Texture2D)) or_return)
|
||||
font_texture^ = rl.LoadTextureFromImage(image)
|
||||
rl.UnloadImage(image)
|
||||
io.Fonts.TexID = font_texture
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
shutdown :: proc() {
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
font_texture: ^rl.Texture2D = transmute(^rl.Texture)io.Fonts.TexID
|
||||
|
||||
if font_texture != nil && font_texture.id != 0 {
|
||||
rl.UnloadTexture(font_texture^)
|
||||
mem.free(font_texture)
|
||||
}
|
||||
|
||||
io.Fonts.TexID = nil
|
||||
}
|
||||
|
||||
new_frame :: proc() {
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
|
||||
if rl.IsWindowFullscreen() {
|
||||
monitor := rl.GetCurrentMonitor()
|
||||
io.DisplaySize.x = f32(rl.GetMonitorWidth(monitor))
|
||||
io.DisplaySize.y = f32(rl.GetMonitorHeight(monitor))
|
||||
} else {
|
||||
io.DisplaySize.x = f32(rl.GetScreenWidth())
|
||||
io.DisplaySize.y = f32(rl.GetScreenHeight())
|
||||
}
|
||||
|
||||
io.DisplayFramebufferScale = rl.GetWindowScaleDPI()
|
||||
io.DeltaTime = rl.GetFrameTime()
|
||||
|
||||
if io.WantSetMousePos {
|
||||
rl.SetMousePosition(c.int(io.MousePos.x), c.int(io.MousePos.y))
|
||||
} else {
|
||||
mouse_pos := rl.GetMousePosition()
|
||||
imgui.IO_AddMousePosEvent(io, mouse_pos.x, mouse_pos.y)
|
||||
}
|
||||
|
||||
set_mouse_event :: proc(io: ^imgui.IO, rl_mouse: rl.MouseButton, imgui_mouse: c.int) {
|
||||
if rl.IsMouseButtonPressed(rl_mouse) {
|
||||
imgui.IO_AddMouseButtonEvent(io, imgui_mouse, true)
|
||||
} else if rl.IsMouseButtonReleased(rl_mouse) {
|
||||
imgui.IO_AddMouseButtonEvent(io, imgui_mouse, false)
|
||||
}
|
||||
}
|
||||
|
||||
set_mouse_event(io, rl.MouseButton.LEFT, c.int(imgui.MouseButton.Left))
|
||||
set_mouse_event(io, rl.MouseButton.RIGHT, c.int(imgui.MouseButton.Right))
|
||||
set_mouse_event(io, rl.MouseButton.MIDDLE, c.int(imgui.MouseButton.Middle))
|
||||
set_mouse_event(io, rl.MouseButton.FORWARD, c.int(imgui.MouseButton.Middle) + 1)
|
||||
set_mouse_event(io, rl.MouseButton.BACK, c.int(imgui.MouseButton.Middle) + 2)
|
||||
|
||||
mouse_wheel := rl.GetMouseWheelMoveV()
|
||||
imgui.IO_AddMouseWheelEvent(io, mouse_wheel.x, mouse_wheel.y)
|
||||
|
||||
if imgui.ConfigFlag.NoMouseCursorChange not_in io.ConfigFlags {
|
||||
imgui_cursor: imgui.MouseCursor = imgui.GetMouseCursor()
|
||||
if imgui_cursor != current_mouse_cursor || io.MouseDrawCursor {
|
||||
current_mouse_cursor = imgui_cursor
|
||||
if io.MouseDrawCursor || imgui_cursor == imgui.MouseCursor.None {
|
||||
rl.HideCursor()
|
||||
} else {
|
||||
rl.ShowCursor()
|
||||
if c.int(imgui_cursor) > -1 && imgui_cursor < imgui.MouseCursor.COUNT {
|
||||
rl.SetMouseCursor(mouse_cursor_map[imgui_cursor])
|
||||
} else {
|
||||
rl.SetMouseCursor(rl.MouseCursor.DEFAULT)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_draw_data :: proc(draw_data: ^imgui.DrawData) {
|
||||
rl.rlDrawRenderBatchActive()
|
||||
rl.rlDisableBackfaceCulling()
|
||||
|
||||
command_lists: []^imgui.DrawList = mem.slice_ptr(draw_data.CmdLists.Data, int(draw_data.CmdLists.Size))
|
||||
for command_list in command_lists {
|
||||
cmd_slice: []imgui.DrawCmd = mem.slice_ptr(command_list.CmdBuffer.Data, int(command_list.CmdBuffer.Size))
|
||||
for i in 0..<command_list.CmdBuffer.Size {
|
||||
cmd := cmd_slice[i]
|
||||
enable_scissor(
|
||||
cmd.ClipRect.x - draw_data.DisplayPos.x,
|
||||
cmd.ClipRect.y,
|
||||
cmd.ClipRect.z - (cmd.ClipRect.x - draw_data.DisplayPos.x),
|
||||
cmd.ClipRect.w - (cmd.ClipRect.y - draw_data.DisplayPos.y)
|
||||
)
|
||||
|
||||
if cmd.UserCallback != nil {
|
||||
cmd.UserCallback(command_list, &cmd)
|
||||
continue
|
||||
}
|
||||
|
||||
render_triangles(cmd.ElemCount, cmd.IdxOffset, command_list.IdxBuffer, command_list.VtxBuffer, cmd.TextureId)
|
||||
rl.rlDrawRenderBatchActive()
|
||||
}
|
||||
}
|
||||
|
||||
rl.rlSetTexture(0)
|
||||
rl.rlDisableScissorTest()
|
||||
rl.rlEnableBackfaceCulling()
|
||||
}
|
||||
|
||||
@private
|
||||
enable_scissor :: proc(x: f32, y: f32, width: f32, height: f32) {
|
||||
rl.rlEnableScissorTest()
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
|
||||
rl.rlScissor(
|
||||
i32(x * io.DisplayFramebufferScale.x),
|
||||
i32((io.DisplaySize.y - math.floor(y + height)) * io.DisplayFramebufferScale.y),
|
||||
i32(width * io.DisplayFramebufferScale.x),
|
||||
i32(height * io.DisplayFramebufferScale.y)
|
||||
)
|
||||
}
|
||||
|
||||
@private
|
||||
render_triangles :: proc(count: u32, index_start: u32, index_buffer: imgui.Vector_DrawIdx, vert_buffer: imgui.Vector_DrawVert, texture_ptr: imgui.TextureID) {
|
||||
if count < 3 {
|
||||
return
|
||||
}
|
||||
|
||||
texture: ^rl.Texture = transmute(^rl.Texture)texture_ptr
|
||||
|
||||
texture_id: u32 = (texture == nil) ? 0 : texture.id
|
||||
|
||||
rl.rlBegin(rl.RL_TRIANGLES)
|
||||
rl.rlSetTexture(texture_id)
|
||||
|
||||
index_slice: []imgui.DrawIdx = mem.slice_ptr(index_buffer.Data, int(index_buffer.Size))
|
||||
vert_slice: []imgui.DrawVert = mem.slice_ptr(vert_buffer.Data, int(vert_buffer.Size))
|
||||
|
||||
for i: u32 = 0; i <= (count - 3); i += 3 {
|
||||
if rl.rlCheckRenderBatchLimit(3) != 0 {
|
||||
rl.rlBegin(rl.RL_TRIANGLES)
|
||||
rl.rlSetTexture(texture_id)
|
||||
}
|
||||
|
||||
index_a := index_slice[index_start + i]
|
||||
index_b := index_slice[index_start + i + 1]
|
||||
index_c := index_slice[index_start + i + 2]
|
||||
|
||||
vertex_a := vert_slice[index_a]
|
||||
vertex_b := vert_slice[index_b]
|
||||
vertex_c := vert_slice[index_c]
|
||||
|
||||
draw_triangle_vert :: proc(vert: imgui.DrawVert) {
|
||||
c: rl.Color = transmute(rl.Color)vert.col
|
||||
rl.rlColor4ub(c.r, c.g, c.b, c.a)
|
||||
rl.rlTexCoord2f(vert.uv.x, vert.uv.y)
|
||||
rl.rlVertex2f(vert.pos.x, vert.pos.y)
|
||||
}
|
||||
|
||||
draw_triangle_vert(vertex_a)
|
||||
draw_triangle_vert(vertex_b)
|
||||
draw_triangle_vert(vertex_c)
|
||||
}
|
||||
|
||||
rl.rlEnd()
|
||||
}
|
||||
|
||||
is_control_down :: proc() -> bool { return rl.IsKeyDown(rl.KeyboardKey.RIGHT_CONTROL) || rl.IsKeyDown(rl.KeyboardKey.LEFT_CONTROL); }
|
||||
is_shift_down :: proc() -> bool { return rl.IsKeyDown(rl.KeyboardKey.RIGHT_SHIFT) || rl.IsKeyDown(rl.KeyboardKey.LEFT_SHIFT); }
|
||||
is_alt_down :: proc() -> bool { return rl.IsKeyDown(rl.KeyboardKey.RIGHT_ALT) || rl.IsKeyDown(rl.KeyboardKey.LEFT_ALT); }
|
||||
is_super_down :: proc() -> bool { return rl.IsKeyDown(rl.KeyboardKey.RIGHT_SUPER) || rl.IsKeyDown(rl.KeyboardKey.LEFT_SUPER); }
|
||||
|
||||
process_events :: proc() -> bool {
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
|
||||
focused := rl.IsWindowFocused()
|
||||
if (focused != last_frame_focused) {
|
||||
imgui.IO_AddFocusEvent(io, focused)
|
||||
}
|
||||
last_frame_focused = focused
|
||||
|
||||
// Handle modifers for key evets so that shortcuts work
|
||||
ctrl_down := is_control_down()
|
||||
if ctrl_down != last_control_pressed {
|
||||
imgui.IO_AddKeyEvent(io, imgui.Key.ImGuiMod_Ctrl, ctrl_down)
|
||||
}
|
||||
last_control_pressed = ctrl_down
|
||||
|
||||
shift_down := is_shift_down()
|
||||
if shift_down != last_shift_pressed {
|
||||
imgui.IO_AddKeyEvent(io, imgui.Key.ImGuiMod_Shift, shift_down)
|
||||
}
|
||||
last_shift_pressed = shift_down
|
||||
|
||||
alt_down := is_alt_down()
|
||||
if alt_down != last_alt_pressed {
|
||||
imgui.IO_AddKeyEvent(io, imgui.Key.ImGuiMod_Alt, alt_down)
|
||||
}
|
||||
last_alt_pressed = alt_down
|
||||
|
||||
super_down := is_super_down()
|
||||
if super_down != last_super_pressed {
|
||||
imgui.IO_AddKeyEvent(io, imgui.Key.ImGuiMod_Super, super_down)
|
||||
}
|
||||
last_super_pressed = super_down
|
||||
|
||||
// Get pressed keys, they are in event order
|
||||
key_id: rl.KeyboardKey = rl.GetKeyPressed()
|
||||
for key_id != rl.KeyboardKey.KEY_NULL {
|
||||
key, ok := raylib_key_map[key_id]
|
||||
if ok {
|
||||
imgui.IO_AddKeyEvent(io, key, true)
|
||||
}
|
||||
|
||||
key_id = rl.GetKeyPressed()
|
||||
}
|
||||
|
||||
// Check for released keys
|
||||
for key in raylib_key_map {
|
||||
if rl.IsKeyReleased(key) {
|
||||
imgui.IO_AddKeyEvent(io, raylib_key_map[key], false)
|
||||
}
|
||||
}
|
||||
|
||||
// Add text input in order
|
||||
pressed: rune = rl.GetCharPressed()
|
||||
for pressed != 0 {
|
||||
imgui.IO_AddInputCharacter(io, u32(pressed))
|
||||
pressed = rl.GetCharPressed()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@private
|
||||
setup_globals :: proc() {
|
||||
last_frame_focused = rl.IsWindowFocused()
|
||||
last_control_pressed = false
|
||||
last_shift_pressed = false
|
||||
last_alt_pressed = false
|
||||
last_super_pressed = false
|
||||
}
|
||||
|
||||
@private
|
||||
setup_keymap :: proc() {
|
||||
raylib_key_map[rl.KeyboardKey.APOSTROPHE] = imgui.Key.Apostrophe
|
||||
raylib_key_map[rl.KeyboardKey.COMMA] = imgui.Key.Comma
|
||||
raylib_key_map[rl.KeyboardKey.MINUS] = imgui.Key.Minus
|
||||
raylib_key_map[rl.KeyboardKey.PERIOD] = imgui.Key.Period
|
||||
raylib_key_map[rl.KeyboardKey.SLASH] = imgui.Key.Slash
|
||||
raylib_key_map[rl.KeyboardKey.ZERO] = imgui.Key._0
|
||||
raylib_key_map[rl.KeyboardKey.ONE] = imgui.Key._1
|
||||
raylib_key_map[rl.KeyboardKey.TWO] = imgui.Key._2
|
||||
raylib_key_map[rl.KeyboardKey.THREE] = imgui.Key._3
|
||||
raylib_key_map[rl.KeyboardKey.FOUR] = imgui.Key._4
|
||||
raylib_key_map[rl.KeyboardKey.FIVE] = imgui.Key._5
|
||||
raylib_key_map[rl.KeyboardKey.SIX] = imgui.Key._6
|
||||
raylib_key_map[rl.KeyboardKey.SEVEN] = imgui.Key._7
|
||||
raylib_key_map[rl.KeyboardKey.EIGHT] = imgui.Key._8
|
||||
raylib_key_map[rl.KeyboardKey.NINE] = imgui.Key._9
|
||||
raylib_key_map[rl.KeyboardKey.SEMICOLON] = imgui.Key.Semicolon
|
||||
raylib_key_map[rl.KeyboardKey.EQUAL] = imgui.Key.Equal
|
||||
raylib_key_map[rl.KeyboardKey.A] = imgui.Key.A
|
||||
raylib_key_map[rl.KeyboardKey.B] = imgui.Key.B
|
||||
raylib_key_map[rl.KeyboardKey.C] = imgui.Key.C
|
||||
raylib_key_map[rl.KeyboardKey.D] = imgui.Key.D
|
||||
raylib_key_map[rl.KeyboardKey.E] = imgui.Key.E
|
||||
raylib_key_map[rl.KeyboardKey.F] = imgui.Key.F
|
||||
raylib_key_map[rl.KeyboardKey.G] = imgui.Key.G
|
||||
raylib_key_map[rl.KeyboardKey.H] = imgui.Key.H
|
||||
raylib_key_map[rl.KeyboardKey.I] = imgui.Key.I
|
||||
raylib_key_map[rl.KeyboardKey.J] = imgui.Key.J
|
||||
raylib_key_map[rl.KeyboardKey.K] = imgui.Key.K
|
||||
raylib_key_map[rl.KeyboardKey.L] = imgui.Key.L
|
||||
raylib_key_map[rl.KeyboardKey.M] = imgui.Key.M
|
||||
raylib_key_map[rl.KeyboardKey.N] = imgui.Key.N
|
||||
raylib_key_map[rl.KeyboardKey.O] = imgui.Key.O
|
||||
raylib_key_map[rl.KeyboardKey.P] = imgui.Key.P
|
||||
raylib_key_map[rl.KeyboardKey.Q] = imgui.Key.Q
|
||||
raylib_key_map[rl.KeyboardKey.R] = imgui.Key.R
|
||||
raylib_key_map[rl.KeyboardKey.S] = imgui.Key.S
|
||||
raylib_key_map[rl.KeyboardKey.T] = imgui.Key.T
|
||||
raylib_key_map[rl.KeyboardKey.U] = imgui.Key.U
|
||||
raylib_key_map[rl.KeyboardKey.V] = imgui.Key.V
|
||||
raylib_key_map[rl.KeyboardKey.W] = imgui.Key.W
|
||||
raylib_key_map[rl.KeyboardKey.X] = imgui.Key.X
|
||||
raylib_key_map[rl.KeyboardKey.Y] = imgui.Key.Y
|
||||
raylib_key_map[rl.KeyboardKey.Z] = imgui.Key.Z
|
||||
raylib_key_map[rl.KeyboardKey.SPACE] = imgui.Key.Space
|
||||
raylib_key_map[rl.KeyboardKey.ESCAPE] = imgui.Key.Escape
|
||||
raylib_key_map[rl.KeyboardKey.ENTER] = imgui.Key.Enter
|
||||
raylib_key_map[rl.KeyboardKey.TAB] = imgui.Key.Tab
|
||||
raylib_key_map[rl.KeyboardKey.BACKSPACE] = imgui.Key.Backspace
|
||||
raylib_key_map[rl.KeyboardKey.INSERT] = imgui.Key.Insert
|
||||
raylib_key_map[rl.KeyboardKey.DELETE] = imgui.Key.Delete
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT] = imgui.Key.RightArrow
|
||||
raylib_key_map[rl.KeyboardKey.LEFT] = imgui.Key.LeftArrow
|
||||
raylib_key_map[rl.KeyboardKey.DOWN] = imgui.Key.DownArrow
|
||||
raylib_key_map[rl.KeyboardKey.UP] = imgui.Key.UpArrow
|
||||
raylib_key_map[rl.KeyboardKey.PAGE_UP] = imgui.Key.PageUp
|
||||
raylib_key_map[rl.KeyboardKey.PAGE_DOWN] = imgui.Key.PageDown
|
||||
raylib_key_map[rl.KeyboardKey.HOME] = imgui.Key.Home
|
||||
raylib_key_map[rl.KeyboardKey.END] = imgui.Key.End
|
||||
raylib_key_map[rl.KeyboardKey.CAPS_LOCK] = imgui.Key.CapsLock
|
||||
raylib_key_map[rl.KeyboardKey.SCROLL_LOCK] = imgui.Key.ScrollLock
|
||||
raylib_key_map[rl.KeyboardKey.NUM_LOCK] = imgui.Key.NumLock
|
||||
raylib_key_map[rl.KeyboardKey.PRINT_SCREEN] = imgui.Key.PrintScreen
|
||||
raylib_key_map[rl.KeyboardKey.PAUSE] = imgui.Key.Pause
|
||||
raylib_key_map[rl.KeyboardKey.F1] = imgui.Key.F1
|
||||
raylib_key_map[rl.KeyboardKey.F2] = imgui.Key.F2
|
||||
raylib_key_map[rl.KeyboardKey.F3] = imgui.Key.F3
|
||||
raylib_key_map[rl.KeyboardKey.F4] = imgui.Key.F4
|
||||
raylib_key_map[rl.KeyboardKey.F5] = imgui.Key.F5
|
||||
raylib_key_map[rl.KeyboardKey.F6] = imgui.Key.F6
|
||||
raylib_key_map[rl.KeyboardKey.F7] = imgui.Key.F7
|
||||
raylib_key_map[rl.KeyboardKey.F8] = imgui.Key.F8
|
||||
raylib_key_map[rl.KeyboardKey.F9] = imgui.Key.F9
|
||||
raylib_key_map[rl.KeyboardKey.F10] = imgui.Key.F10
|
||||
raylib_key_map[rl.KeyboardKey.F11] = imgui.Key.F11
|
||||
raylib_key_map[rl.KeyboardKey.F12] = imgui.Key.F12
|
||||
raylib_key_map[rl.KeyboardKey.LEFT_SHIFT] = imgui.Key.LeftShift
|
||||
raylib_key_map[rl.KeyboardKey.LEFT_CONTROL] = imgui.Key.LeftCtrl
|
||||
raylib_key_map[rl.KeyboardKey.LEFT_ALT] = imgui.Key.LeftAlt
|
||||
raylib_key_map[rl.KeyboardKey.LEFT_SUPER] = imgui.Key.LeftSuper
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT_SHIFT] = imgui.Key.RightShift
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT_CONTROL] = imgui.Key.RightCtrl
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT_ALT] = imgui.Key.RightAlt
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT_SUPER] = imgui.Key.RightSuper
|
||||
raylib_key_map[rl.KeyboardKey.KB_MENU] = imgui.Key.Menu
|
||||
raylib_key_map[rl.KeyboardKey.LEFT_BRACKET] = imgui.Key.LeftBracket
|
||||
raylib_key_map[rl.KeyboardKey.BACKSLASH] = imgui.Key.Backslash
|
||||
raylib_key_map[rl.KeyboardKey.RIGHT_BRACKET] = imgui.Key.RightBracket
|
||||
raylib_key_map[rl.KeyboardKey.GRAVE] = imgui.Key.GraveAccent
|
||||
raylib_key_map[rl.KeyboardKey.KP_0] = imgui.Key.Keypad0
|
||||
raylib_key_map[rl.KeyboardKey.KP_1] = imgui.Key.Keypad1
|
||||
raylib_key_map[rl.KeyboardKey.KP_2] = imgui.Key.Keypad2
|
||||
raylib_key_map[rl.KeyboardKey.KP_3] = imgui.Key.Keypad3
|
||||
raylib_key_map[rl.KeyboardKey.KP_4] = imgui.Key.Keypad4
|
||||
raylib_key_map[rl.KeyboardKey.KP_5] = imgui.Key.Keypad5
|
||||
raylib_key_map[rl.KeyboardKey.KP_6] = imgui.Key.Keypad6
|
||||
raylib_key_map[rl.KeyboardKey.KP_7] = imgui.Key.Keypad7
|
||||
raylib_key_map[rl.KeyboardKey.KP_8] = imgui.Key.Keypad8
|
||||
raylib_key_map[rl.KeyboardKey.KP_9] = imgui.Key.Keypad9
|
||||
raylib_key_map[rl.KeyboardKey.KP_DECIMAL] = imgui.Key.KeypadDecimal
|
||||
raylib_key_map[rl.KeyboardKey.KP_DIVIDE] = imgui.Key.KeypadDivide
|
||||
raylib_key_map[rl.KeyboardKey.KP_MULTIPLY] = imgui.Key.KeypadMultiply
|
||||
raylib_key_map[rl.KeyboardKey.KP_SUBTRACT] = imgui.Key.KeypadSubtract
|
||||
raylib_key_map[rl.KeyboardKey.KP_ADD] = imgui.Key.KeypadAdd
|
||||
raylib_key_map[rl.KeyboardKey.KP_ENTER] = imgui.Key.KeypadEnter
|
||||
raylib_key_map[rl.KeyboardKey.KP_EQUAL] = imgui.Key.KeypadEqual
|
||||
}
|
||||
|
||||
@private
|
||||
setup_mouse_cursor :: proc() {
|
||||
mouse_cursor_map[imgui.MouseCursor.Arrow] = rl.MouseCursor.ARROW;
|
||||
mouse_cursor_map[imgui.MouseCursor.TextInput] = rl.MouseCursor.IBEAM;
|
||||
mouse_cursor_map[imgui.MouseCursor.Hand] = rl.MouseCursor.POINTING_HAND;
|
||||
mouse_cursor_map[imgui.MouseCursor.ResizeAll] = rl.MouseCursor.RESIZE_ALL;
|
||||
mouse_cursor_map[imgui.MouseCursor.ResizeEW] = rl.MouseCursor.RESIZE_EW;
|
||||
mouse_cursor_map[imgui.MouseCursor.ResizeNESW] = rl.MouseCursor.RESIZE_NESW;
|
||||
mouse_cursor_map[imgui.MouseCursor.ResizeNS] = rl.MouseCursor.RESIZE_NS;
|
||||
mouse_cursor_map[imgui.MouseCursor.ResizeNWSE] = rl.MouseCursor.RESIZE_NWSE;
|
||||
mouse_cursor_map[imgui.MouseCursor.NotAllowed] = rl.MouseCursor.NOT_ALLOWED;
|
||||
}
|
||||
|
||||
@private
|
||||
setup_backend :: proc() {
|
||||
io: ^imgui.IO = imgui.GetIO()
|
||||
io.BackendPlatformName = "imgui_impl_raylib"
|
||||
|
||||
io.BackendFlags |= { imgui.BackendFlag.HasMouseCursors }
|
||||
|
||||
io.MousePos = { 0, 0 }
|
||||
|
||||
io.SetClipboardTextFn = set_clip_text_callback
|
||||
io.GetClipboardTextFn = get_clip_text_callback
|
||||
|
||||
io.ClipboardUserData = nil
|
||||
}
|
||||
|
||||
@private
|
||||
set_clip_text_callback :: proc "c" (user_data: rawptr, text: cstring) {
|
||||
rl.SetClipboardText(text)
|
||||
}
|
||||
|
||||
@private
|
||||
get_clip_text_callback :: proc "c" (user_data: rawptr) -> cstring {
|
||||
return rl.GetClipboardText()
|
||||
}
|
||||
Submodule
+1
Submodule odin-imgui added at 0615247fab
Reference in New Issue
Block a user