mirror of
https://github.com/aap/librw.git
synced 2026-05-15 09:37:17 +01:00
Merge pull request #147 from madebr/add-sdl3-support
Update imgui and add SDL3 support
This commit is contained in:
@@ -16,13 +16,15 @@ jobs:
|
|||||||
case:
|
case:
|
||||||
- { name: 'Windows (DirectX 9)', os: 'windows-latest', platform: 'D3D9' }
|
- { name: 'Windows (DirectX 9)', os: 'windows-latest', platform: 'D3D9' }
|
||||||
- { name: 'Windows (GL3, glfw)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
- { name: 'Windows (GL3, glfw)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
||||||
- { name: 'Windows (GL3, SDL2)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'SDL2' }
|
- { name: 'Windows (GL3, SDL2)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
|
||||||
|
- { name: 'Windows (GL3, SDL3)', os: 'windows-latest', platform: 'GL3', gl3_gfxlib: 'SDL3', sdl-version: '3-latest' }
|
||||||
- { name: 'Windows (null)', os: 'windows-latest', platform: 'NULL' }
|
- { name: 'Windows (null)', os: 'windows-latest', platform: 'NULL' }
|
||||||
- { name: 'macOS (GL3, glfw)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
- { name: 'macOS (GL3, glfw)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
||||||
- { name: 'macOS (GL3, SDL2)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'SDL2' }
|
- { name: 'macOS (GL3, SDL2)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
|
||||||
|
- { name: 'macOS (GL3, SDL3)', os: 'macos-latest', platform: 'GL3', gl3_gfxlib: 'SDL3', sdl-version: '3-latest' }
|
||||||
- { name: 'macOS (null)', os: 'macos-latest', platform: 'NULL' }
|
- { name: 'macOS (null)', os: 'macos-latest', platform: 'NULL' }
|
||||||
- { name: 'Ubuntu (GL3, glfw)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
- { name: 'Ubuntu (GL3, glfw)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW' }
|
||||||
- { name: 'Ubuntu (GL3, SDL2)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'SDL2' }
|
- { name: 'Ubuntu (GL3, SDL2)', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'SDL2', sdl-version: '2-latest' }
|
||||||
- { name: 'Ubuntu (null)', os: 'ubuntu-latest', platform: 'NULL' }
|
- { name: 'Ubuntu (null)', os: 'ubuntu-latest', platform: 'NULL' }
|
||||||
- { name: 'PlayStation 2', os: 'ubuntu-latest', platform: 'PS2', ps2: true, container: 'ps2dev/ps2dev:latest', cmake-toolchain-file: 'cmake/ps2/cmaketoolchain/toolchain_ps2_ee.cmake' }
|
- { name: 'PlayStation 2', os: 'ubuntu-latest', platform: 'PS2', ps2: true, container: 'ps2dev/ps2dev:latest', cmake-toolchain-file: 'cmake/ps2/cmaketoolchain/toolchain_ps2_ee.cmake' }
|
||||||
- { name: 'Nintendo Switch', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW', glfw-nobuild: true, container: 'devkitpro/devkita64:latest', cmake-toolchain-file: '/opt/devkitpro/cmake/Switch.cmake' }
|
- { name: 'Nintendo Switch', os: 'ubuntu-latest', platform: 'GL3', gl3_gfxlib: 'GLFW', glfw-nobuild: true, container: 'devkitpro/devkita64:latest', cmake-toolchain-file: '/opt/devkitpro/cmake/Switch.cmake' }
|
||||||
@@ -36,11 +38,11 @@ jobs:
|
|||||||
if: ${{ matrix.case.ps2 }}
|
if: ${{ matrix.case.ps2 }}
|
||||||
run: |
|
run: |
|
||||||
apk add cmake gmp mpc1 mpfr4 make pkgconf git
|
apk add cmake gmp mpc1 mpfr4 make pkgconf git
|
||||||
- name: 'Setup SDL2'
|
- name: 'Setup SDL'
|
||||||
if: ${{ matrix.case.gl3_gfxlib == 'SDL2' }}
|
if: ${{ !!matrix.case.sdl-version }}
|
||||||
uses: libsdl-org/setup-sdl@main
|
uses: libsdl-org/setup-sdl@main
|
||||||
with:
|
with:
|
||||||
version: 2-latest
|
version: ${{ matrix.case.sdl-version }}
|
||||||
install-linux-dependencies: true
|
install-linux-dependencies: true
|
||||||
cmake-toolchain-file: ${{ matrix.case.cmake-toolchain-file }}
|
cmake-toolchain-file: ${{ matrix.case.cmake-toolchain-file }}
|
||||||
- name: 'Setup GLFW'
|
- name: 'Setup GLFW'
|
||||||
|
|||||||
+5
-2
@@ -39,7 +39,7 @@ if(NOT LIBRW_PLATFORM IN_LIST LIBRW_PLATFORMS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LIBRW_PLATFORM_GL3)
|
if(LIBRW_PLATFORM_GL3)
|
||||||
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2")
|
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2" "SDL3")
|
||||||
set(LIBRW_GL3_GFXLIB "GLFW" CACHE STRING "gfxlib for gl3 (choices=${LIBRW_GL3_GFXLIBS})")
|
set(LIBRW_GL3_GFXLIB "GLFW" CACHE STRING "gfxlib for gl3 (choices=${LIBRW_GL3_GFXLIBS})")
|
||||||
set_property(CACHE LIBRW_GL3_GFXLIB PROPERTY STRINGS ${LIBRW_GL3_GFXLIBS})
|
set_property(CACHE LIBRW_GL3_GFXLIB PROPERTY STRINGS ${LIBRW_GL3_GFXLIBS})
|
||||||
if(LIBRW_PLATFORM_GL3)
|
if(LIBRW_PLATFORM_GL3)
|
||||||
@@ -91,6 +91,7 @@ if(LIBRW_INSTALL)
|
|||||||
EXPORT librw-targets NAMESPACE librw::
|
EXPORT librw-targets NAMESPACE librw::
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
|
||||||
)
|
)
|
||||||
|
export(TARGETS librw NAMESPACE librw:: FILE librw-targets.cmake)
|
||||||
|
|
||||||
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
||||||
install(
|
install(
|
||||||
@@ -126,8 +127,10 @@ if(LIBRW_INSTALL)
|
|||||||
elseif(LIBRW_PLATFORM_GL3)
|
elseif(LIBRW_PLATFORM_GL3)
|
||||||
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
|
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
|
||||||
set(platform "-gl3-glfw")
|
set(platform "-gl3-glfw")
|
||||||
else()
|
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
||||||
set(platform "-gl3-sdl2")
|
set(platform "-gl3-sdl2")
|
||||||
|
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL3")
|
||||||
|
set(platform "-gl3-sdl3")
|
||||||
endif()
|
endif()
|
||||||
elseif(LIBRW_PLATFORM_D3D9)
|
elseif(LIBRW_PLATFORM_D3D9)
|
||||||
set(platform "-d3d9")
|
set(platform "-d3d9")
|
||||||
|
|||||||
@@ -14,16 +14,21 @@ if(LIBRW_PLATFORM_GL3)
|
|||||||
message(FATAL_ERROR "find_package(OpenGL) failed: no target was created")
|
message(FATAL_ERROR "find_package(OpenGL) failed: no target was created")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
|
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
|
||||||
if (NOT TARGET glfw)
|
if (NOT TARGET glfw)
|
||||||
find_package(glfw3 REQUIRED)
|
find_dependency(glfw3 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
||||||
if (NOT TARGET SDL2::SDL2)
|
if (NOT TARGET SDL2::SDL2)
|
||||||
find_package(SDL2 CONFIG)
|
find_dependency(SDL2 CONFIG)
|
||||||
if (NOT TARGET SDL2::SDL2)
|
if (NOT TARGET SDL2::SDL2)
|
||||||
find_package(SDL2 MODULE REQUIRED)
|
find_dependency(SDL2 MODULE REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
elseif(LIBRW_GL3_GFXLIB STREQUAL "SDL3")
|
||||||
|
if (NOT TARGET SDL3::SDL3)
|
||||||
|
find_dependency(SDL3 CONFIG REQUIRED)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
+21
-3
@@ -6,6 +6,7 @@ newoption {
|
|||||||
allowed = {
|
allowed = {
|
||||||
{ "glfw", "GLFW" },
|
{ "glfw", "GLFW" },
|
||||||
{ "sdl2", "SDL2" },
|
{ "sdl2", "SDL2" },
|
||||||
|
{ "sdl3", "SDL3" },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +28,14 @@ newoption {
|
|||||||
trigger = "sdl2dir",
|
trigger = "sdl2dir",
|
||||||
value = "PATH",
|
value = "PATH",
|
||||||
description = "Directory of sdl2",
|
description = "Directory of sdl2",
|
||||||
default = "../SDL2-2.0.14",
|
default = "../SDL2-2.32.10",
|
||||||
|
}
|
||||||
|
|
||||||
|
newoption {
|
||||||
|
trigger = "sdl3dir",
|
||||||
|
value = "PATH",
|
||||||
|
description = "Directory of sdl3",
|
||||||
|
default = "../SDL3-3.2.22",
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace "librw"
|
workspace "librw"
|
||||||
@@ -64,6 +72,10 @@ workspace "librw"
|
|||||||
defines { "RW_GL3" }
|
defines { "RW_GL3" }
|
||||||
if _OPTIONS["gfxlib"] == "sdl2" then
|
if _OPTIONS["gfxlib"] == "sdl2" then
|
||||||
defines { "LIBRW_SDL2" }
|
defines { "LIBRW_SDL2" }
|
||||||
|
elseif _OPTIONS["gfxlib"] == "sdl3" then
|
||||||
|
defines { "LIBRW_SDL3" }
|
||||||
|
elseif _OPTIONS["gfxlib"] == "glfw" then
|
||||||
|
defines { "LIBRW_GLFW" }
|
||||||
end
|
end
|
||||||
filter { "platforms:*d3d9" }
|
filter { "platforms:*d3d9" }
|
||||||
defines { "RW_D3D9" }
|
defines { "RW_D3D9" }
|
||||||
@@ -131,21 +143,27 @@ function findlibs()
|
|||||||
links { "GL" }
|
links { "GL" }
|
||||||
if _OPTIONS["gfxlib"] == "glfw" then
|
if _OPTIONS["gfxlib"] == "glfw" then
|
||||||
links { "glfw" }
|
links { "glfw" }
|
||||||
else
|
elseif _OPTIONS["gfxlib"] == "sdl2" then
|
||||||
links { "SDL2" }
|
links { "SDL2" }
|
||||||
|
elseif _OPTIONS["gfxlib"] == "sdl3" then
|
||||||
|
links { "SDL3" }
|
||||||
end
|
end
|
||||||
filter { "platforms:win-amd64-gl3" }
|
filter { "platforms:win-amd64-gl3" }
|
||||||
libdirs { path.join(_OPTIONS["glfwdir64"], "lib-vc2015") }
|
libdirs { path.join(_OPTIONS["glfwdir64"], "lib-vc2015") }
|
||||||
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
|
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x64") }
|
||||||
|
libdirs { path.join(_OPTIONS["sdl3dir"], "lib/x64") }
|
||||||
filter { "platforms:win-x86-gl3" }
|
filter { "platforms:win-x86-gl3" }
|
||||||
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-vc2015") }
|
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-vc2015") }
|
||||||
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
|
libdirs { path.join(_OPTIONS["sdl2dir"], "lib/x86") }
|
||||||
|
libdirs { path.join(_OPTIONS["sdl3dir"], "lib/x86") }
|
||||||
filter { "platforms:win*gl3" }
|
filter { "platforms:win*gl3" }
|
||||||
links { "opengl32" }
|
links { "opengl32" }
|
||||||
if _OPTIONS["gfxlib"] == "glfw" then
|
if _OPTIONS["gfxlib"] == "glfw" then
|
||||||
links { "glfw3" }
|
links { "glfw3" }
|
||||||
else
|
elseif _OPTIONS["gfxlib"] == "sdl2" then
|
||||||
links { "SDL2" }
|
links { "SDL2" }
|
||||||
|
elseif _OPTIONS["gfxlib"] == "sdl3" then
|
||||||
|
links { "SDL3" }
|
||||||
end
|
end
|
||||||
filter { "platforms:*d3d9" }
|
filter { "platforms:*d3d9" }
|
||||||
links { "gdi32", "d3d9" }
|
links { "gdi32", "d3d9" }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
add_library(librw_skeleton
|
add_library(librw_skeleton
|
||||||
glfw.cpp
|
glfw.cpp
|
||||||
sdl2.cpp
|
sdl2.cpp
|
||||||
|
sdl3.cpp
|
||||||
skeleton.cpp
|
skeleton.cpp
|
||||||
skeleton.h
|
skeleton.h
|
||||||
win.cpp
|
win.cpp
|
||||||
@@ -38,7 +39,7 @@ target_link_libraries(librw_skeleton
|
|||||||
librw
|
librw
|
||||||
)
|
)
|
||||||
|
|
||||||
if (LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
if (LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
|
||||||
target_compile_definitions(librw_skeleton PRIVATE SDL_MAIN_HANDLED)
|
target_compile_definitions(librw_skeleton PRIVATE SDL_MAIN_HANDLED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
#ifndef LIBRW_SDL2
|
#ifdef LIBRW_GLFW
|
||||||
|
|
||||||
#include <rw.h>
|
#include <rw.h>
|
||||||
#include "skeleton.h"
|
#include "skeleton.h"
|
||||||
|
|||||||
+199
-43
@@ -1,5 +1,5 @@
|
|||||||
// https://github.com/CedricGuillemet/ImGuizmo
|
// https://github.com/CedricGuillemet/ImGuizmo
|
||||||
// v 1.89 WIP
|
// v1.91.3 WIP
|
||||||
//
|
//
|
||||||
// The MIT License(MIT)
|
// The MIT License(MIT)
|
||||||
//
|
//
|
||||||
@@ -666,7 +666,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
struct Context
|
struct Context
|
||||||
{
|
{
|
||||||
Context() : mbUsing(false), mbEnable(true), mbUsingBounds(false)
|
Context() : mbUsing(false), mbUsingViewManipulate(false), mbEnable(true), mIsViewManipulatorHovered(false), mbUsingBounds(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,9 +702,11 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
vec_t mRelativeOrigin;
|
vec_t mRelativeOrigin;
|
||||||
|
|
||||||
bool mbUsing;
|
bool mbUsing;
|
||||||
|
bool mbUsingViewManipulate;
|
||||||
bool mbEnable;
|
bool mbEnable;
|
||||||
bool mbMouseOver;
|
bool mbMouseOver;
|
||||||
bool mReversed; // reversed projection matrix
|
bool mReversed; // reversed projection matrix
|
||||||
|
bool mIsViewManipulatorHovered;
|
||||||
|
|
||||||
// translation
|
// translation
|
||||||
vec_t mTranslationPlan;
|
vec_t mTranslationPlan;
|
||||||
@@ -726,6 +728,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
// save axis factor when using gizmo
|
// save axis factor when using gizmo
|
||||||
bool mBelowAxisLimit[3];
|
bool mBelowAxisLimit[3];
|
||||||
|
int mAxisMask = 0;
|
||||||
bool mBelowPlaneLimit[3];
|
bool mBelowPlaneLimit[3];
|
||||||
float mAxisFactor[3];
|
float mAxisFactor[3];
|
||||||
|
|
||||||
@@ -754,13 +757,25 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
float mDisplayRatio = 1.f;
|
float mDisplayRatio = 1.f;
|
||||||
|
|
||||||
bool mIsOrthographic = false;
|
bool mIsOrthographic = false;
|
||||||
|
// check to not have multiple gizmo highlighted at the same time
|
||||||
|
bool mbOverGizmoHotspot = false;
|
||||||
|
|
||||||
int mActualID = -1;
|
ImGuiWindow* mAlternativeWindow = nullptr;
|
||||||
int mEditingID = -1;
|
ImVector<ImGuiID> mIDStack;
|
||||||
|
ImGuiID mEditingID = -1;
|
||||||
OPERATION mOperation = OPERATION(-1);
|
OPERATION mOperation = OPERATION(-1);
|
||||||
|
|
||||||
bool mAllowAxisFlip = true;
|
bool mAllowAxisFlip = true;
|
||||||
float mGizmoSizeClipSpace = 0.1f;
|
float mGizmoSizeClipSpace = 0.1f;
|
||||||
|
|
||||||
|
inline ImGuiID GetCurrentID()
|
||||||
|
{
|
||||||
|
if (mIDStack.empty())
|
||||||
|
{
|
||||||
|
mIDStack.push_back(-1);
|
||||||
|
}
|
||||||
|
return mIDStack.back();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Context gContext;
|
static Context gContext;
|
||||||
@@ -929,6 +944,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
ImGuiWindow* window = ImGui::FindWindowByName(gContext.mDrawList->_OwnerName);
|
ImGuiWindow* window = ImGui::FindWindowByName(gContext.mDrawList->_OwnerName);
|
||||||
if (g.HoveredWindow == window) // Mouse hovering drawlist window
|
if (g.HoveredWindow == window) // Mouse hovering drawlist window
|
||||||
return true;
|
return true;
|
||||||
|
if (gContext.mAlternativeWindow != nullptr && g.HoveredWindow == gContext.mAlternativeWindow)
|
||||||
|
return true;
|
||||||
if (g.HoveredWindow != NULL) // Any other window is hovered
|
if (g.HoveredWindow != NULL) // Any other window is hovered
|
||||||
return false;
|
return false;
|
||||||
if (ImGui::IsMouseHoveringRect(window->InnerRect.Min, window->InnerRect.Max, false)) // Hovering drawlist window rect, while no other window is hovered (for _NoInputs windows)
|
if (ImGui::IsMouseHoveringRect(window->InnerRect.Min, window->InnerRect.Max, false)) // Hovering drawlist window rect, while no other window is hovered (for _NoInputs windows)
|
||||||
@@ -981,6 +998,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
ImGui::Begin("gizmo", NULL, flags);
|
ImGui::Begin("gizmo", NULL, flags);
|
||||||
gContext.mDrawList = ImGui::GetWindowDrawList();
|
gContext.mDrawList = ImGui::GetWindowDrawList();
|
||||||
|
gContext.mbOverGizmoHotspot = false;
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
@@ -988,7 +1006,17 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
bool IsUsing()
|
bool IsUsing()
|
||||||
{
|
{
|
||||||
return (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID)) || gContext.mbUsingBounds;
|
return (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) || gContext.mbUsingBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUsingViewManipulate()
|
||||||
|
{
|
||||||
|
return gContext.mbUsingViewManipulate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsViewManipulateHovered()
|
||||||
|
{
|
||||||
|
return gContext.mIsViewManipulatorHovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUsingAny()
|
bool IsUsingAny()
|
||||||
@@ -1078,7 +1106,6 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// compute scale from the size of camera right vector projected on screen at the matrix position
|
// compute scale from the size of camera right vector projected on screen at the matrix position
|
||||||
vec_t pointRight = viewInverse.v.right;
|
vec_t pointRight = viewInverse.v.right;
|
||||||
pointRight.TransformPoint(gContext.mViewProjection);
|
pointRight.TransformPoint(gContext.mViewProjection);
|
||||||
gContext.mScreenFactor = gContext.mGizmoSizeClipSpace / (pointRight.x / pointRight.w - gContext.mMVP.v.position.x / gContext.mMVP.v.position.w);
|
|
||||||
|
|
||||||
vec_t rightViewInverse = viewInverse.v.right;
|
vec_t rightViewInverse = viewInverse.v.right;
|
||||||
rightViewInverse.TransformVector(gContext.mModelInverse);
|
rightViewInverse.TransformVector(gContext.mModelInverse);
|
||||||
@@ -1146,11 +1173,13 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
dirPlaneX = directionUnary[(axisIndex + 1) % 3];
|
dirPlaneX = directionUnary[(axisIndex + 1) % 3];
|
||||||
dirPlaneY = directionUnary[(axisIndex + 2) % 3];
|
dirPlaneY = directionUnary[(axisIndex + 2) % 3];
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
// when using, use stored factors so the gizmo doesn't flip when we translate
|
// when using, use stored factors so the gizmo doesn't flip when we translate
|
||||||
belowAxisLimit = gContext.mBelowAxisLimit[axisIndex];
|
|
||||||
belowPlaneLimit = gContext.mBelowPlaneLimit[axisIndex];
|
// Apply axis mask to axes and planes
|
||||||
|
belowAxisLimit = gContext.mBelowAxisLimit[axisIndex] && ((1<<axisIndex)&gContext.mAxisMask);
|
||||||
|
belowPlaneLimit = gContext.mBelowPlaneLimit[axisIndex] && (((1<<axisIndex) == gContext.mAxisMask) || !gContext.mAxisMask);
|
||||||
|
|
||||||
dirAxis *= gContext.mAxisFactor[axisIndex];
|
dirAxis *= gContext.mAxisFactor[axisIndex];
|
||||||
dirPlaneX *= gContext.mAxisFactor[(axisIndex + 1) % 3];
|
dirPlaneX *= gContext.mAxisFactor[(axisIndex + 1) % 3];
|
||||||
@@ -1181,8 +1210,9 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
float axisLengthInClipSpace = GetSegmentLengthClipSpace(makeVect(0.f, 0.f, 0.f), dirAxis * gContext.mScreenFactor, localCoordinates);
|
float axisLengthInClipSpace = GetSegmentLengthClipSpace(makeVect(0.f, 0.f, 0.f), dirAxis * gContext.mScreenFactor, localCoordinates);
|
||||||
|
|
||||||
float paraSurf = GetParallelogram(makeVect(0.f, 0.f, 0.f), dirPlaneX * gContext.mScreenFactor, dirPlaneY * gContext.mScreenFactor);
|
float paraSurf = GetParallelogram(makeVect(0.f, 0.f, 0.f), dirPlaneX * gContext.mScreenFactor, dirPlaneY * gContext.mScreenFactor);
|
||||||
belowPlaneLimit = (paraSurf > gContext.mAxisLimit);
|
// Apply axis mask to axes and planes
|
||||||
belowAxisLimit = (axisLengthInClipSpace > gContext.mPlaneLimit);
|
belowPlaneLimit = (paraSurf > gContext.mAxisLimit) && (((1<<axisIndex) == gContext.mAxisMask) || !gContext.mAxisMask);
|
||||||
|
belowAxisLimit = (axisLengthInClipSpace > gContext.mPlaneLimit) && !((1<<axisIndex)&gContext.mAxisMask);
|
||||||
|
|
||||||
// and store values
|
// and store values
|
||||||
gContext.mAxisFactor[axisIndex] = mulAxis;
|
gContext.mAxisFactor[axisIndex] = mulAxis;
|
||||||
@@ -1241,6 +1271,9 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
}
|
}
|
||||||
ImDrawList* drawList = gContext.mDrawList;
|
ImDrawList* drawList = gContext.mDrawList;
|
||||||
|
|
||||||
|
bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0;
|
||||||
|
bool isNoAxesMasked = !gContext.mAxisMask;
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
ImU32 colors[7];
|
ImU32 colors[7];
|
||||||
ComputeColors(colors, type, ROTATE);
|
ComputeColors(colors, type, ROTATE);
|
||||||
@@ -1268,8 +1301,15 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAxisMasked = ((1 << (2 - axis)) & gContext.mAxisMask) != 0;
|
||||||
|
|
||||||
|
if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const bool usingAxis = (gContext.mbUsing && type == MT_ROTATE_Z - axis);
|
const bool usingAxis = (gContext.mbUsing && type == MT_ROTATE_Z - axis);
|
||||||
const int circleMul = (hasRSC && !usingAxis ) ? 1 : 2;
|
const int circleMul = (hasRSC && !usingAxis) ? 1 : 2;
|
||||||
|
|
||||||
ImVec2* circlePos = (ImVec2*)alloca(sizeof(ImVec2) * (circleMul * halfCircleSegmentCount + 1));
|
ImVec2* circlePos = (ImVec2*)alloca(sizeof(ImVec2) * (circleMul * halfCircleSegmentCount + 1));
|
||||||
|
|
||||||
@@ -1293,12 +1333,12 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
gContext.mRadiusSquareCenter = radiusAxis;
|
gContext.mRadiusSquareCenter = radiusAxis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(hasRSC && (!gContext.mbUsing || type == MT_ROTATE_SCREEN))
|
if(hasRSC && (!gContext.mbUsing || type == MT_ROTATE_SCREEN) && (!isMultipleAxesMasked && isNoAxesMasked))
|
||||||
{
|
{
|
||||||
drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), gContext.mRadiusSquareCenter, colors[0], 64, gContext.mStyle.RotationOuterLineThickness);
|
drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), gContext.mRadiusSquareCenter, colors[0], 64, gContext.mStyle.RotationOuterLineThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsRotateType(type))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsRotateType(type))
|
||||||
{
|
{
|
||||||
ImVec2 circlePos[halfCircleSegmentCount + 1];
|
ImVec2 circlePos[halfCircleSegmentCount + 1];
|
||||||
|
|
||||||
@@ -1355,7 +1395,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// draw
|
// draw
|
||||||
vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
|
vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
scaleDisplay = gContext.mScale;
|
scaleDisplay = gContext.mScale;
|
||||||
}
|
}
|
||||||
@@ -1382,7 +1422,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
ImVec2 worldDirSSpaceNoScale = worldToPos(dirAxis * markerScale * gContext.mScreenFactor, gContext.mMVP);
|
ImVec2 worldDirSSpaceNoScale = worldToPos(dirAxis * markerScale * gContext.mScreenFactor, gContext.mMVP);
|
||||||
ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVP);
|
ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVP);
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
ImU32 scaleLineColor = GetColorU32(SCALE_LINE);
|
ImU32 scaleLineColor = GetColorU32(SCALE_LINE);
|
||||||
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, scaleLineColor, gContext.mStyle.ScaleLineThickness);
|
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, scaleLineColor, gContext.mStyle.ScaleLineThickness);
|
||||||
@@ -1406,7 +1446,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// draw screen cirle
|
// draw screen cirle
|
||||||
drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32);
|
drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32);
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsScaleType(type))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(type))
|
||||||
{
|
{
|
||||||
//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
||||||
ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
||||||
@@ -1443,7 +1483,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// draw
|
// draw
|
||||||
vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
|
vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
scaleDisplay = gContext.mScale;
|
scaleDisplay = gContext.mScale;
|
||||||
}
|
}
|
||||||
@@ -1471,7 +1511,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVPLocal);
|
ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVPLocal);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, IM_COL32(0x40, 0x40, 0x40, 0xFF), 3.f);
|
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, IM_COL32(0x40, 0x40, 0x40, 0xFF), 3.f);
|
||||||
drawList->AddCircleFilled(worldDirSSpaceNoScale, 6.f, IM_COL32(0x40, 0x40, 0x40, 0xFF));
|
drawList->AddCircleFilled(worldDirSSpaceNoScale, 6.f, IM_COL32(0x40, 0x40, 0x40, 0xFF));
|
||||||
@@ -1491,7 +1531,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// draw screen cirle
|
// draw screen cirle
|
||||||
drawList->AddCircle(gContext.mScreenSquareCenter, 20.f, colors[0], 32, gContext.mStyle.CenterCircleSize);
|
drawList->AddCircle(gContext.mScreenSquareCenter, 20.f, colors[0], 32, gContext.mStyle.CenterCircleSize);
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsScaleType(type))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(type))
|
||||||
{
|
{
|
||||||
//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
||||||
ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
||||||
@@ -1585,7 +1625,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32);
|
drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32);
|
||||||
|
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsTranslateType(type))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsTranslateType(type))
|
||||||
{
|
{
|
||||||
ImU32 translationLineColor = GetColorU32(TRANSLATION_LINE);
|
ImU32 translationLineColor = GetColorU32(TRANSLATION_LINE);
|
||||||
|
|
||||||
@@ -1779,7 +1819,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
gContext.mBoundsLocalPivot[thirdAxis] = aabb[oppositeIndex][thirdAxis];
|
gContext.mBoundsLocalPivot[thirdAxis] = aabb[oppositeIndex][thirdAxis];
|
||||||
|
|
||||||
gContext.mbUsingBounds = true;
|
gContext.mbUsingBounds = true;
|
||||||
gContext.mEditingID = gContext.mActualID;
|
gContext.mEditingID = gContext.GetCurrentID();
|
||||||
gContext.mBoundsMatrix = gContext.mModelSource;
|
gContext.mBoundsMatrix = gContext.mModelSource;
|
||||||
}
|
}
|
||||||
// small anchor on middle of segment
|
// small anchor on middle of segment
|
||||||
@@ -1798,12 +1838,12 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
gContext.mBoundsLocalPivot[gContext.mBoundsAxis[0]] = aabb[oppositeIndex][indices[i % 2]];// bounds[gContext.mBoundsAxis[0]] * (((i + 1) & 2) ? 1.f : -1.f);
|
gContext.mBoundsLocalPivot[gContext.mBoundsAxis[0]] = aabb[oppositeIndex][indices[i % 2]];// bounds[gContext.mBoundsAxis[0]] * (((i + 1) & 2) ? 1.f : -1.f);
|
||||||
|
|
||||||
gContext.mbUsingBounds = true;
|
gContext.mbUsingBounds = true;
|
||||||
gContext.mEditingID = gContext.mActualID;
|
gContext.mEditingID = gContext.GetCurrentID();
|
||||||
gContext.mBoundsMatrix = gContext.mModelSource;
|
gContext.mBoundsMatrix = gContext.mModelSource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gContext.mbUsingBounds && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID))
|
if (gContext.mbUsingBounds && (gContext.GetCurrentID() == gContext.mEditingID))
|
||||||
{
|
{
|
||||||
matrix_t scale;
|
matrix_t scale;
|
||||||
scale.SetToIdentity();
|
scale.SetToIdentity();
|
||||||
@@ -1904,6 +1944,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0;
|
||||||
|
|
||||||
vec_t dirPlaneX, dirPlaneY, dirAxis;
|
vec_t dirPlaneX, dirPlaneY, dirAxis;
|
||||||
bool belowAxisLimit, belowPlaneLimit;
|
bool belowAxisLimit, belowPlaneLimit;
|
||||||
ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true);
|
ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true);
|
||||||
@@ -1924,7 +1966,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
if ((closestPointOnAxis - makeVect(posOnPlanScreen)).Length() < 12.f) // pixel size
|
if ((closestPointOnAxis - makeVect(posOnPlanScreen)).Length() < 12.f) // pixel size
|
||||||
{
|
{
|
||||||
type = MT_SCALE_X + i;
|
if (!isAxisMasked)
|
||||||
|
type = MT_SCALE_X + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1973,6 +2016,10 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
return MT_NONE;
|
return MT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNoAxesMasked = !gContext.mAxisMask;
|
||||||
|
bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
int type = MT_NONE;
|
int type = MT_NONE;
|
||||||
|
|
||||||
@@ -1980,6 +2027,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
float dist = deltaScreen.Length();
|
float dist = deltaScreen.Length();
|
||||||
if (Intersects(op, ROTATE_SCREEN) && dist >= (gContext.mRadiusSquareCenter - 4.0f) && dist < (gContext.mRadiusSquareCenter + 4.0f))
|
if (Intersects(op, ROTATE_SCREEN) && dist >= (gContext.mRadiusSquareCenter - 4.0f) && dist < (gContext.mRadiusSquareCenter + 4.0f))
|
||||||
{
|
{
|
||||||
|
if (!isNoAxesMasked)
|
||||||
|
return MT_NONE;
|
||||||
type = MT_ROTATE_SCREEN;
|
type = MT_ROTATE_SCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1994,6 +2043,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0;
|
||||||
// pickup plan
|
// pickup plan
|
||||||
vec_t pickupPlan = BuildPlan(gContext.mModel.v.position, planNormals[i]);
|
vec_t pickupPlan = BuildPlan(gContext.mModel.v.position, planNormals[i]);
|
||||||
|
|
||||||
@@ -2018,6 +2068,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
const float distance = makeVect(distanceOnScreen).Length();
|
const float distance = makeVect(distanceOnScreen).Length();
|
||||||
if (distance < 8.f) // pixel size
|
if (distance < 8.f) // pixel size
|
||||||
{
|
{
|
||||||
|
if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked)
|
||||||
|
break;
|
||||||
type = MT_ROTATE_X + i;
|
type = MT_ROTATE_X + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2031,6 +2083,10 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
return MT_NONE;
|
return MT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNoAxesMasked = !gContext.mAxisMask;
|
||||||
|
bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
int type = MT_NONE;
|
int type = MT_NONE;
|
||||||
|
|
||||||
@@ -2047,6 +2103,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// compute
|
// compute
|
||||||
for (int i = 0; i < 3 && type == MT_NONE; i++)
|
for (int i = 0; i < 3 && type == MT_NONE; i++)
|
||||||
{
|
{
|
||||||
|
bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0;
|
||||||
vec_t dirPlaneX, dirPlaneY, dirAxis;
|
vec_t dirPlaneX, dirPlaneY, dirAxis;
|
||||||
bool belowAxisLimit, belowPlaneLimit;
|
bool belowAxisLimit, belowPlaneLimit;
|
||||||
ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
|
ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
|
||||||
@@ -2063,6 +2120,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
vec_t closestPointOnAxis = PointOnSegment(screenCoord, makeVect(axisStartOnScreen), makeVect(axisEndOnScreen));
|
vec_t closestPointOnAxis = PointOnSegment(screenCoord, makeVect(axisStartOnScreen), makeVect(axisEndOnScreen));
|
||||||
if ((closestPointOnAxis - screenCoord).Length() < 12.f && Intersects(op, static_cast<OPERATION>(TRANSLATE_X << i))) // pixel size
|
if ((closestPointOnAxis - screenCoord).Length() < 12.f && Intersects(op, static_cast<OPERATION>(TRANSLATE_X << i))) // pixel size
|
||||||
{
|
{
|
||||||
|
if (isAxisMasked)
|
||||||
|
break;
|
||||||
type = MT_MOVE_X + i;
|
type = MT_MOVE_X + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2070,6 +2129,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
const float dy = dirPlaneY.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
const float dy = dirPlaneY.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
||||||
if (belowPlaneLimit && dx >= quadUV[0] && dx <= quadUV[4] && dy >= quadUV[1] && dy <= quadUV[3] && Contains(op, TRANSLATE_PLANS[i]))
|
if (belowPlaneLimit && dx >= quadUV[0] && dx <= quadUV[4] && dy >= quadUV[1] && dy <= quadUV[3] && Contains(op, TRANSLATE_PLANS[i]))
|
||||||
{
|
{
|
||||||
|
if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked)
|
||||||
|
break;
|
||||||
type = MT_MOVE_YZ + i;
|
type = MT_MOVE_YZ + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2092,7 +2153,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// move
|
// move
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsTranslateType(gContext.mCurrentOperation))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsTranslateType(gContext.mCurrentOperation))
|
||||||
{
|
{
|
||||||
#if IMGUI_VERSION_NUM >= 18723
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||||
@@ -2166,7 +2227,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
// find new possible way to move
|
// find new possible way to move
|
||||||
vec_t gizmoHitProportion;
|
vec_t gizmoHitProportion;
|
||||||
type = GetMoveType(op, &gizmoHitProportion);
|
type = gContext.mbOverGizmoHotspot ? MT_NONE : GetMoveType(op, &gizmoHitProportion);
|
||||||
|
gContext.mbOverGizmoHotspot |= type != MT_NONE;
|
||||||
if (type != MT_NONE)
|
if (type != MT_NONE)
|
||||||
{
|
{
|
||||||
#if IMGUI_VERSION_NUM >= 18723
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
@@ -2178,7 +2240,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
if (CanActivate() && type != MT_NONE)
|
if (CanActivate() && type != MT_NONE)
|
||||||
{
|
{
|
||||||
gContext.mbUsing = true;
|
gContext.mbUsing = true;
|
||||||
gContext.mEditingID = gContext.mActualID;
|
gContext.mEditingID = gContext.GetCurrentID();
|
||||||
gContext.mCurrentOperation = type;
|
gContext.mCurrentOperation = type;
|
||||||
vec_t movePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir,
|
vec_t movePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir,
|
||||||
gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir,
|
gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir,
|
||||||
@@ -2215,7 +2277,9 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
if (!gContext.mbUsing)
|
if (!gContext.mbUsing)
|
||||||
{
|
{
|
||||||
// find new possible way to scale
|
// find new possible way to scale
|
||||||
type = GetScaleType(op);
|
type = gContext.mbOverGizmoHotspot ? MT_NONE : GetScaleType(op);
|
||||||
|
gContext.mbOverGizmoHotspot |= type != MT_NONE;
|
||||||
|
|
||||||
if (type != MT_NONE)
|
if (type != MT_NONE)
|
||||||
{
|
{
|
||||||
#if IMGUI_VERSION_NUM >= 18723
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
@@ -2227,23 +2291,23 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
if (CanActivate() && type != MT_NONE)
|
if (CanActivate() && type != MT_NONE)
|
||||||
{
|
{
|
||||||
gContext.mbUsing = true;
|
gContext.mbUsing = true;
|
||||||
gContext.mEditingID = gContext.mActualID;
|
gContext.mEditingID = gContext.GetCurrentID();
|
||||||
gContext.mCurrentOperation = type;
|
gContext.mCurrentOperation = type;
|
||||||
const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.up, gContext.mModel.v.right, -gContext.mCameraDir };
|
const vec_t movePlanNormal[] = { gContext.mModelLocal.v.up, gContext.mModelLocal.v.dir, gContext.mModelLocal.v.right, gContext.mModelLocal.v.dir, gContext.mModelLocal.v.up, gContext.mModelLocal.v.right, -gContext.mCameraDir };
|
||||||
// pickup plan
|
// pickup plan
|
||||||
|
|
||||||
gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - MT_SCALE_X]);
|
gContext.mTranslationPlan = BuildPlan(gContext.mModelLocal.v.position, movePlanNormal[type - MT_SCALE_X]);
|
||||||
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
||||||
gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
|
gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
|
||||||
gContext.mMatrixOrigin = gContext.mModel.v.position;
|
gContext.mMatrixOrigin = gContext.mModelLocal.v.position;
|
||||||
gContext.mScale.Set(1.f, 1.f, 1.f);
|
gContext.mScale.Set(1.f, 1.f, 1.f);
|
||||||
gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
|
gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModelLocal.v.position) * (1.f / gContext.mScreenFactor);
|
||||||
gContext.mScaleValueOrigin = makeVect(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
|
gContext.mScaleValueOrigin = makeVect(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
|
||||||
gContext.mSaveMousePosx = io.MousePos.x;
|
gContext.mSaveMousePosx = io.MousePos.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// scale
|
// scale
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsScaleType(gContext.mCurrentOperation))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(gContext.mCurrentOperation))
|
||||||
{
|
{
|
||||||
#if IMGUI_VERSION_NUM >= 18723
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||||
@@ -2336,7 +2400,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
if (!gContext.mbUsing)
|
if (!gContext.mbUsing)
|
||||||
{
|
{
|
||||||
type = GetRotateType(op);
|
type = gContext.mbOverGizmoHotspot ? MT_NONE : GetRotateType(op);
|
||||||
|
gContext.mbOverGizmoHotspot |= type != MT_NONE;
|
||||||
|
|
||||||
if (type != MT_NONE)
|
if (type != MT_NONE)
|
||||||
{
|
{
|
||||||
@@ -2355,7 +2420,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
if (CanActivate() && type != MT_NONE)
|
if (CanActivate() && type != MT_NONE)
|
||||||
{
|
{
|
||||||
gContext.mbUsing = true;
|
gContext.mbUsing = true;
|
||||||
gContext.mEditingID = gContext.mActualID;
|
gContext.mEditingID = gContext.GetCurrentID();
|
||||||
gContext.mCurrentOperation = type;
|
gContext.mCurrentOperation = type;
|
||||||
const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
|
const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
|
||||||
// pickup plan
|
// pickup plan
|
||||||
@@ -2376,7 +2441,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rotation
|
// rotation
|
||||||
if (gContext.mbUsing && (gContext.mActualID == -1 || gContext.mActualID == gContext.mEditingID) && IsRotateType(gContext.mCurrentOperation))
|
if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsRotateType(gContext.mCurrentOperation))
|
||||||
{
|
{
|
||||||
#if IMGUI_VERSION_NUM >= 18723
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||||
@@ -2482,9 +2547,74 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
mat.v.position.Set(translation[0], translation[1], translation[2], 1.f);
|
mat.v.position.Set(translation[0], translation[1], translation[2], 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAlternativeWindow(ImGuiWindow* window)
|
||||||
|
{
|
||||||
|
gContext.mAlternativeWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
void SetID(int id)
|
void SetID(int id)
|
||||||
{
|
{
|
||||||
gContext.mActualID = id;
|
if (gContext.mIDStack.empty())
|
||||||
|
{
|
||||||
|
gContext.mIDStack.push_back(-1);
|
||||||
|
}
|
||||||
|
gContext.mIDStack.back() = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiID GetID(const char* str, const char* str_end)
|
||||||
|
{
|
||||||
|
ImGuiID seed = gContext.GetCurrentID();
|
||||||
|
ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiID GetID(const char* str)
|
||||||
|
{
|
||||||
|
return GetID(str, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiID GetID(const void* ptr)
|
||||||
|
{
|
||||||
|
ImGuiID seed = gContext.GetCurrentID();
|
||||||
|
ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiID GetID(int n)
|
||||||
|
{
|
||||||
|
ImGuiID seed = gContext.GetCurrentID();
|
||||||
|
ImGuiID id = ImHashData(&n, sizeof(n), seed);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushID(const char* str_id)
|
||||||
|
{
|
||||||
|
ImGuiID id = GetID(str_id);
|
||||||
|
gContext.mIDStack.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushID(const char* str_id_begin, const char* str_id_end)
|
||||||
|
{
|
||||||
|
ImGuiID id = GetID(str_id_begin, str_id_end);
|
||||||
|
gContext.mIDStack.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushID(const void* ptr_id)
|
||||||
|
{
|
||||||
|
ImGuiID id = GetID(ptr_id);
|
||||||
|
gContext.mIDStack.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushID(int int_id)
|
||||||
|
{
|
||||||
|
ImGuiID id = GetID(int_id);
|
||||||
|
gContext.mIDStack.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopID()
|
||||||
|
{
|
||||||
|
IM_ASSERT(gContext.mIDStack.Size > 1); // Too many PopID(), or could be popping in a wrong/different window?
|
||||||
|
gContext.mIDStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllowAxisFlip(bool value)
|
void AllowAxisFlip(bool value)
|
||||||
@@ -2497,13 +2627,28 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
gContext.mAxisLimit=value;
|
gContext.mAxisLimit=value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAxisMask(bool x, bool y, bool z)
|
||||||
|
{
|
||||||
|
gContext.mAxisMask = (x ? 1 : 0) + (y ? 2 : 0) + (z ? 4 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
void SetPlaneLimit(float value)
|
void SetPlaneLimit(float value)
|
||||||
{
|
{
|
||||||
gContext.mPlaneLimit = value;
|
gContext.mPlaneLimit = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsOver(float* position, float pixelRadius)
|
||||||
|
{
|
||||||
|
const ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
float radius = sqrtf((ImLengthSqr(worldToPos({ position[0], position[1], position[2], 0.0f }, gContext.mViewProjection) - io.MousePos)));
|
||||||
|
return radius < pixelRadius;
|
||||||
|
}
|
||||||
|
|
||||||
bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix, const float* snap, const float* localBounds, const float* boundsSnap)
|
bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix, const float* snap, const float* localBounds, const float* boundsSnap)
|
||||||
{
|
{
|
||||||
|
gContext.mDrawList->PushClipRect (ImVec2 (gContext.mX, gContext.mY), ImVec2 (gContext.mX + gContext.mWidth, gContext.mY + gContext.mHeight), false);
|
||||||
|
|
||||||
// Scale is always local or matrix will be skewed when applying world scale or oriented matrix
|
// Scale is always local or matrix will be skewed when applying world scale or oriented matrix
|
||||||
ComputeContext(view, projection, matrix, (operation & SCALE) ? LOCAL : mode);
|
ComputeContext(view, projection, matrix, (operation & SCALE) ? LOCAL : mode);
|
||||||
|
|
||||||
@@ -2547,6 +2692,8 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
DrawScaleGizmo(operation, type);
|
DrawScaleGizmo(operation, type);
|
||||||
DrawScaleUniveralGizmo(operation, type);
|
DrawScaleUniveralGizmo(operation, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gContext.mDrawList->PopClipRect ();
|
||||||
return manipulated;
|
return manipulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2775,7 +2922,6 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
{
|
{
|
||||||
static bool isDraging = false;
|
static bool isDraging = false;
|
||||||
static bool isClicking = false;
|
static bool isClicking = false;
|
||||||
static bool isInside = false;
|
|
||||||
static vec_t interpolationUp;
|
static vec_t interpolationUp;
|
||||||
static vec_t interpolationDir;
|
static vec_t interpolationDir;
|
||||||
static int interpolationFrames = 0;
|
static int interpolationFrames = 0;
|
||||||
@@ -2888,10 +3034,11 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
if (iPass)
|
if (iPass)
|
||||||
{
|
{
|
||||||
ImU32 directionColor = GetColorU32(DIRECTION_X + normalIndex);
|
ImU32 directionColor = GetColorU32(DIRECTION_X + normalIndex);
|
||||||
gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, (directionColor | IM_COL32(0x80, 0x80, 0x80, 0x80)) | (isInside ? IM_COL32(0x08, 0x08, 0x08, 0) : 0));
|
gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, (directionColor | IM_COL32(0x80, 0x80, 0x80, 0x80)) | (gContext.mIsViewManipulatorHovered ? IM_COL32(0x08, 0x08, 0x08, 0) : 0));
|
||||||
if (boxes[boxCoordInt])
|
if (boxes[boxCoordInt])
|
||||||
{
|
{
|
||||||
gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, IM_COL32(0xF0, 0xA0, 0x60, 0x80));
|
ImU32 selectionColor = GetColorU32(SELECTION);
|
||||||
|
gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, selectionColor);
|
||||||
|
|
||||||
if (io.MouseDown[0] && !isClicking && !isDraging && GImGui->ActiveId == 0) {
|
if (io.MouseDown[0] && !isClicking && !isDraging && GImGui->ActiveId == 0) {
|
||||||
overBox = boxCoordInt;
|
overBox = boxCoordInt;
|
||||||
@@ -2917,7 +3064,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
vec_t newEye = camTarget + newDir * length;
|
vec_t newEye = camTarget + newDir * length;
|
||||||
LookAt(&newEye.x, &camTarget.x, &newUp.x, view);
|
LookAt(&newEye.x, &camTarget.x, &newUp.x, view);
|
||||||
}
|
}
|
||||||
isInside = gContext.mbMouseOver && ImRect(position, position + size).Contains(io.MousePos);
|
gContext.mIsViewManipulatorHovered = gContext.mbMouseOver && ImRect(position, position + size).Contains(io.MousePos);
|
||||||
|
|
||||||
if (io.MouseDown[0] && (fabsf(io.MouseDelta[0]) || fabsf(io.MouseDelta[1])) && isClicking)
|
if (io.MouseDown[0] && (fabsf(io.MouseDelta[0]) || fabsf(io.MouseDelta[1])) && isClicking)
|
||||||
{
|
{
|
||||||
@@ -2990,6 +3137,15 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
LookAt(&newEye.x, &camTarget.x, &referenceUp.x, view);
|
LookAt(&newEye.x, &camTarget.x, &referenceUp.x, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gContext.mbUsingViewManipulate = (interpolationFrames != 0) || isDraging;
|
||||||
|
if (isClicking || gContext.mbUsingViewManipulate || gContext.mIsViewManipulatorHovered) {
|
||||||
|
#if IMGUI_VERSION_NUM >= 18723
|
||||||
|
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||||
|
#else
|
||||||
|
ImGui::CaptureMouseFromApp();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// restore view/projection because it was used to compute ray
|
// restore view/projection because it was used to compute ray
|
||||||
ComputeContext(svgView.m16, svgProjection.m16, gContext.mModelSource.m16, gContext.mMode);
|
ComputeContext(svgView.m16, svgProjection.m16, gContext.mModelSource.m16, gContext.mMode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// https://github.com/CedricGuillemet/ImGuizmo
|
// https://github.com/CedricGuillemet/ImGuizmo
|
||||||
// v 1.89 WIP
|
// v1.91.3 WIP
|
||||||
//
|
//
|
||||||
// The MIT License(MIT)
|
// The MIT License(MIT)
|
||||||
//
|
//
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
// - display rotation/translation/scale infos in local/world space and not only local
|
// - display rotation/translation/scale infos in local/world space and not only local
|
||||||
// - finish local/world matrix application
|
// - finish local/world matrix application
|
||||||
// - OPERATION as bitmask
|
// - OPERATION as bitmask
|
||||||
//
|
//
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
// Example
|
// Example
|
||||||
#if 0
|
#if 0
|
||||||
void EditTransform(const Camera& camera, matrix_t& matrix)
|
void EditTransform(const Camera& camera, matrix_t& matrix)
|
||||||
{
|
{
|
||||||
@@ -115,6 +115,8 @@ void EditTransform(const Camera& camera, matrix_t& matrix)
|
|||||||
#define IMGUIZMO_NAMESPACE ImGuizmo
|
#define IMGUIZMO_NAMESPACE ImGuizmo
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ImGuiWindow;
|
||||||
|
|
||||||
namespace IMGUIZMO_NAMESPACE
|
namespace IMGUIZMO_NAMESPACE
|
||||||
{
|
{
|
||||||
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
|
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
|
||||||
@@ -136,6 +138,11 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// return true if mouse IsOver or if the gizmo is in moving state
|
// return true if mouse IsOver or if the gizmo is in moving state
|
||||||
IMGUI_API bool IsUsing();
|
IMGUI_API bool IsUsing();
|
||||||
|
|
||||||
|
// return true if the view gizmo is in moving state
|
||||||
|
IMGUI_API bool IsUsingViewManipulate();
|
||||||
|
// only check if your mouse is over the view manipulator - no matter whether it's active or not
|
||||||
|
IMGUI_API bool IsViewManipulateHovered();
|
||||||
|
|
||||||
// return true if any gizmo is in moving state
|
// return true if any gizmo is in moving state
|
||||||
IMGUI_API bool IsUsingAny();
|
IMGUI_API bool IsUsingAny();
|
||||||
|
|
||||||
@@ -167,7 +174,7 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
IMGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize);
|
IMGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize);
|
||||||
|
|
||||||
// call it when you want a gizmo
|
// call it when you want a gizmo
|
||||||
// Needs view and projection matrices.
|
// Needs view and projection matrices.
|
||||||
// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
|
// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
|
||||||
// translation is applied in world space
|
// translation is applied in world space
|
||||||
enum OPERATION
|
enum OPERATION
|
||||||
@@ -216,8 +223,31 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
// use this version if you did not call Manipulate before and you are just using ViewManipulate
|
// use this version if you did not call Manipulate before and you are just using ViewManipulate
|
||||||
IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
|
IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
|
||||||
|
|
||||||
|
IMGUI_API void SetAlternativeWindow(ImGuiWindow* window);
|
||||||
|
|
||||||
|
[[deprecated("Use PushID/PopID instead.")]]
|
||||||
IMGUI_API void SetID(int id);
|
IMGUI_API void SetID(int id);
|
||||||
|
|
||||||
|
// ID stack/scopes
|
||||||
|
// Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
|
||||||
|
// - Those questions are answered and impacted by understanding of the ID stack system:
|
||||||
|
// - "Q: Why is my widget not reacting when I click on it?"
|
||||||
|
// - "Q: How can I have widgets with an empty label?"
|
||||||
|
// - "Q: How can I have multiple widgets with the same label?"
|
||||||
|
// - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely
|
||||||
|
// want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
|
||||||
|
// - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
|
||||||
|
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
|
||||||
|
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
|
||||||
|
IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).
|
||||||
|
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
|
||||||
|
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
|
||||||
|
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
|
||||||
|
IMGUI_API void PopID(); // pop from the ID stack.
|
||||||
|
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
|
||||||
|
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);
|
||||||
|
IMGUI_API ImGuiID GetID(const void* ptr_id);
|
||||||
|
|
||||||
// return true if the cursor is over the operation's gizmo
|
// return true if the cursor is over the operation's gizmo
|
||||||
IMGUI_API bool IsOver(OPERATION op);
|
IMGUI_API bool IsOver(OPERATION op);
|
||||||
IMGUI_API void SetGizmoSizeClipSpace(float value);
|
IMGUI_API void SetGizmoSizeClipSpace(float value);
|
||||||
@@ -229,8 +259,12 @@ namespace IMGUIZMO_NAMESPACE
|
|||||||
|
|
||||||
// Configure the limit where axis are hidden
|
// Configure the limit where axis are hidden
|
||||||
IMGUI_API void SetAxisLimit(float value);
|
IMGUI_API void SetAxisLimit(float value);
|
||||||
|
// Set an axis mask to permanently hide a given axis (true -> hidden, false -> shown)
|
||||||
|
IMGUI_API void SetAxisMask(bool x, bool y, bool z);
|
||||||
// Configure the limit where planes are hiden
|
// Configure the limit where planes are hiden
|
||||||
IMGUI_API void SetPlaneLimit(float value);
|
IMGUI_API void SetPlaneLimit(float value);
|
||||||
|
// from a x,y,z point in space and using Manipulation view/projection matrix, check if mouse is in pixel radius distance of that projected point
|
||||||
|
IMGUI_API bool IsOver(float* position, float pixelRadius);
|
||||||
|
|
||||||
enum COLOR
|
enum COLOR
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2021 Omar Cornut
|
Copyright (c) 2014-2025 Omar Cornut
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
|
|
||||||
|
|
||||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||||
@@ -43,12 +42,13 @@
|
|||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default io.PlatformOpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
//---- Enable Test Engine / Automation features.
|
//---- Enable Test Engine / Automation features.
|
||||||
@@ -59,9 +59,12 @@
|
|||||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||||
|
|
||||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
|
||||||
|
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||||
|
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||||
|
|
||||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||||
//#define IMGUI_USE_WCHAR32
|
//#define IMGUI_USE_WCHAR32
|
||||||
|
|
||||||
@@ -83,10 +86,12 @@
|
|||||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||||
//#define IMGUI_ENABLE_FREETYPE
|
//#define IMGUI_ENABLE_FREETYPE
|
||||||
|
|
||||||
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||||
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
|
||||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||||
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||||
|
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||||
|
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
|
|
||||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||||
@@ -124,6 +129,10 @@
|
|||||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||||
//#define IM_DEBUG_BREAK __debugbreak()
|
//#define IM_DEBUG_BREAK __debugbreak()
|
||||||
|
|
||||||
|
//---- Debug Tools: Enable highlight ID conflicts _before_ hovering items. When io.ConfigDebugHighlightIdConflicts is set.
|
||||||
|
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
|
||||||
|
//#define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
|
||||||
|
|
||||||
//---- Debug Tools: Enable slower asserts
|
//---- Debug Tools: Enable slower asserts
|
||||||
//#define IMGUI_DEBUG_PARANOID
|
//#define IMGUI_DEBUG_PARANOID
|
||||||
|
|
||||||
|
|||||||
+3115
-1501
File diff suppressed because it is too large
Load Diff
+924
-432
File diff suppressed because it is too large
Load Diff
+2246
-1725
File diff suppressed because it is too large
Load Diff
+2723
-1051
File diff suppressed because it is too large
Load Diff
@@ -80,7 +80,7 @@ ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
|
|||||||
if(pcmd->UserCallback)
|
if(pcmd->UserCallback)
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
else{
|
else{
|
||||||
rw::Texture *tex = (rw::Texture*)pcmd->TextureId;
|
rw::Texture *tex = (rw::Texture*)pcmd->GetTexID();
|
||||||
if(tex && tex->raster){
|
if(tex && tex->raster){
|
||||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||||
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
|
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
|
||||||
@@ -116,26 +116,6 @@ ImGui_ImplRW_Init(void)
|
|||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
io.KeyMap[ImGuiKey_Tab] = KEY_TAB;
|
|
||||||
io.KeyMap[ImGuiKey_LeftArrow] = KEY_LEFT;
|
|
||||||
io.KeyMap[ImGuiKey_RightArrow] = KEY_RIGHT;
|
|
||||||
io.KeyMap[ImGuiKey_UpArrow] = KEY_UP;
|
|
||||||
io.KeyMap[ImGuiKey_DownArrow] = KEY_DOWN;
|
|
||||||
io.KeyMap[ImGuiKey_PageUp] = KEY_PGUP;
|
|
||||||
io.KeyMap[ImGuiKey_PageDown] = KEY_PGDN;
|
|
||||||
io.KeyMap[ImGuiKey_Home] = KEY_HOME;
|
|
||||||
io.KeyMap[ImGuiKey_End] = KEY_END;
|
|
||||||
io.KeyMap[ImGuiKey_Delete] = KEY_DEL;
|
|
||||||
io.KeyMap[ImGuiKey_Backspace] = KEY_BACKSP;
|
|
||||||
io.KeyMap[ImGuiKey_Enter] = KEY_ENTER;
|
|
||||||
io.KeyMap[ImGuiKey_Escape] = KEY_ESC;
|
|
||||||
io.KeyMap[ImGuiKey_A] = 'A';
|
|
||||||
io.KeyMap[ImGuiKey_C] = 'C';
|
|
||||||
io.KeyMap[ImGuiKey_V] = 'V';
|
|
||||||
io.KeyMap[ImGuiKey_X] = 'X';
|
|
||||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
|
||||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,9 +169,9 @@ ImGui_ImplRW_NewFrame(float timeDelta)
|
|||||||
io.DisplaySize = ImVec2(sk::globals.width, sk::globals.height);
|
io.DisplaySize = ImVec2(sk::globals.width, sk::globals.height);
|
||||||
io.DeltaTime = timeDelta;
|
io.DeltaTime = timeDelta;
|
||||||
|
|
||||||
io.KeyCtrl = io.KeysDown[sk::KEY_LCTRL] || io.KeysDown[sk::KEY_RCTRL];
|
io.KeyCtrl = ImGui::IsKeyPressed(ImGuiKey_LeftCtrl) || ImGui::IsKeyPressed(ImGuiKey_RightCtrl);
|
||||||
io.KeyShift = io.KeysDown[sk::KEY_LSHIFT] || io.KeysDown[sk::KEY_RSHIFT];
|
io.KeyShift = ImGui::IsKeyPressed(ImGuiKey_LeftShift) || ImGui::IsKeyPressed(ImGuiKey_RightShift);
|
||||||
io.KeyAlt = io.KeysDown[sk::KEY_LALT] || io.KeysDown[sk::KEY_RALT];
|
io.KeyAlt = ImGui::IsKeyPressed(ImGuiKey_LeftAlt) || ImGui::IsKeyPressed(ImGuiKey_RightAlt);
|
||||||
io.KeySuper = false;
|
io.KeySuper = false;
|
||||||
|
|
||||||
if(io.WantSetMousePos)
|
if(io.WantSetMousePos)
|
||||||
@@ -200,6 +180,100 @@ ImGui_ImplRW_NewFrame(float timeDelta)
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ImGuiKey SkKeyToImGuiKey(int keycode)
|
||||||
|
{
|
||||||
|
switch (keycode) {
|
||||||
|
case ' ': return ImGuiKey_Space;
|
||||||
|
case '\'': return ImGuiKey_Apostrophe;
|
||||||
|
case '-': return ImGuiKey_Minus;
|
||||||
|
case '.': return ImGuiKey_Period;
|
||||||
|
case '/': return ImGuiKey_Slash;
|
||||||
|
case '0': return ImGuiKey_0;
|
||||||
|
case '1': return ImGuiKey_1;
|
||||||
|
case '2': return ImGuiKey_2;
|
||||||
|
case '3': return ImGuiKey_3;
|
||||||
|
case '4': return ImGuiKey_4;
|
||||||
|
case '5': return ImGuiKey_5;
|
||||||
|
case '6': return ImGuiKey_6;
|
||||||
|
case '7': return ImGuiKey_7;
|
||||||
|
case '8': return ImGuiKey_8;
|
||||||
|
case '9': return ImGuiKey_9;
|
||||||
|
|
||||||
|
case ';': return ImGuiKey_Semicolon;
|
||||||
|
case '=': return ImGuiKey_Equal;
|
||||||
|
|
||||||
|
case 'A': return ImGuiKey_A;
|
||||||
|
case 'B': return ImGuiKey_B;
|
||||||
|
case 'C': return ImGuiKey_C;
|
||||||
|
case 'D': return ImGuiKey_D;
|
||||||
|
case 'E': return ImGuiKey_E;
|
||||||
|
case 'F': return ImGuiKey_F;
|
||||||
|
case 'G': return ImGuiKey_G;
|
||||||
|
case 'H': return ImGuiKey_H;
|
||||||
|
case 'I': return ImGuiKey_I;
|
||||||
|
case 'J': return ImGuiKey_J;
|
||||||
|
case 'K': return ImGuiKey_K;
|
||||||
|
case 'L': return ImGuiKey_L;
|
||||||
|
case 'M': return ImGuiKey_M;
|
||||||
|
case 'N': return ImGuiKey_N;
|
||||||
|
case 'O': return ImGuiKey_O;
|
||||||
|
case 'P': return ImGuiKey_P;
|
||||||
|
case 'Q': return ImGuiKey_Q;
|
||||||
|
case 'R': return ImGuiKey_R;
|
||||||
|
case 'S': return ImGuiKey_S;
|
||||||
|
case 'T': return ImGuiKey_T;
|
||||||
|
case 'U': return ImGuiKey_U;
|
||||||
|
case 'V': return ImGuiKey_V;
|
||||||
|
case 'W': return ImGuiKey_W;
|
||||||
|
case 'X': return ImGuiKey_X;
|
||||||
|
case 'Y': return ImGuiKey_Y;
|
||||||
|
case 'Z': return ImGuiKey_Z;
|
||||||
|
|
||||||
|
case '[': return ImGuiKey_LeftBracket;
|
||||||
|
case '\\': return ImGuiKey_Backslash;
|
||||||
|
case ']': return ImGuiKey_RightBracket;
|
||||||
|
case '`': return ImGuiKey_GraveAccent;
|
||||||
|
case sk::KEY_ESC: return ImGuiKey_Escape;
|
||||||
|
case sk::KEY_ENTER: return ImGuiKey_Enter;
|
||||||
|
case sk::KEY_TAB: return ImGuiKey_Tab;
|
||||||
|
case sk::KEY_BACKSP: return ImGuiKey_Backspace;
|
||||||
|
case sk::KEY_INS: return ImGuiKey_Insert;
|
||||||
|
case sk::KEY_DEL: return ImGuiKey_Delete;
|
||||||
|
case sk::KEY_RIGHT: return ImGuiKey_RightArrow;
|
||||||
|
case sk::KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||||
|
case sk::KEY_DOWN: return ImGuiKey_DownArrow;
|
||||||
|
case sk::KEY_UP: return ImGuiKey_UpArrow;
|
||||||
|
case sk::KEY_PGUP: return ImGuiKey_PageUp;
|
||||||
|
case sk::KEY_PGDN: return ImGuiKey_PageDown;
|
||||||
|
case sk::KEY_HOME: return ImGuiKey_Home;
|
||||||
|
case sk::KEY_END: return ImGuiKey_End;
|
||||||
|
case sk::KEY_CAPSLK: return ImGuiKey_CapsLock;
|
||||||
|
|
||||||
|
case sk::KEY_F1: return ImGuiKey_F1;
|
||||||
|
case sk::KEY_F2: return ImGuiKey_F2;
|
||||||
|
case sk::KEY_F3: return ImGuiKey_F3;
|
||||||
|
case sk::KEY_F4: return ImGuiKey_F4;
|
||||||
|
case sk::KEY_F5: return ImGuiKey_F5;
|
||||||
|
case sk::KEY_F6: return ImGuiKey_F6;
|
||||||
|
case sk::KEY_F7: return ImGuiKey_F7;
|
||||||
|
case sk::KEY_F8: return ImGuiKey_F8;
|
||||||
|
case sk::KEY_F9: return ImGuiKey_F9;
|
||||||
|
case sk::KEY_F10: return ImGuiKey_F10;
|
||||||
|
case sk::KEY_F11: return ImGuiKey_F11;
|
||||||
|
case sk::KEY_F12: return ImGuiKey_F12;
|
||||||
|
|
||||||
|
case sk::KEY_LSHIFT: return ImGuiKey_LeftShift;
|
||||||
|
case sk::KEY_LCTRL: return ImGuiKey_LeftCtrl;
|
||||||
|
case sk::KEY_LALT: return ImGuiKey_LeftAlt;
|
||||||
|
case sk::KEY_RSHIFT: return ImGuiKey_RightShift;
|
||||||
|
case sk::KEY_RCTRL: return ImGuiKey_RightCtrl;
|
||||||
|
case sk::KEY_RALT: return ImGuiKey_RightAlt;
|
||||||
|
|
||||||
|
case sk::KEY_NULL: return ImGuiKey_None;
|
||||||
|
}
|
||||||
|
return ImGuiKey_None;
|
||||||
|
}
|
||||||
|
|
||||||
sk::EventStatus
|
sk::EventStatus
|
||||||
ImGuiEventHandler(sk::Event e, void *param)
|
ImGuiEventHandler(sk::Event e, void *param)
|
||||||
{
|
{
|
||||||
@@ -211,14 +285,10 @@ ImGuiEventHandler(sk::Event e, void *param)
|
|||||||
|
|
||||||
switch(e){
|
switch(e){
|
||||||
case KEYDOWN:
|
case KEYDOWN:
|
||||||
c = *(int*)param;
|
io.AddKeyEvent(SkKeyToImGuiKey(*(int*)param), true);
|
||||||
if(c < 256)
|
|
||||||
io.KeysDown[c] = 1;
|
|
||||||
return EVENTPROCESSED;
|
return EVENTPROCESSED;
|
||||||
case KEYUP:
|
case KEYUP:
|
||||||
c = *(int*)param;
|
io.AddKeyEvent(SkKeyToImGuiKey(*(int*)param), false);
|
||||||
if(c < 256)
|
|
||||||
io.KeysDown[c] = 0;
|
|
||||||
return EVENTPROCESSED;
|
return EVENTPROCESSED;
|
||||||
case CHARINPUT:
|
case CHARINPUT:
|
||||||
c = (uint)(uintptr)param;
|
c = (uint)(uintptr)param;
|
||||||
|
|||||||
+722
-525
File diff suppressed because it is too large
Load Diff
+196
-85
@@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.0
|
// dear imgui, v1.92.2b
|
||||||
// (tables and columns code)
|
// (tables and columns code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -221,6 +221,7 @@ Index of this file:
|
|||||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||||
|
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
|
||||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||||
@@ -229,9 +230,15 @@ Index of this file:
|
|||||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||||
|
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||||
|
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||||
|
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -328,13 +335,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
|
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
|
||||||
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
|
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
|
||||||
const ImVec2 avail_size = GetContentRegionAvail();
|
const ImVec2 avail_size = GetContentRegionAvail();
|
||||||
const ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
|
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f));
|
||||||
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
||||||
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
|
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
|
||||||
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
|
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
|
||||||
{
|
{
|
||||||
ItemSize(outer_rect);
|
ItemSize(outer_rect);
|
||||||
ItemAdd(outer_rect, id);
|
ItemAdd(outer_rect, id);
|
||||||
|
g.NextWindowData.ClearFlags();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,6 +377,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
table->ColumnsCount = columns_count;
|
table->ColumnsCount = columns_count;
|
||||||
table->IsLayoutLocked = false;
|
table->IsLayoutLocked = false;
|
||||||
table->InnerWidth = inner_width;
|
table->InnerWidth = inner_width;
|
||||||
|
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
|
||||||
temp_data->UserOuterSize = outer_size;
|
temp_data->UserOuterSize = outer_size;
|
||||||
|
|
||||||
// Instance data (for instance 0, TableID == TableInstanceID)
|
// Instance data (for instance 0, TableID == TableInstanceID)
|
||||||
@@ -409,11 +418,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
|
|
||||||
// Reset scroll if we are reactivating it
|
// Reset scroll if we are reactivating it
|
||||||
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
|
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
|
||||||
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) == 0)
|
||||||
|
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
// Create scrolling region (without border and zero window padding)
|
// Create scrolling region (without border and zero window padding)
|
||||||
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
|
ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None;
|
||||||
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags);
|
ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None;
|
||||||
|
if (flags & ImGuiTableFlags_ScrollX)
|
||||||
|
child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar;
|
||||||
|
BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags);
|
||||||
table->InnerWindow = g.CurrentWindow;
|
table->InnerWindow = g.CurrentWindow;
|
||||||
table->WorkRect = table->InnerWindow->WorkRect;
|
table->WorkRect = table->InnerWindow->WorkRect;
|
||||||
table->OuterRect = table->InnerWindow->Rect();
|
table->OuterRect = table->InnerWindow->Rect();
|
||||||
@@ -438,6 +451,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
|
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
|
||||||
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
|
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
|
||||||
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
|
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
|
||||||
|
table->InnerWindow->DC.TreeDepth++; // This is designed to always linking ImGuiTreeNodeFlags_DrawLines linking accross a table
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push a standardized ID for both child-using and not-child-using tables
|
// Push a standardized ID for both child-using and not-child-using tables
|
||||||
@@ -460,16 +474,27 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
|
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
|
||||||
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||||
|
|
||||||
// Make left and top borders not overlap our contents by offsetting HostClipRect (#6765)
|
// Make borders not overlap our contents by offsetting HostClipRect (#6765, #7428, #3752)
|
||||||
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
|
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
|
||||||
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
|
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
|
||||||
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
|
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
|
||||||
if (inner_window != outer_window)
|
if (inner_window != outer_window)
|
||||||
{
|
{
|
||||||
|
// FIXME: Because inner_window's Scrollbar doesn't know about border size, since it's not encoded in window->WindowBorderSize,
|
||||||
|
// it already overlaps it and doesn't need an extra offset. Ideally we should be able to pass custom border size with
|
||||||
|
// different x/y values to BeginChild().
|
||||||
if (flags & ImGuiTableFlags_BordersOuterV)
|
if (flags & ImGuiTableFlags_BordersOuterV)
|
||||||
|
{
|
||||||
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
|
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
|
||||||
|
if (inner_window->DecoOuterSizeX2 == 0.0f)
|
||||||
|
table->HostClipRect.Max.x = ImMax(table->HostClipRect.Max.x - TABLE_BORDER_SIZE, table->HostClipRect.Min.x);
|
||||||
|
}
|
||||||
if (flags & ImGuiTableFlags_BordersOuterH)
|
if (flags & ImGuiTableFlags_BordersOuterH)
|
||||||
|
{
|
||||||
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
|
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
|
||||||
|
if (inner_window->DecoOuterSizeY2 == 0.0f)
|
||||||
|
table->HostClipRect.Max.y = ImMax(table->HostClipRect.Max.y - TABLE_BORDER_SIZE, table->HostClipRect.Min.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padding and Spacing
|
// Padding and Spacing
|
||||||
@@ -497,7 +522,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
|
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
|
||||||
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
|
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
|
||||||
table->InnerClipRect.ClipWithFull(table->HostClipRect);
|
table->InnerClipRect.ClipWithFull(table->HostClipRect);
|
||||||
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
|
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : table->HostClipRect.Max.y;
|
||||||
|
|
||||||
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
|
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
|
||||||
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
||||||
@@ -517,7 +542,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
|
|
||||||
// Make table current
|
// Make table current
|
||||||
g.CurrentTable = table;
|
g.CurrentTable = table;
|
||||||
outer_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
inner_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
||||||
outer_window->DC.CurrentTableIdx = table_idx;
|
outer_window->DC.CurrentTableIdx = table_idx;
|
||||||
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
|
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
|
||||||
inner_window->DC.CurrentTableIdx = table_idx;
|
inner_window->DC.CurrentTableIdx = table_idx;
|
||||||
@@ -555,6 +580,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
// Initialize
|
// Initialize
|
||||||
table->SettingsOffset = -1;
|
table->SettingsOffset = -1;
|
||||||
table->IsSortSpecsDirty = true;
|
table->IsSortSpecsDirty = true;
|
||||||
|
table->IsSettingsDirty = true; // Records itself into .ini file even when in default state (#7934)
|
||||||
table->InstanceInteracted = -1;
|
table->InstanceInteracted = -1;
|
||||||
table->ContextPopupColumn = -1;
|
table->ContextPopupColumn = -1;
|
||||||
table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1;
|
table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1;
|
||||||
@@ -855,7 +881,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
|
|
||||||
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
|
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
|
||||||
// Combine width from regular rows + width from headers unless requested not to.
|
// Combine width from regular rows + width from headers unless requested not to.
|
||||||
if (!column->IsPreserveWidthAuto)
|
if (!column->IsPreserveWidthAuto && table->InstanceCurrent == 0)
|
||||||
column->WidthAuto = TableGetColumnWidthAuto(table, column);
|
column->WidthAuto = TableGetColumnWidthAuto(table, column);
|
||||||
|
|
||||||
// Non-resizable columns keep their requested width (apply user value regardless of IsPreserveWidthAuto)
|
// Non-resizable columns keep their requested width (apply user value regardless of IsPreserveWidthAuto)
|
||||||
@@ -954,7 +980,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
// [Part 4] Apply final widths based on requested widths
|
// [Part 4] Apply final widths based on requested widths
|
||||||
const ImRect work_rect = table->WorkRect;
|
const ImRect work_rect = table->WorkRect;
|
||||||
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
||||||
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920)
|
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synced tables with mismatching scrollbar state (#5920)
|
||||||
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
|
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
|
||||||
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
|
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
|
||||||
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
|
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
|
||||||
@@ -1033,7 +1059,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
|
// Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
|
||||||
|
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
|
||||||
|
|
||||||
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
||||||
{
|
{
|
||||||
@@ -1059,16 +1086,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect hovered column
|
|
||||||
if (is_hovering_table && mouse_skewed_x >= column->ClipRect.Min.x && mouse_skewed_x < column->ClipRect.Max.x)
|
|
||||||
table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n;
|
|
||||||
|
|
||||||
// Lock start position
|
// Lock start position
|
||||||
column->MinX = offset_x;
|
column->MinX = offset_x;
|
||||||
|
|
||||||
// Lock width based on start position and minimum/maximum width for this position
|
// Lock width based on start position and minimum/maximum width for this position
|
||||||
float max_width = TableGetMaxColumnWidth(table, column_n);
|
column->WidthMax = TableCalcMaxColumnWidth(table, column_n);
|
||||||
column->WidthGiven = ImMin(column->WidthGiven, max_width);
|
column->WidthGiven = ImMin(column->WidthGiven, column->WidthMax);
|
||||||
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, table->MinColumnWidth));
|
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, table->MinColumnWidth));
|
||||||
column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
|
column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
|
||||||
|
|
||||||
@@ -1117,8 +1140,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
column->Flags |= ImGuiTableColumnFlags_IsVisible;
|
column->Flags |= ImGuiTableColumnFlags_IsVisible;
|
||||||
if (column->SortOrder != -1)
|
if (column->SortOrder != -1)
|
||||||
column->Flags |= ImGuiTableColumnFlags_IsSorted;
|
column->Flags |= ImGuiTableColumnFlags_IsSorted;
|
||||||
if (table->HoveredColumnBody == column_n)
|
|
||||||
|
// Detect hovered column
|
||||||
|
if (is_hovering_table && mouse_skewed_x >= column->ClipRect.Min.x && mouse_skewed_x < column->ClipRect.Max.x)
|
||||||
|
{
|
||||||
column->Flags |= ImGuiTableColumnFlags_IsHovered;
|
column->Flags |= ImGuiTableColumnFlags_IsHovered;
|
||||||
|
table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n;
|
||||||
|
}
|
||||||
|
|
||||||
// Alignment
|
// Alignment
|
||||||
// FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in
|
// FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in
|
||||||
@@ -1148,7 +1176,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't decrement auto-fit counters until container window got a chance to submit its items
|
// Don't decrement auto-fit counters until container window got a chance to submit its items
|
||||||
if (table->HostSkipItems == false)
|
if (table->HostSkipItems == false && table->InstanceCurrent == 0)
|
||||||
{
|
{
|
||||||
column->AutoFitQueue >>= 1;
|
column->AutoFitQueue >>= 1;
|
||||||
column->CannotSkipItemsQueue >>= 1;
|
column->CannotSkipItemsQueue >>= 1;
|
||||||
@@ -1223,7 +1251,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
|
|
||||||
// [Part 11] Default context menu
|
// [Part 11] Default context menu
|
||||||
// - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup().
|
// - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup().
|
||||||
// - To modify or replace this: set table->IsContextPopupNoDefaultContents = true, then call TableBeginContextMenuPopup()/.../EndPopup().
|
// - To modify or replace this: set table->DisableDefaultContextMenu = true, then call TableBeginContextMenuPopup()/.../EndPopup().
|
||||||
// - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu,
|
// - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu,
|
||||||
// e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options.
|
// e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options.
|
||||||
if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table))
|
if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table))
|
||||||
@@ -1249,7 +1277,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||||
table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
|
table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
|
||||||
else
|
else
|
||||||
inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false);
|
inner_window->DrawList->PushClipRect(inner_window->InnerClipRect.Min, inner_window->InnerClipRect.Max, false); // FIXME: use table->InnerClipRect?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
|
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
|
||||||
@@ -1319,7 +1347,11 @@ void ImGui::EndTable()
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!");
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||||
@@ -1361,7 +1393,7 @@ void ImGui::EndTable()
|
|||||||
|
|
||||||
// Setup inner scrolling range
|
// Setup inner scrolling range
|
||||||
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
|
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
|
||||||
// but since the later is likely to be impossible to do we'd rather update both axises together.
|
// but since the later is likely to be impossible to do we'd rather update both axes together.
|
||||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||||
{
|
{
|
||||||
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
|
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
|
||||||
@@ -1471,12 +1503,15 @@ void ImGui::EndTable()
|
|||||||
if (inner_window != outer_window)
|
if (inner_window != outer_window)
|
||||||
{
|
{
|
||||||
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
||||||
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
|
inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
|
||||||
|
g.CurrentTable = NULL; // To avoid error recovery recursing
|
||||||
EndChild();
|
EndChild();
|
||||||
|
g.CurrentTable = table;
|
||||||
inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask;
|
inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
table->InnerWindow->DC.TreeDepth--;
|
||||||
ItemSize(table->OuterRect.GetSize());
|
ItemSize(table->OuterRect.GetSize());
|
||||||
ItemAdd(table->OuterRect, 0);
|
ItemAdd(table->OuterRect, 0);
|
||||||
}
|
}
|
||||||
@@ -1534,14 +1569,43 @@ void ImGui::EndTable()
|
|||||||
NavUpdateCurrentWindowIsScrollPushableX();
|
NavUpdateCurrentWindowIsScrollPushableX();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called in TableSetupColumn() when initializing and in TableLoadSettings() for defaults before applying stored settings.
|
||||||
|
// 'init_mask' specify which fields to initialize.
|
||||||
|
static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags init_mask)
|
||||||
|
{
|
||||||
|
ImGuiTableColumnFlags flags = column->Flags;
|
||||||
|
if (init_mask & ImGuiTableFlags_Resizable)
|
||||||
|
{
|
||||||
|
float init_width_or_weight = column->InitStretchWeightOrWidth;
|
||||||
|
column->WidthRequest = ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
|
||||||
|
column->StretchWeight = (init_width_or_weight > 0.0f && (flags & ImGuiTableColumnFlags_WidthStretch)) ? init_width_or_weight : -1.0f;
|
||||||
|
if (init_width_or_weight > 0.0f) // Disable auto-fit if an explicit width/weight has been specified
|
||||||
|
column->AutoFitQueue = 0x00;
|
||||||
|
}
|
||||||
|
if (init_mask & ImGuiTableFlags_Reorderable)
|
||||||
|
column->DisplayOrder = (ImGuiTableColumnIdx)table->Columns.index_from_ptr(column);
|
||||||
|
if (init_mask & ImGuiTableFlags_Hideable)
|
||||||
|
column->IsUserEnabled = column->IsUserEnabledNextFrame = (flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1;
|
||||||
|
if (init_mask & ImGuiTableFlags_Sortable)
|
||||||
|
{
|
||||||
|
// Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
|
||||||
|
column->SortOrder = (flags & ImGuiTableColumnFlags_DefaultSort) ? 0 : -1;
|
||||||
|
column->SortDirection = (flags & ImGuiTableColumnFlags_DefaultSort) ? ((flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending)) : (ImS8)ImGuiSortDirection_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See "COLUMNS SIZING POLICIES" comments at the top of this file
|
// See "COLUMNS SIZING POLICIES" comments at the top of this file
|
||||||
// If (init_width_or_weight <= 0.0f) it is ignored
|
// If (init_width_or_weight <= 0.0f) it is ignored
|
||||||
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
if (table == NULL)
|
||||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!");
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||||
{
|
{
|
||||||
@@ -1558,7 +1622,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
|||||||
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
|
||||||
|
|
||||||
// When passing a width automatically enforce WidthFixed policy
|
// When passing a width automatically enforce WidthFixed policy
|
||||||
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
|
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable)
|
||||||
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
|
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
|
||||||
if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
|
if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
|
||||||
flags |= ImGuiTableColumnFlags_WidthFixed;
|
flags |= ImGuiTableColumnFlags_WidthFixed;
|
||||||
@@ -1576,27 +1640,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
|||||||
column->InitStretchWeightOrWidth = init_width_or_weight;
|
column->InitStretchWeightOrWidth = init_width_or_weight;
|
||||||
if (table->IsInitializing)
|
if (table->IsInitializing)
|
||||||
{
|
{
|
||||||
// Init width or weight
|
ImGuiTableFlags init_flags = ~table->SettingsLoadedFlags;
|
||||||
if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f)
|
if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f)
|
||||||
{
|
init_flags |= ImGuiTableFlags_Resizable;
|
||||||
if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
|
TableInitColumnDefaults(table, column, init_flags);
|
||||||
column->WidthRequest = init_width_or_weight;
|
|
||||||
if (flags & ImGuiTableColumnFlags_WidthStretch)
|
|
||||||
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
|
|
||||||
|
|
||||||
// Disable auto-fit if an explicit width/weight has been specified
|
|
||||||
if (init_width_or_weight > 0.0f)
|
|
||||||
column->AutoFitQueue = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init default visibility/sort state
|
|
||||||
if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
|
|
||||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = false;
|
|
||||||
if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0)
|
|
||||||
{
|
|
||||||
column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
|
|
||||||
column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store name (append with zero-terminator in contiguous buffer)
|
// Store name (append with zero-terminator in contiguous buffer)
|
||||||
@@ -1605,7 +1652,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
|||||||
if (label != NULL && label[0] != 0)
|
if (label != NULL && label[0] != 0)
|
||||||
{
|
{
|
||||||
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
column->NameOffset = (ImS16)table->ColumnsNames.size();
|
||||||
table->ColumnsNames.append(label, label + strlen(label) + 1);
|
table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1614,7 +1661,11 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||||
@@ -1691,9 +1742,11 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL);
|
if (table == NULL)
|
||||||
if (!table)
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||||
if (column_n < 0)
|
if (column_n < 0)
|
||||||
column_n = table->CurrentColumn;
|
column_n = table->CurrentColumn;
|
||||||
@@ -1772,6 +1825,11 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||||
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (color == IM_COL32_DISABLE)
|
if (color == IM_COL32_DISABLE)
|
||||||
color = 0;
|
color = 0;
|
||||||
@@ -1900,7 +1958,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
IM_ASSERT(table->IsInsideRow);
|
IM_ASSERT(table->IsInsideRow);
|
||||||
|
|
||||||
if (table->CurrentColumn != -1)
|
if (table->CurrentColumn != -1)
|
||||||
|
{
|
||||||
TableEndCell(table);
|
TableEndCell(table);
|
||||||
|
table->CurrentColumn = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
@@ -1998,8 +2059,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
if (unfreeze_rows_request)
|
if (unfreeze_rows_request)
|
||||||
{
|
{
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
|
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
|
||||||
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
||||||
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
||||||
|
|
||||||
if (unfreeze_rows_actual)
|
if (unfreeze_rows_actual)
|
||||||
@@ -2008,8 +2069,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
table->IsUnfrozenRows = true;
|
table->IsUnfrozenRows = true;
|
||||||
|
|
||||||
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
||||||
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, table->InnerClipRect.Max.y);
|
||||||
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = table->InnerClipRect.Max.y;
|
||||||
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
||||||
IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y);
|
IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y);
|
||||||
|
|
||||||
@@ -2065,7 +2126,11 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
|||||||
{
|
{
|
||||||
if (table->CurrentColumn != -1)
|
if (table->CurrentColumn != -1)
|
||||||
TableEndCell(table);
|
TableEndCell(table);
|
||||||
IM_ASSERT(column_n >= 0 && table->ColumnsCount);
|
if ((column_n >= 0 && column_n < table->ColumnsCount) == false)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
TableBeginCell(table, column_n);
|
TableBeginCell(table, column_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2136,6 +2201,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
|
|||||||
g.LastItemData.StatusFlags = 0;
|
g.LastItemData.StatusFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also see TablePushColumnChannel()
|
||||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||||
{
|
{
|
||||||
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
|
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
|
||||||
@@ -2195,8 +2261,8 @@ void ImGui::TableEndCell(ImGuiTable* table)
|
|||||||
// Note that actual columns widths are computed in TableUpdateLayout().
|
// Note that actual columns widths are computed in TableUpdateLayout().
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis.
|
// Maximum column content width given current layout. Use column->MinX so this value differs on a per-column basis.
|
||||||
float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
|
float ImGui::TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n)
|
||||||
{
|
{
|
||||||
const ImGuiTableColumn* column = &table->Columns[column_n];
|
const ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
float max_width = FLT_MAX;
|
float max_width = FLT_MAX;
|
||||||
@@ -2258,7 +2324,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
|
|||||||
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
|
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
|
||||||
IM_ASSERT(table->MinColumnWidth > 0.0f);
|
IM_ASSERT(table->MinColumnWidth > 0.0f);
|
||||||
const float min_width = table->MinColumnWidth;
|
const float min_width = table->MinColumnWidth;
|
||||||
const float max_width = ImMax(min_width, TableGetMaxColumnWidth(table, column_n));
|
const float max_width = ImMax(min_width, column_0->WidthMax); // Don't use TableCalcMaxColumnWidth() here as it would rely on MinX from last instance (#7933)
|
||||||
column_0_width = ImClamp(column_0_width, min_width, max_width);
|
column_0_width = ImClamp(column_0_width, min_width, max_width);
|
||||||
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
|
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
|
||||||
return;
|
return;
|
||||||
@@ -2409,10 +2475,38 @@ void ImGui::TablePopBackgroundChannel()
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
|
||||||
|
|
||||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||||
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
|
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
|
||||||
|
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[table->CurrentColumn].DrawChannelCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also see TableBeginCell()
|
||||||
|
void ImGui::TablePushColumnChannel(int column_n)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiTable* table = g.CurrentTable;
|
||||||
|
|
||||||
|
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||||
|
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||||
|
return;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
const ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||||
|
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TablePopColumnChannel()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiTable* table = g.CurrentTable;
|
||||||
|
|
||||||
|
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||||
|
if ((table->Flags & ImGuiTableFlags_NoClip) || (table->CurrentColumn == -1)) // Calling TreePop() after TableNextRow() is supported.
|
||||||
|
return;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
const ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
||||||
|
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||||
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2743,7 +2837,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
|||||||
const ImU32 outer_col = table->BorderColorStrong;
|
const ImU32 outer_col = table->BorderColorStrong;
|
||||||
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
|
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
|
||||||
{
|
{
|
||||||
inner_drawlist->AddRect(outer_border.Min, outer_border.Max + ImVec2(1, 1), outer_col, 0.0f, 0, border_size);
|
inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size);
|
||||||
}
|
}
|
||||||
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
|
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
|
||||||
{
|
{
|
||||||
@@ -2787,9 +2881,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL);
|
if (table == NULL || !(table->Flags & ImGuiTableFlags_Sortable))
|
||||||
|
|
||||||
if (!(table->Flags & ImGuiTableFlags_Sortable))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
|
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
|
||||||
@@ -3007,15 +3099,21 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth()
|
|||||||
// The intent is that advanced users willing to create customized headers would not need to use this helper
|
// The intent is that advanced users willing to create customized headers would not need to use this helper
|
||||||
// and can create their own! For example: TableHeader() may be preceded by Checkbox() or other custom widgets.
|
// and can create their own! For example: TableHeader() may be preceded by Checkbox() or other custom widgets.
|
||||||
// See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this.
|
// See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this.
|
||||||
// This code is constructed to not make much use of internal functions, as it is intended to be a template to copy.
|
// This code is intentionally written to not make much use of internal functions, to give you better direction
|
||||||
|
// if you need to write your own.
|
||||||
// FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public.
|
// FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public.
|
||||||
void ImGui::TableHeadersRow()
|
void ImGui::TableHeadersRow()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Layout if not already done (this is automatically done by TableNextRow, we do it here solely to facilitate stepping in debugger as it is frequent to step in TableUpdateLayout)
|
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||||
|
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||||
if (!table->IsLayoutLocked)
|
if (!table->IsLayoutLocked)
|
||||||
TableUpdateLayout(table);
|
TableUpdateLayout(table);
|
||||||
|
|
||||||
@@ -3032,8 +3130,7 @@ void ImGui::TableHeadersRow()
|
|||||||
if (!TableSetColumnIndex(column_n))
|
if (!TableSetColumnIndex(column_n))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them)
|
// Push an id to allow empty/unnamed headers. This is also idiomatic as it ensure there is a consistent ID path to access columns (for e.g. automation)
|
||||||
// In your own code you may omit the PushID/PopID all-together, provided you know they won't collide.
|
|
||||||
const char* name = (TableGetColumnFlags(column_n) & ImGuiTableColumnFlags_NoHeaderLabel) ? "" : TableGetColumnName(column_n);
|
const char* name = (TableGetColumnFlags(column_n) & ImGuiTableColumnFlags_NoHeaderLabel) ? "" : TableGetColumnName(column_n);
|
||||||
PushID(column_n);
|
PushID(column_n);
|
||||||
TableHeader(name);
|
TableHeader(name);
|
||||||
@@ -3058,7 +3155,12 @@ void ImGui::TableHeader(const char* label)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!");
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IM_ASSERT(table->CurrentColumn != -1);
|
IM_ASSERT(table->CurrentColumn != -1);
|
||||||
const int column_n = table->CurrentColumn;
|
const int column_n = table->CurrentColumn;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
@@ -3124,7 +3226,7 @@ void ImGui::TableHeader(const char* label)
|
|||||||
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
|
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
|
||||||
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
|
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
|
||||||
}
|
}
|
||||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding);
|
RenderNavCursor(bb, id, ImGuiNavRenderCursorFlags_Compact | ImGuiNavRenderCursorFlags_NoRounding);
|
||||||
if (held)
|
if (held)
|
||||||
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
|
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
|
||||||
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
|
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
|
||||||
@@ -3179,7 +3281,7 @@ void ImGui::TableHeader(const char* label)
|
|||||||
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
|
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
|
||||||
// be merged into a single draw call.
|
// be merged into a single draw call.
|
||||||
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
|
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
|
||||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size);
|
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, bb.Max.y), ellipsis_max, label, label_end, &label_size);
|
||||||
|
|
||||||
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
|
||||||
if (text_clipped && hovered && g.ActiveId == 0)
|
if (text_clipped && hovered && g.ActiveId == 0)
|
||||||
@@ -3233,7 +3335,11 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
|||||||
ImGuiTable* table = g.CurrentTable;
|
ImGuiTable* table = g.CurrentTable;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImDrawList* draw_list = window->DrawList;
|
ImDrawList* draw_list = window->DrawList;
|
||||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
if (table == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||||
|
|
||||||
if (max_label_width == 0.0f)
|
if (max_label_width == 0.0f)
|
||||||
@@ -3272,13 +3378,13 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
|||||||
ButtonBehavior(row_r, row_id, NULL, NULL);
|
ButtonBehavior(row_r, row_id, NULL, NULL);
|
||||||
KeepAliveID(row_id);
|
KeepAliveID(row_id);
|
||||||
|
|
||||||
const float ascent_scaled = g.Font->Ascent * g.FontScale; // FIXME: Standardize those scaling factors better
|
const float ascent_scaled = g.FontBaked->Ascent * g.FontBakedScale; // FIXME: Standardize those scaling factors better
|
||||||
const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f);
|
const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f);
|
||||||
const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
|
const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
|
||||||
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
|
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
|
||||||
|
|
||||||
// Draw background and labels in first pass, then all borders.
|
// Draw background and labels in first pass, then all borders.
|
||||||
float max_x = 0.0f;
|
float max_x = -FLT_MAX;
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
for (int order_n = 0; order_n < data_count; order_n++)
|
for (int order_n = 0; order_n < data_count; order_n++)
|
||||||
{
|
{
|
||||||
@@ -3327,7 +3433,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
|||||||
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
|
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
|
||||||
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
||||||
PushStyleColor(ImGuiCol_Text, request->TextColor);
|
PushStyleColor(ImGuiCol_Text, request->TextColor);
|
||||||
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size);
|
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, label_name, label_name_eol, &label_size);
|
||||||
PopStyleColor();
|
PopStyleColor();
|
||||||
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
||||||
|
|
||||||
@@ -3664,6 +3770,14 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
|||||||
table->SettingsLoadedFlags = settings->SaveFlags;
|
table->SettingsLoadedFlags = settings->SaveFlags;
|
||||||
table->RefScale = settings->RefScale;
|
table->RefScale = settings->RefScale;
|
||||||
|
|
||||||
|
// Initialize default columns settings
|
||||||
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
|
{
|
||||||
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
TableInitColumnDefaults(table, column, ~0);
|
||||||
|
column->AutoFitQueue = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
|
||||||
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
|
||||||
ImU64 display_order_mask = 0;
|
ImU64 display_order_mask = 0;
|
||||||
@@ -3680,14 +3794,12 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
|
|||||||
column->StretchWeight = column_settings->WidthOrWeight;
|
column->StretchWeight = column_settings->WidthOrWeight;
|
||||||
else
|
else
|
||||||
column->WidthRequest = column_settings->WidthOrWeight;
|
column->WidthRequest = column_settings->WidthOrWeight;
|
||||||
column->AutoFitQueue = 0x00;
|
|
||||||
}
|
}
|
||||||
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
|
||||||
column->DisplayOrder = column_settings->DisplayOrder;
|
column->DisplayOrder = column_settings->DisplayOrder;
|
||||||
else
|
|
||||||
column->DisplayOrder = (ImGuiTableColumnIdx)column_n;
|
|
||||||
display_order_mask |= (ImU64)1 << column->DisplayOrder;
|
display_order_mask |= (ImU64)1 << column->DisplayOrder;
|
||||||
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled;
|
if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1)
|
||||||
|
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1;
|
||||||
column->SortOrder = column_settings->SortOrder;
|
column->SortOrder = column_settings->SortOrder;
|
||||||
column->SortDirection = column_settings->SortDirection;
|
column->SortDirection = column_settings->SortDirection;
|
||||||
}
|
}
|
||||||
@@ -3783,8 +3895,7 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
|
|||||||
const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0;
|
const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0;
|
||||||
const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0;
|
const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0;
|
||||||
const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0;
|
const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0;
|
||||||
if (!save_size && !save_visible && !save_order && !save_sort)
|
// We need to save the [Table] entry even if all the bools are false, since this records a table with "default settings".
|
||||||
continue;
|
|
||||||
|
|
||||||
buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve
|
buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve
|
||||||
buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount);
|
buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount);
|
||||||
@@ -4396,7 +4507,7 @@ void ImGui::EndColumns()
|
|||||||
{
|
{
|
||||||
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
|
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
|
||||||
if (hovered || held)
|
if (hovered || held)
|
||||||
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
|
SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||||
if (held && !(column->Flags & ImGuiOldColumnFlags_NoResize))
|
if (held && !(column->Flags & ImGuiOldColumnFlags_NoResize))
|
||||||
dragging_column = n;
|
dragging_column = n;
|
||||||
}
|
}
|
||||||
@@ -4428,12 +4539,12 @@ void ImGui::EndColumns()
|
|||||||
NavUpdateCurrentWindowIsScrollPushableX();
|
NavUpdateCurrentWindowIsScrollPushableX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Columns(int columns_count, const char* id, bool border)
|
void ImGui::Columns(int columns_count, const char* id, bool borders)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
IM_ASSERT(columns_count >= 1);
|
IM_ASSERT(columns_count >= 1);
|
||||||
|
|
||||||
ImGuiOldColumnFlags flags = (border ? 0 : ImGuiOldColumnFlags_NoBorder);
|
ImGuiOldColumnFlags flags = (borders ? 0 : ImGuiOldColumnFlags_NoBorder);
|
||||||
//flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior
|
//flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior
|
||||||
ImGuiOldColumns* columns = window->DC.CurrentColumns;
|
ImGuiOldColumns* columns = window->DC.CurrentColumns;
|
||||||
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
|
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
|
||||||
|
|||||||
+1128
-665
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,8 @@
|
|||||||
// Those changes would need to be pushed into nothings/stb:
|
// Those changes would need to be pushed into nothings/stb:
|
||||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||||
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||||
|
// - Added name to struct or it may be forward declared in our code.
|
||||||
|
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||||
|
|
||||||
@@ -139,6 +141,7 @@
|
|||||||
// with previous char)
|
// with previous char)
|
||||||
// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character
|
// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character
|
||||||
// (return type is int, -1 means not valid to insert)
|
// (return type is int, -1 means not valid to insert)
|
||||||
|
// (not supported if you want to use UTF-8, see below)
|
||||||
// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based
|
// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based
|
||||||
// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize
|
// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize
|
||||||
// as manually wordwrapping for end-of-line positioning
|
// as manually wordwrapping for end-of-line positioning
|
||||||
@@ -176,6 +179,13 @@
|
|||||||
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
|
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
|
||||||
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
|
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
|
||||||
//
|
//
|
||||||
|
// To support UTF-8:
|
||||||
|
//
|
||||||
|
// STB_TEXTEDIT_GETPREVCHARINDEX returns index of previous character
|
||||||
|
// STB_TEXTEDIT_GETNEXTCHARINDEX returns index of next character
|
||||||
|
// Do NOT define STB_TEXTEDIT_KEYTOTEXT.
|
||||||
|
// Instead, call stb_textedit_text() directly for text contents.
|
||||||
|
//
|
||||||
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
||||||
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
||||||
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
|
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
|
||||||
@@ -209,6 +219,7 @@
|
|||||||
// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
||||||
// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
|
// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
|
||||||
|
// void stb_textedit_text(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int text_len)
|
||||||
//
|
//
|
||||||
// Each of these functions potentially updates the string and updates the
|
// Each of these functions potentially updates the string and updates the
|
||||||
// state.
|
// state.
|
||||||
@@ -243,7 +254,14 @@
|
|||||||
// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
|
// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
|
||||||
// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
|
// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
|
||||||
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
||||||
// anything other type you wante before including.
|
// anything other type you want before including.
|
||||||
|
// if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are
|
||||||
|
// transformed into text and stb_textedit_text() is automatically called.
|
||||||
|
//
|
||||||
|
// text: (added 2025)
|
||||||
|
// call this to directly send text input the textfield, which is required
|
||||||
|
// for UTF-8 support, because stb_textedit_key() + STB_TEXTEDIT_KEYTOTEXT()
|
||||||
|
// cannot infer text length.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// When rendering, you can read the cursor position and selection state from
|
// When rendering, you can read the cursor position and selection state from
|
||||||
@@ -318,7 +336,7 @@ typedef struct
|
|||||||
int undo_char_point, redo_char_point;
|
int undo_char_point, redo_char_point;
|
||||||
} StbUndoState;
|
} StbUndoState;
|
||||||
|
|
||||||
typedef struct
|
typedef struct STB_TexteditState
|
||||||
{
|
{
|
||||||
/////////////////////
|
/////////////////////
|
||||||
//
|
//
|
||||||
@@ -392,6 +410,16 @@ typedef struct
|
|||||||
#define IMSTB_TEXTEDIT_memmove memmove
|
#define IMSTB_TEXTEDIT_memmove memmove
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// [DEAR IMGUI]
|
||||||
|
// Functions must be implemented for UTF8 support
|
||||||
|
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
|
||||||
|
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
|
||||||
|
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
|
||||||
|
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(OBJ, IDX) ((IDX) - 1)
|
||||||
|
#endif
|
||||||
|
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
|
||||||
|
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(OBJ, IDX) ((IDX) + 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -438,13 +466,13 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
|||||||
if (x < r.x1) {
|
if (x < r.x1) {
|
||||||
// search characters in row for one that straddles 'x'
|
// search characters in row for one that straddles 'x'
|
||||||
prev_x = r.x0;
|
prev_x = r.x0;
|
||||||
for (k=0; k < r.num_chars; ++k) {
|
for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
|
||||||
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
|
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
|
||||||
if (x < prev_x+w) {
|
if (x < prev_x+w) {
|
||||||
if (x < prev_x+w/2)
|
if (x < prev_x+w/2)
|
||||||
return k+i;
|
return k+i;
|
||||||
else
|
else
|
||||||
return k+i+1;
|
return IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k);
|
||||||
}
|
}
|
||||||
prev_x += w;
|
prev_x += w;
|
||||||
}
|
}
|
||||||
@@ -563,7 +591,7 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
|
|||||||
|
|
||||||
// now scan to find xpos
|
// now scan to find xpos
|
||||||
find->x = r.x0;
|
find->x = r.x0;
|
||||||
for (i=0; first+i < n; ++i)
|
for (i=0; first+i < n; i = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, first + i) - first)
|
||||||
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
|
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,9 +677,9 @@ static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
|||||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||||
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||||
{
|
{
|
||||||
--c; // always move at least one character
|
c = IMSTB_TEXTEDIT_GETPREVCHARINDEX( str, c ); // always move at least one character
|
||||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
while (c >= 0 && !is_word_boundary(str, c))
|
||||||
--c;
|
c = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, c);
|
||||||
|
|
||||||
if( c < 0 )
|
if( c < 0 )
|
||||||
c = 0;
|
c = 0;
|
||||||
@@ -665,9 +693,9 @@ static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c
|
|||||||
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||||
{
|
{
|
||||||
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
++c; // always move at least one character
|
c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c); // always move at least one character
|
||||||
while( c < len && !is_word_boundary( str, c ) )
|
while( c < len && !is_word_boundary( str, c ) )
|
||||||
++c;
|
c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c);
|
||||||
|
|
||||||
if( c > len )
|
if( c > len )
|
||||||
c = len;
|
c = len;
|
||||||
@@ -720,36 +748,45 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
|
|||||||
#define STB_TEXTEDIT_KEYTYPE int
|
#define STB_TEXTEDIT_KEYTYPE int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// API key: process text input
|
||||||
|
// [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility.
|
||||||
|
static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
|
||||||
|
{
|
||||||
|
// can't add newline in single-line mode
|
||||||
|
if (text[0] == '\n' && state->single_line)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
||||||
|
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
||||||
|
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
||||||
|
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
||||||
|
state->cursor += text_len;
|
||||||
|
state->has_preferred_x = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stb_textedit_delete_selection(str, state); // implicitly clamps
|
||||||
|
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
||||||
|
stb_text_makeundo_insert(state, state->cursor, text_len);
|
||||||
|
state->cursor += text_len;
|
||||||
|
state->has_preferred_x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// API key: process a keyboard input
|
// API key: process a keyboard input
|
||||||
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
switch (key) {
|
switch (key) {
|
||||||
default: {
|
default: {
|
||||||
|
#ifdef STB_TEXTEDIT_KEYTOTEXT
|
||||||
|
// This is not suitable for UTF-8 support.
|
||||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c;
|
||||||
|
stb_textedit_text(str, state, &ch, 1);
|
||||||
// can't add newline in single-line mode
|
|
||||||
if (c == '\n' && state->single_line)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
|
||||||
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
|
||||||
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
|
||||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
|
||||||
++state->cursor;
|
|
||||||
state->has_preferred_x = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
|
||||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
|
||||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
|
||||||
++state->cursor;
|
|
||||||
state->has_preferred_x = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,7 +812,7 @@ retry:
|
|||||||
stb_textedit_move_to_first(state);
|
stb_textedit_move_to_first(state);
|
||||||
else
|
else
|
||||||
if (state->cursor > 0)
|
if (state->cursor > 0)
|
||||||
--state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -784,7 +821,7 @@ retry:
|
|||||||
if (STB_TEXT_HAS_SELECTION(state))
|
if (STB_TEXT_HAS_SELECTION(state))
|
||||||
stb_textedit_move_to_last(str, state);
|
stb_textedit_move_to_last(str, state);
|
||||||
else
|
else
|
||||||
++state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
@@ -794,7 +831,7 @@ retry:
|
|||||||
stb_textedit_prep_selection_at_cursor(state);
|
stb_textedit_prep_selection_at_cursor(state);
|
||||||
// move selection left
|
// move selection left
|
||||||
if (state->select_end > 0)
|
if (state->select_end > 0)
|
||||||
--state->select_end;
|
state->select_end = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->select_end);
|
||||||
state->cursor = state->select_end;
|
state->cursor = state->select_end;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
@@ -844,7 +881,7 @@ retry:
|
|||||||
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
|
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
|
||||||
stb_textedit_prep_selection_at_cursor(state);
|
stb_textedit_prep_selection_at_cursor(state);
|
||||||
// move selection right
|
// move selection right
|
||||||
++state->select_end;
|
state->select_end = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->select_end);
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
state->cursor = state->select_end;
|
state->cursor = state->select_end;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@@ -891,8 +928,9 @@ retry:
|
|||||||
state->cursor = start;
|
state->cursor = start;
|
||||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||||
|
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
@@ -900,7 +938,8 @@ retry:
|
|||||||
x += dx;
|
x += dx;
|
||||||
if (x > goal_x)
|
if (x > goal_x)
|
||||||
break;
|
break;
|
||||||
++state->cursor;
|
i += next - state->cursor;
|
||||||
|
state->cursor = next;
|
||||||
}
|
}
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
|
|
||||||
@@ -953,8 +992,9 @@ retry:
|
|||||||
state->cursor = find.prev_first;
|
state->cursor = find.prev_first;
|
||||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||||
|
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
@@ -962,7 +1002,8 @@ retry:
|
|||||||
x += dx;
|
x += dx;
|
||||||
if (x > goal_x)
|
if (x > goal_x)
|
||||||
break;
|
break;
|
||||||
++state->cursor;
|
i += next - state->cursor;
|
||||||
|
state->cursor = next;
|
||||||
}
|
}
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
|
|
||||||
@@ -975,8 +1016,13 @@ retry:
|
|||||||
// go to previous line
|
// go to previous line
|
||||||
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
|
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
|
||||||
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
|
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
|
||||||
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
|
while (prev_scan > 0)
|
||||||
--prev_scan;
|
{
|
||||||
|
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, prev_scan);
|
||||||
|
if (STB_TEXTEDIT_GETCHAR(str, prev) == STB_TEXTEDIT_NEWLINE)
|
||||||
|
break;
|
||||||
|
prev_scan = prev;
|
||||||
|
}
|
||||||
find.first_char = find.prev_first;
|
find.first_char = find.prev_first;
|
||||||
find.prev_first = prev_scan;
|
find.prev_first = prev_scan;
|
||||||
}
|
}
|
||||||
@@ -990,7 +1036,7 @@ retry:
|
|||||||
else {
|
else {
|
||||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
if (state->cursor < n)
|
if (state->cursor < n)
|
||||||
stb_textedit_delete(str, state, state->cursor, 1);
|
stb_textedit_delete(str, state, state->cursor, IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor) - state->cursor);
|
||||||
}
|
}
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
@@ -1002,8 +1048,9 @@ retry:
|
|||||||
else {
|
else {
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
if (state->cursor > 0) {
|
if (state->cursor > 0) {
|
||||||
stb_textedit_delete(str, state, state->cursor-1, 1);
|
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||||
--state->cursor;
|
stb_textedit_delete(str, state, prev, state->cursor - prev);
|
||||||
|
state->cursor = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
@@ -1054,7 +1101,7 @@ retry:
|
|||||||
if (state->single_line)
|
if (state->single_line)
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||||
--state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1066,9 +1113,9 @@ retry:
|
|||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
stb_textedit_move_to_first(state);
|
stb_textedit_move_to_first(state);
|
||||||
if (state->single_line)
|
if (state->single_line)
|
||||||
state->cursor = n;
|
state->cursor = n;
|
||||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||||
++state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1082,7 +1129,7 @@ retry:
|
|||||||
if (state->single_line)
|
if (state->single_line)
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||||
--state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||||
state->select_end = state->cursor;
|
state->select_end = state->cursor;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
@@ -1097,7 +1144,7 @@ retry:
|
|||||||
if (state->single_line)
|
if (state->single_line)
|
||||||
state->cursor = n;
|
state->cursor = n;
|
||||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||||
++state->cursor;
|
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||||
state->select_end = state->cursor;
|
state->select_end = state->cursor;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -4516,8 +4516,8 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
|
|||||||
q2[0] = (float)x2;
|
q2[0] = (float)x2;
|
||||||
q2[1] = (float)y2;
|
q2[1] = (float)y2;
|
||||||
if (equal(q0,q1) || equal(q1,q2)) {
|
if (equal(q0,q1) || equal(q1,q2)) {
|
||||||
x0 = (int)verts[i-1].x;
|
x0 = (int)verts[i-1].x; //-V1048
|
||||||
y0 = (int)verts[i-1].y;
|
y0 = (int)verts[i-1].y; //-V1048
|
||||||
x1 = (int)verts[i ].x;
|
x1 = (int)verts[i ].x;
|
||||||
y1 = (int)verts[i ].y;
|
y1 = (int)verts[i ].y;
|
||||||
if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
|
if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
|
||||||
|
|||||||
@@ -0,0 +1,323 @@
|
|||||||
|
#ifdef LIBRW_SDL3
|
||||||
|
|
||||||
|
#include <rw.h>
|
||||||
|
#include "skeleton.h"
|
||||||
|
|
||||||
|
using namespace sk;
|
||||||
|
using namespace rw;
|
||||||
|
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
|
||||||
|
SDL_Window *window;
|
||||||
|
|
||||||
|
static int keyCodeToSkKey(SDL_Keycode keycode) {
|
||||||
|
switch (keycode) {
|
||||||
|
case SDLK_SPACE: return ' ';
|
||||||
|
case SDLK_APOSTROPHE: return '\'';
|
||||||
|
case SDLK_COMMA: return ',';
|
||||||
|
case SDLK_MINUS: return '-';
|
||||||
|
case SDLK_PERIOD: return '.';
|
||||||
|
case SDLK_SLASH: return '/';
|
||||||
|
|
||||||
|
case SDLK_0: return '0';
|
||||||
|
case SDLK_1: return '1';
|
||||||
|
case SDLK_2: return '2';
|
||||||
|
case SDLK_3: return '3';
|
||||||
|
case SDLK_4: return '4';
|
||||||
|
case SDLK_5: return '5';
|
||||||
|
case SDLK_6: return '6';
|
||||||
|
case SDLK_7: return '7';
|
||||||
|
case SDLK_8: return '8';
|
||||||
|
case SDLK_9: return '9';
|
||||||
|
|
||||||
|
case SDLK_SEMICOLON: return ';';
|
||||||
|
case SDLK_EQUALS: return '=';
|
||||||
|
|
||||||
|
case SDLK_A: return 'A';
|
||||||
|
case SDLK_B: return 'B';
|
||||||
|
case SDLK_C: return 'C';
|
||||||
|
case SDLK_D: return 'D';
|
||||||
|
case SDLK_E: return 'E';
|
||||||
|
case SDLK_F: return 'F';
|
||||||
|
case SDLK_G: return 'G';
|
||||||
|
case SDLK_H: return 'H';
|
||||||
|
case SDLK_I: return 'I';
|
||||||
|
case SDLK_J: return 'J';
|
||||||
|
case SDLK_K: return 'K';
|
||||||
|
case SDLK_L: return 'L';
|
||||||
|
case SDLK_M: return 'M';
|
||||||
|
case SDLK_N: return 'N';
|
||||||
|
case SDLK_O: return 'O';
|
||||||
|
case SDLK_P: return 'P';
|
||||||
|
case SDLK_Q: return 'Q';
|
||||||
|
case SDLK_R: return 'R';
|
||||||
|
case SDLK_S: return 'S';
|
||||||
|
case SDLK_T: return 'T';
|
||||||
|
case SDLK_U: return 'U';
|
||||||
|
case SDLK_V: return 'V';
|
||||||
|
case SDLK_W: return 'W';
|
||||||
|
case SDLK_X: return 'X';
|
||||||
|
case SDLK_Y: return 'Y';
|
||||||
|
case SDLK_Z: return 'Z';
|
||||||
|
|
||||||
|
case SDLK_LEFTBRACKET: return '[';
|
||||||
|
case SDLK_BACKSLASH: return '\\';
|
||||||
|
case SDLK_RIGHTBRACKET: return ']';
|
||||||
|
case SDLK_GRAVE: return '`';
|
||||||
|
case SDLK_ESCAPE: return KEY_ESC;
|
||||||
|
case SDLK_RETURN: return KEY_ENTER;
|
||||||
|
case SDLK_TAB: return KEY_TAB;
|
||||||
|
case SDLK_BACKSPACE: return KEY_BACKSP;
|
||||||
|
case SDLK_INSERT: return KEY_INS;
|
||||||
|
case SDLK_DELETE: return KEY_DEL;
|
||||||
|
case SDLK_RIGHT: return KEY_RIGHT;
|
||||||
|
case SDLK_LEFT: return KEY_LEFT;
|
||||||
|
case SDLK_DOWN: return KEY_DOWN;
|
||||||
|
case SDLK_UP: return KEY_UP;
|
||||||
|
case SDLK_PAGEUP: return KEY_PGUP;
|
||||||
|
case SDLK_PAGEDOWN: return KEY_PGDN;
|
||||||
|
case SDLK_HOME: return KEY_HOME;
|
||||||
|
case SDLK_END: return KEY_END;
|
||||||
|
case SDLK_CAPSLOCK: return KEY_CAPSLK;
|
||||||
|
case SDLK_SCROLLLOCK: return KEY_NULL;
|
||||||
|
case SDLK_NUMLOCKCLEAR: return KEY_NULL;
|
||||||
|
case SDLK_PRINTSCREEN: return KEY_NULL;
|
||||||
|
case SDLK_PAUSE: return KEY_NULL;
|
||||||
|
|
||||||
|
case SDLK_F1: return KEY_F1;
|
||||||
|
case SDLK_F2: return KEY_F2;
|
||||||
|
case SDLK_F3: return KEY_F3;
|
||||||
|
case SDLK_F4: return KEY_F4;
|
||||||
|
case SDLK_F5: return KEY_F5;
|
||||||
|
case SDLK_F6: return KEY_F6;
|
||||||
|
case SDLK_F7: return KEY_F7;
|
||||||
|
case SDLK_F8: return KEY_F8;
|
||||||
|
case SDLK_F9: return KEY_F9;
|
||||||
|
case SDLK_F10: return KEY_F10;
|
||||||
|
case SDLK_F11: return KEY_F11;
|
||||||
|
case SDLK_F12: return KEY_F12;
|
||||||
|
case SDLK_F13: return KEY_NULL;
|
||||||
|
case SDLK_F14: return KEY_NULL;
|
||||||
|
case SDLK_F15: return KEY_NULL;
|
||||||
|
case SDLK_F16: return KEY_NULL;
|
||||||
|
case SDLK_F17: return KEY_NULL;
|
||||||
|
case SDLK_F18: return KEY_NULL;
|
||||||
|
case SDLK_F19: return KEY_NULL;
|
||||||
|
case SDLK_F20: return KEY_NULL;
|
||||||
|
case SDLK_F21: return KEY_NULL;
|
||||||
|
case SDLK_F22: return KEY_NULL;
|
||||||
|
case SDLK_F23: return KEY_NULL;
|
||||||
|
case SDLK_F24: return KEY_NULL;
|
||||||
|
|
||||||
|
case SDLK_KP_0: return KEY_NULL;
|
||||||
|
case SDLK_KP_1: return KEY_NULL;
|
||||||
|
case SDLK_KP_2: return KEY_NULL;
|
||||||
|
case SDLK_KP_3: return KEY_NULL;
|
||||||
|
case SDLK_KP_4: return KEY_NULL;
|
||||||
|
case SDLK_KP_5: return KEY_NULL;
|
||||||
|
case SDLK_KP_6: return KEY_NULL;
|
||||||
|
case SDLK_KP_7: return KEY_NULL;
|
||||||
|
case SDLK_KP_8: return KEY_NULL;
|
||||||
|
case SDLK_KP_9: return KEY_NULL;
|
||||||
|
case SDLK_KP_DECIMAL: return KEY_NULL;
|
||||||
|
case SDLK_KP_DIVIDE: return KEY_NULL;
|
||||||
|
case SDLK_KP_MULTIPLY: return KEY_NULL;
|
||||||
|
case SDLK_KP_MINUS: return KEY_NULL;
|
||||||
|
case SDLK_KP_PLUS: return KEY_NULL;
|
||||||
|
case SDLK_KP_ENTER: return KEY_NULL;
|
||||||
|
case SDLK_KP_EQUALS: return KEY_NULL;
|
||||||
|
|
||||||
|
case SDLK_LSHIFT: return KEY_LSHIFT;
|
||||||
|
case SDLK_LCTRL: return KEY_LCTRL;
|
||||||
|
case SDLK_LALT: return KEY_LALT;
|
||||||
|
case SDLK_LGUI: return KEY_NULL;
|
||||||
|
case SDLK_RSHIFT: return KEY_RSHIFT;
|
||||||
|
case SDLK_RCTRL: return KEY_RCTRL;
|
||||||
|
case SDLK_RALT: return KEY_RALT;
|
||||||
|
case SDLK_RGUI: return KEY_NULL;
|
||||||
|
case SDLK_MENU: return KEY_NULL;
|
||||||
|
}
|
||||||
|
return KEY_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void
|
||||||
|
keypress(SDL_Window *window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if(key >= 0 && key <= GLFW_KEY_LAST){
|
||||||
|
if(action == GLFW_RELEASE) KeyUp(keymap[key]);
|
||||||
|
else if(action == GLFW_PRESS) KeyDown(keymap[key]);
|
||||||
|
else if(action == GLFW_REPEAT) KeyDown(keymap[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
charinput(GLFWwindow *window, unsigned int c)
|
||||||
|
{
|
||||||
|
EventHandler(CHARINPUT, (void*)(uintptr)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resize(GLFWwindow *window, int w, int h)
|
||||||
|
{
|
||||||
|
rw::Rect r;
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.w = w;
|
||||||
|
r.h = h;
|
||||||
|
EventHandler(RESIZE, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mousebtn(GLFWwindow *window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
static int buttons = 0;
|
||||||
|
sk::MouseState ms;
|
||||||
|
|
||||||
|
switch(button){
|
||||||
|
case GLFW_MOUSE_BUTTON_LEFT:
|
||||||
|
if(action == GLFW_PRESS)
|
||||||
|
buttons |= 1;
|
||||||
|
else
|
||||||
|
buttons &= ~1;
|
||||||
|
break;
|
||||||
|
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||||
|
if(action == GLFW_PRESS)
|
||||||
|
buttons |= 2;
|
||||||
|
else
|
||||||
|
buttons &= ~2;
|
||||||
|
break;
|
||||||
|
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||||
|
if(action == GLFW_PRESS)
|
||||||
|
buttons |= 4;
|
||||||
|
else
|
||||||
|
buttons &= ~4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk::MouseState ms;
|
||||||
|
ms.buttons = buttons;
|
||||||
|
EventHandler(MOUSEBTN, &ms);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum mousebutton {
|
||||||
|
BUTTON_LEFT = 0x1,
|
||||||
|
BUTTON_MIDDLE = 0x2,
|
||||||
|
BUTTON_RIGHT = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
args.argc = argc;
|
||||||
|
args.argv = argv;
|
||||||
|
|
||||||
|
if(EventHandler(INITIALIZE, nil) == EVENTERROR)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
engineOpenParams.width = sk::globals.width;
|
||||||
|
engineOpenParams.height = sk::globals.height;
|
||||||
|
engineOpenParams.windowtitle = sk::globals.windowtitle;
|
||||||
|
engineOpenParams.window = &window;
|
||||||
|
|
||||||
|
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Uint64 lastTicks = SDL_GetPerformanceCounter();
|
||||||
|
const float tickPeriod = 1.f / SDL_GetPerformanceFrequency();
|
||||||
|
SDL_Event event;
|
||||||
|
int mouseButtons = 0;
|
||||||
|
|
||||||
|
SDL_StartTextInput(window);
|
||||||
|
|
||||||
|
while(!sk::globals.quit){
|
||||||
|
while(SDL_PollEvent(&event)){
|
||||||
|
switch(event.type){
|
||||||
|
case SDL_EVENT_QUIT:
|
||||||
|
sk::globals.quit = true;
|
||||||
|
break;
|
||||||
|
case SDL_EVENT_WINDOW_RESIZED: {
|
||||||
|
rw::Rect r;
|
||||||
|
SDL_GetWindowPosition(window, &r.x, &r.y);
|
||||||
|
r.w = event.window.data1;
|
||||||
|
r.h = event.window.data2;
|
||||||
|
EventHandler(RESIZE, &r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_KEY_UP: {
|
||||||
|
int c = keyCodeToSkKey(event.key.key);
|
||||||
|
EventHandler(KEYUP, &c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
|
int c = keyCodeToSkKey(event.key.key);
|
||||||
|
EventHandler(KEYDOWN, &c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_TEXT_INPUT: {
|
||||||
|
const char *c = event.text.text;
|
||||||
|
while (int ci = *c) {
|
||||||
|
EventHandler(CHARINPUT, (void*)(uintptr)ci);
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_MOTION: {
|
||||||
|
sk::MouseState ms;
|
||||||
|
ms.posx = event.motion.x;
|
||||||
|
ms.posy = event.motion.y;
|
||||||
|
EventHandler(MOUSEMOVE, &ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
|
||||||
|
switch (event.button.button) {
|
||||||
|
case SDL_BUTTON_LEFT: mouseButtons |= BUTTON_LEFT; break;
|
||||||
|
case SDL_BUTTON_MIDDLE: mouseButtons |= BUTTON_MIDDLE; break;
|
||||||
|
case SDL_BUTTON_RIGHT: mouseButtons |= BUTTON_RIGHT; break;
|
||||||
|
}
|
||||||
|
sk::MouseState ms;
|
||||||
|
ms.buttons = mouseButtons;
|
||||||
|
EventHandler(MOUSEBTN, &ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||||
|
switch (event.button.button) {
|
||||||
|
case SDL_BUTTON_LEFT: mouseButtons &= ~BUTTON_LEFT; break;
|
||||||
|
case SDL_BUTTON_MIDDLE: mouseButtons &= ~BUTTON_MIDDLE; break;
|
||||||
|
case SDL_BUTTON_RIGHT: mouseButtons &= ~BUTTON_RIGHT; break;
|
||||||
|
}
|
||||||
|
sk::MouseState ms;
|
||||||
|
ms.buttons = mouseButtons;
|
||||||
|
EventHandler(MOUSEBTN, &ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint64 currTicks = SDL_GetPerformanceCounter();
|
||||||
|
float timeDelta = (currTicks - lastTicks) * tickPeriod;
|
||||||
|
|
||||||
|
EventHandler(IDLE, &timeDelta);
|
||||||
|
|
||||||
|
lastTicks = currTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_StopTextInput(window);
|
||||||
|
|
||||||
|
EventHandler(RWTERMINATE, nil);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sk {
|
||||||
|
|
||||||
|
void
|
||||||
|
SetMousePosition(int x, int y)
|
||||||
|
{
|
||||||
|
SDL_WarpMouseInWindow(*engineOpenParams.window, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -153,6 +153,7 @@ if(LIBRW_PLATFORM_GL3)
|
|||||||
if (NOT TARGET glfw)
|
if (NOT TARGET glfw)
|
||||||
find_package(glfw3 REQUIRED)
|
find_package(glfw3 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
target_compile_definitions(librw PUBLIC LIBRW_GLFW)
|
||||||
target_link_libraries(librw
|
target_link_libraries(librw
|
||||||
PUBLIC
|
PUBLIC
|
||||||
glfw
|
glfw
|
||||||
@@ -169,6 +170,13 @@ if(LIBRW_PLATFORM_GL3)
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
SDL2::SDL2
|
SDL2::SDL2
|
||||||
)
|
)
|
||||||
|
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL3")
|
||||||
|
find_package(SDL3 CONFIG REQUIRED)
|
||||||
|
target_compile_definitions(librw PUBLIC LIBRW_SDL3)
|
||||||
|
target_link_libraries(librw
|
||||||
|
PUBLIC
|
||||||
|
SDL3::SDL3
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(OpenGL_GL_PREFERENCE GLVND)
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
|
|||||||
+281
-5
@@ -1246,8 +1246,12 @@ getFramebufferRect(Raster *frameBuffer)
|
|||||||
if(fb->type == Raster::CAMERA){
|
if(fb->type == Raster::CAMERA){
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
|
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
glfwGetFramebufferSize(glGlobals.window, &r.w, &r.h);
|
glfwGetFramebufferSize(glGlobals.window, &r.w, &r.h);
|
||||||
|
#else
|
||||||
|
missing implementation
|
||||||
#endif
|
#endif
|
||||||
}else{
|
}else{
|
||||||
r.w = fb->width;
|
r.w = fb->width;
|
||||||
@@ -1412,12 +1416,20 @@ showRaster(Raster *raster, uint32 flags)
|
|||||||
else
|
else
|
||||||
SDL_GL_SetSwapInterval(0);
|
SDL_GL_SetSwapInterval(0);
|
||||||
SDL_GL_SwapWindow(glGlobals.window);
|
SDL_GL_SwapWindow(glGlobals.window);
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
if(flags & Raster::FLIPWAITVSYNCH)
|
||||||
|
SDL_GL_SetSwapInterval(1);
|
||||||
|
else
|
||||||
|
SDL_GL_SetSwapInterval(0);
|
||||||
|
SDL_GL_SwapWindow(glGlobals.window);
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
if(flags & Raster::FLIPWAITVSYNCH)
|
if(flags & Raster::FLIPWAITVSYNCH)
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
else
|
else
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
glfwSwapBuffers(glGlobals.window);
|
glfwSwapBuffers(glGlobals.window);
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1603,7 +1615,174 @@ stopSDL2(void)
|
|||||||
SDL_DestroyWindow(glGlobals.window);
|
SDL_DestroyWindow(glGlobals.window);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
#elif defined(LIBRW_SDL3)
|
||||||
|
|
||||||
|
static void
|
||||||
|
addVideoMode(const SDL_DisplayMode *mode)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 1; i < glGlobals.numModes; i++){
|
||||||
|
if(glGlobals.modes[i].mode.w == mode->w &&
|
||||||
|
glGlobals.modes[i].mode.h == mode->h &&
|
||||||
|
glGlobals.modes[i].mode.format == mode->format){
|
||||||
|
// had this mode already, remember highest refresh rate
|
||||||
|
if(mode->refresh_rate > glGlobals.modes[i].mode.refresh_rate)
|
||||||
|
glGlobals.modes[i].mode.refresh_rate = mode->refresh_rate;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// none found, add
|
||||||
|
glGlobals.modes[glGlobals.numModes].mode = *mode;
|
||||||
|
glGlobals.modes[glGlobals.numModes].flags = VIDEOMODEEXCLUSIVE;
|
||||||
|
glGlobals.numModes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
makeVideoModeList(SDL_DisplayID displayIndex, SDL_DisplayID *displays)
|
||||||
|
{
|
||||||
|
int i, num, depth;
|
||||||
|
const SDL_DisplayMode *currentMode;
|
||||||
|
SDL_DisplayMode **modes;
|
||||||
|
|
||||||
|
currentMode = SDL_GetCurrentDisplayMode(displays[displayIndex]);
|
||||||
|
modes = SDL_GetFullscreenDisplayModes(displayIndex, &num);
|
||||||
|
|
||||||
|
rwFree(glGlobals.modes);
|
||||||
|
glGlobals.modes = rwNewT(DisplayMode, num+(currentMode != NULL ? 1 : 0), ID_DRIVER | MEMDUR_EVENT);
|
||||||
|
|
||||||
|
if (currentMode) {
|
||||||
|
glGlobals.modes[0].mode = *currentMode;
|
||||||
|
glGlobals.modes[0].flags = 0;
|
||||||
|
glGlobals.numModes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num; i++)
|
||||||
|
addVideoMode(modes[i]);
|
||||||
|
|
||||||
|
for(i = 0; i < glGlobals.numModes; i++){
|
||||||
|
depth = SDL_BITSPERPIXEL(glGlobals.modes[i].mode.format);
|
||||||
|
// set depth to power of two
|
||||||
|
for(glGlobals.modes[i].depth = 1; glGlobals.modes[i].depth < depth; glGlobals.modes[i].depth <<= 1);
|
||||||
|
}
|
||||||
|
SDL_free(modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
openSDL3(EngineOpenParams *openparams)
|
||||||
|
{
|
||||||
|
glGlobals.winWidth = openparams->width;
|
||||||
|
glGlobals.winHeight = openparams->height;
|
||||||
|
glGlobals.winTitle = openparams->windowtitle;
|
||||||
|
glGlobals.pWindow = openparams->window;
|
||||||
|
|
||||||
|
memset(&gl3Caps, 0, sizeof(gl3Caps));
|
||||||
|
|
||||||
|
/* Init SDL */
|
||||||
|
if (!SDL_InitSubSystem(SDL_INIT_VIDEO)){
|
||||||
|
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGlobals.currentDisplay = 0;
|
||||||
|
SDL_DisplayID *displays = SDL_GetDisplays(&glGlobals.numDisplays);
|
||||||
|
|
||||||
|
if (glGlobals.currentDisplay >= glGlobals.numDisplays) {
|
||||||
|
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeVideoModeList(glGlobals.currentDisplay, displays);
|
||||||
|
SDL_free(displays);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
closeSDL3(void)
|
||||||
|
{
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int gl;
|
||||||
|
int major, minor;
|
||||||
|
} profiles[] = {
|
||||||
|
{ SDL_GL_CONTEXT_PROFILE_CORE, 3, 3 },
|
||||||
|
{ SDL_GL_CONTEXT_PROFILE_CORE, 2, 1 },
|
||||||
|
{ SDL_GL_CONTEXT_PROFILE_ES, 3, 1 },
|
||||||
|
{ SDL_GL_CONTEXT_PROFILE_ES, 2, 0 },
|
||||||
|
{ 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
startSDL3(void)
|
||||||
|
{
|
||||||
|
SDL_Window *win;
|
||||||
|
SDL_GLContext ctx;
|
||||||
|
DisplayMode *mode;
|
||||||
|
|
||||||
|
mode = &glGlobals.modes[glGlobals.currentMode];
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, glGlobals.numSamples);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 0; profiles[i].gl; i++){
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profiles[i].gl);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, profiles[i].major);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, profiles[i].minor);
|
||||||
|
|
||||||
|
if(mode->flags & VIDEOMODEEXCLUSIVE) {
|
||||||
|
win = SDL_CreateWindow(glGlobals.winTitle, mode->mode.w, mode->mode.h, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
|
||||||
|
if (win)
|
||||||
|
SDL_SetWindowFullscreenMode(win, &mode->mode);
|
||||||
|
} else {
|
||||||
|
win = SDL_CreateWindow(glGlobals.winTitle, glGlobals.winWidth, glGlobals.winHeight, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
|
||||||
|
if (win)
|
||||||
|
SDL_SetWindowFullscreenMode(win, NULL);
|
||||||
|
}
|
||||||
|
if(win){
|
||||||
|
gl3Caps.gles = profiles[i].gl == SDL_GL_CONTEXT_PROFILE_ES;
|
||||||
|
gl3Caps.glversion = profiles[i].major*10 + profiles[i].minor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(win == nil){
|
||||||
|
RWERROR((ERR_GENERAL, SDL_GetError()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ctx = SDL_GL_CreateContext(win);
|
||||||
|
|
||||||
|
if (!((gl3Caps.gles ? gladLoadGLES2Loader : gladLoadGLLoader) ((GLADloadproc) SDL_GL_GetProcAddress, gl3Caps.glversion)) ) {
|
||||||
|
RWERROR((ERR_GENERAL, "gladLoadGLLoader failed"));
|
||||||
|
SDL_GL_DestroyContext(ctx);
|
||||||
|
SDL_DestroyWindow(win);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||||
|
|
||||||
|
glGlobals.window = win;
|
||||||
|
glGlobals.glcontext = ctx;
|
||||||
|
*glGlobals.pWindow = win;
|
||||||
|
glGlobals.presentWidth = 0;
|
||||||
|
glGlobals.presentHeight = 0;
|
||||||
|
glGlobals.presentOffX = 0;
|
||||||
|
glGlobals.presentOffY = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
stopSDL3(void)
|
||||||
|
{
|
||||||
|
SDL_GL_DestroyContext(glGlobals.glcontext);
|
||||||
|
SDL_DestroyWindow(glGlobals.window);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
addVideoMode(const GLFWvidmode *mode)
|
addVideoMode(const GLFWvidmode *mode)
|
||||||
@@ -1767,6 +1946,8 @@ stopGLFW(void)
|
|||||||
glfwDestroyWindow(glGlobals.window);
|
glfwDestroyWindow(glGlobals.window);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2007,7 +2188,94 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
|
||||||
|
static int
|
||||||
|
deviceSystemSDL3(DeviceReq req, void *arg, int32 n)
|
||||||
|
{
|
||||||
|
VideoMode *rwmode;
|
||||||
|
|
||||||
|
switch(req){
|
||||||
|
case DEVICEOPEN:
|
||||||
|
return openSDL3((EngineOpenParams*)arg);
|
||||||
|
case DEVICECLOSE:
|
||||||
|
return closeSDL3();
|
||||||
|
|
||||||
|
case DEVICEINIT:
|
||||||
|
return startSDL3() && initOpenGL();
|
||||||
|
case DEVICETERM:
|
||||||
|
return termOpenGL() && stopSDL3();
|
||||||
|
|
||||||
|
case DEVICEFINALIZE:
|
||||||
|
return finalizeOpenGL();
|
||||||
|
|
||||||
|
|
||||||
|
case DEVICEGETNUMSUBSYSTEMS:
|
||||||
|
return glGlobals.numDisplays;
|
||||||
|
|
||||||
|
case DEVICEGETCURRENTSUBSYSTEM:
|
||||||
|
return glGlobals.currentDisplay;
|
||||||
|
|
||||||
|
case DEVICESETSUBSYSTEM:
|
||||||
|
if (n >= glGlobals.numDisplays)
|
||||||
|
return 0;
|
||||||
|
glGlobals.currentDisplay = n;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case DEVICEGETSUBSSYSTEMINFO: {
|
||||||
|
const char *display_name = SDL_GetDisplayName(n);
|
||||||
|
if (display_name == nil)
|
||||||
|
return 0;
|
||||||
|
strncpy(((SubSystemInfo*)arg)->name, display_name, sizeof(SubSystemInfo::name));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case DEVICEGETNUMVIDEOMODES:
|
||||||
|
return glGlobals.numModes;
|
||||||
|
|
||||||
|
case DEVICEGETCURRENTVIDEOMODE:
|
||||||
|
return glGlobals.currentMode;
|
||||||
|
|
||||||
|
case DEVICESETVIDEOMODE:
|
||||||
|
if(n >= glGlobals.numModes)
|
||||||
|
return 0;
|
||||||
|
glGlobals.currentMode = n;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case DEVICEGETVIDEOMODEINFO:
|
||||||
|
if (n <= 0)
|
||||||
|
return 0;
|
||||||
|
rwmode = (VideoMode*)arg;
|
||||||
|
rwmode->width = glGlobals.modes[n].mode.w;
|
||||||
|
rwmode->height = glGlobals.modes[n].mode.h;
|
||||||
|
rwmode->depth = glGlobals.modes[n].depth;
|
||||||
|
rwmode->flags = glGlobals.modes[n].flags;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case DEVICEGETMAXMULTISAMPLINGLEVELS:
|
||||||
|
{
|
||||||
|
GLint maxSamples;
|
||||||
|
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||||
|
if(maxSamples == 0)
|
||||||
|
return 1;
|
||||||
|
return maxSamples;
|
||||||
|
}
|
||||||
|
case DEVICEGETMULTISAMPLINGLEVELS:
|
||||||
|
if(glGlobals.numSamples == 0)
|
||||||
|
return 1;
|
||||||
|
return glGlobals.numSamples;
|
||||||
|
case DEVICESETMULTISAMPLINGLEVELS:
|
||||||
|
glGlobals.numSamples = (uint32)n;
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
assert(0 && "not implemented");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
||||||
@@ -2094,6 +2362,10 @@ deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
not implemented
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Device renderdevice = {
|
Device renderdevice = {
|
||||||
@@ -2115,8 +2387,12 @@ Device renderdevice = {
|
|||||||
gl3::im3DEnd,
|
gl3::im3DEnd,
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
gl3::deviceSystemSDL2
|
gl3::deviceSystemSDL2
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
gl3::deviceSystemSDL3
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
gl3::deviceSystemGLFW
|
gl3::deviceSystemGLFW
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -2,8 +2,12 @@
|
|||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -15,8 +19,13 @@ struct EngineOpenParams
|
|||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
SDL_Window **window;
|
SDL_Window **window;
|
||||||
bool32 fullscreen;
|
bool32 fullscreen;
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
SDL_Window **window;
|
||||||
|
bool32 fullscreen;
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
GLFWwindow **window;
|
GLFWwindow **window;
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
int width, height;
|
int width, height;
|
||||||
const char *windowtitle;
|
const char *windowtitle;
|
||||||
|
|||||||
+15
-2
@@ -26,8 +26,12 @@ struct DisplayMode
|
|||||||
{
|
{
|
||||||
#ifdef LIBRW_SDL2
|
#ifdef LIBRW_SDL2
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
int32 depth;
|
int32 depth;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
@@ -42,13 +46,22 @@ struct GlGlobals
|
|||||||
|
|
||||||
int numDisplays;
|
int numDisplays;
|
||||||
int currentDisplay;
|
int currentDisplay;
|
||||||
#else
|
#elif defined(LIBRW_SDL3)
|
||||||
|
SDL_Window **pWindow;
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_GLContext glcontext;
|
||||||
|
|
||||||
|
int numDisplays;
|
||||||
|
int currentDisplay;
|
||||||
|
#elif defined(LIBRW_GLFW)
|
||||||
GLFWwindow **pWindow;
|
GLFWwindow **pWindow;
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
|
|
||||||
GLFWmonitor *monitor;
|
GLFWmonitor *monitor;
|
||||||
int numMonitors;
|
int numMonitors;
|
||||||
int currentMonitor;
|
int currentMonitor;
|
||||||
|
#else
|
||||||
|
not implemented
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DisplayMode *modes;
|
DisplayMode *modes;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ target_link_libraries(dumprwtree
|
|||||||
librw::librw
|
librw::librw
|
||||||
)
|
)
|
||||||
|
|
||||||
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
if(LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
|
||||||
target_compile_definitions(dumprwtree PRIVATE SDL_MAIN_HANDLED)
|
target_compile_definitions(dumprwtree PRIVATE SDL_MAIN_HANDLED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ target_link_libraries(ska2anm
|
|||||||
librw::librw
|
librw::librw
|
||||||
)
|
)
|
||||||
|
|
||||||
if(LIBRW_GL3_GFXLIB STREQUAL "SDL2")
|
if(LIBRW_GL3_GFXLIB MATCHES "SDL[23]")
|
||||||
target_compile_definitions(ska2anm PRIVATE SDL_MAIN_HANDLED)
|
target_compile_definitions(ska2anm PRIVATE SDL_MAIN_HANDLED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user