@ -1,6 +1,23 @@
// dear imgui, v1.64 WIP
// dear imgui, v1.64 WIP
// (widgets code)
// (widgets code)
// Index of this file:
// - Widgets: Text, etc.
// - Widgets: Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc.
// - Widgets: ComboBox
// - Data Type and Data Formatting Helpers
// - Widgets: DragScalar, DragFloat, DragInt, etc.
// - Widgets: SliderScalar, SliderFloat, SliderInt, etc.
// - Widgets: InputScalar, InputFloat, InputInt, etc.
// - Widgets: InputText, InputTextMultiline
// - Widgets: ColorEdit, ColorPicker, ColorButton, etc.
// - Widgets: TreeNode, TreePush, TreePop, etc.
// - Widgets: Selectable
// - Widgets: ListBox
// - Widgets: PlotLines, PlotHistogram
// - Widgets: Value
// - Widgets: MenuItem, BeginMenu, EndMenu, etc.
# if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
# if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
# define _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS
# endif
# endif
@ -347,6 +364,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
// - ArrowButton()
// - ArrowButton()
// - CloseButton() [Internal]
// - CloseButton() [Internal]
// - CollapseButton() [Internal]
// - CollapseButton() [Internal]
// - Scrollbar() [Internal]
// - Image()
// - Image()
// - ImageButton()
// - ImageButton()
// - Checkbox()
// - Checkbox()
@ -673,6 +691,116 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
return pressed ;
return pressed ;
}
}
// Vertical/Horizontal scrollbar
// The entire piece of code below is rather confusing because:
// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
void ImGui : : Scrollbar ( ImGuiLayoutType direction )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
const bool horizontal = ( direction = = ImGuiLayoutType_Horizontal ) ;
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( horizontal ? " #SCROLLX " : " #SCROLLY " ) ;
// Render background
bool other_scrollbar = ( horizontal ? window - > ScrollbarY : window - > ScrollbarX ) ;
float other_scrollbar_size_w = other_scrollbar ? style . ScrollbarSize : 0.0f ;
const ImRect window_rect = window - > Rect ( ) ;
const float border_size = window - > WindowBorderSize ;
ImRect bb = horizontal
? ImRect ( window - > Pos . x + border_size , window_rect . Max . y - style . ScrollbarSize , window_rect . Max . x - other_scrollbar_size_w - border_size , window_rect . Max . y - border_size )
: ImRect ( window_rect . Max . x - style . ScrollbarSize , window - > Pos . y + border_size , window_rect . Max . x - border_size , window_rect . Max . y - other_scrollbar_size_w - border_size ) ;
if ( ! horizontal )
bb . Min . y + = window - > TitleBarHeight ( ) + ( ( window - > Flags & ImGuiWindowFlags_MenuBar ) ? window - > MenuBarHeight ( ) : 0.0f ) ;
if ( bb . GetWidth ( ) < = 0.0f | | bb . GetHeight ( ) < = 0.0f )
return ;
int window_rounding_corners ;
if ( horizontal )
window_rounding_corners = ImDrawCornerFlags_BotLeft | ( other_scrollbar ? 0 : ImDrawCornerFlags_BotRight ) ;
else
window_rounding_corners = ( ( ( window - > Flags & ImGuiWindowFlags_NoTitleBar ) & & ! ( window - > Flags & ImGuiWindowFlags_MenuBar ) ) ? ImDrawCornerFlags_TopRight : 0 ) | ( other_scrollbar ? 0 : ImDrawCornerFlags_BotRight ) ;
window - > DrawList - > AddRectFilled ( bb . Min , bb . Max , GetColorU32 ( ImGuiCol_ScrollbarBg ) , window - > WindowRounding , window_rounding_corners ) ;
bb . Expand ( ImVec2 ( - ImClamp ( ( float ) ( int ) ( ( bb . Max . x - bb . Min . x - 2.0f ) * 0.5f ) , 0.0f , 3.0f ) , - ImClamp ( ( float ) ( int ) ( ( bb . Max . y - bb . Min . y - 2.0f ) * 0.5f ) , 0.0f , 3.0f ) ) ) ;
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
float scrollbar_size_v = horizontal ? bb . GetWidth ( ) : bb . GetHeight ( ) ;
float scroll_v = horizontal ? window - > Scroll . x : window - > Scroll . y ;
float win_size_avail_v = ( horizontal ? window - > SizeFull . x : window - > SizeFull . y ) - other_scrollbar_size_w ;
float win_size_contents_v = horizontal ? window - > SizeContents . x : window - > SizeContents . y ;
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
IM_ASSERT ( ImMax ( win_size_contents_v , win_size_avail_v ) > 0.0f ) ; // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
const float win_size_v = ImMax ( ImMax ( win_size_contents_v , win_size_avail_v ) , 1.0f ) ;
const float grab_h_pixels = ImClamp ( scrollbar_size_v * ( win_size_avail_v / win_size_v ) , style . GrabMinSize , scrollbar_size_v ) ;
const float grab_h_norm = grab_h_pixels / scrollbar_size_v ;
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
bool held = false ;
bool hovered = false ;
const bool previously_held = ( g . ActiveId = = id ) ;
ButtonBehavior ( bb , id , & hovered , & held , ImGuiButtonFlags_NoNavFocus ) ;
float scroll_max = ImMax ( 1.0f , win_size_contents_v - win_size_avail_v ) ;
float scroll_ratio = ImSaturate ( scroll_v / scroll_max ) ;
float grab_v_norm = scroll_ratio * ( scrollbar_size_v - grab_h_pixels ) / scrollbar_size_v ;
if ( held & & grab_h_norm < 1.0f )
{
float scrollbar_pos_v = horizontal ? bb . Min . x : bb . Min . y ;
float mouse_pos_v = horizontal ? g . IO . MousePos . x : g . IO . MousePos . y ;
float * click_delta_to_grab_center_v = horizontal ? & g . ScrollbarClickDeltaToGrabCenter . x : & g . ScrollbarClickDeltaToGrabCenter . y ;
// Click position in scrollbar normalized space (0.0f->1.0f)
const float clicked_v_norm = ImSaturate ( ( mouse_pos_v - scrollbar_pos_v ) / scrollbar_size_v ) ;
SetHoveredID ( id ) ;
bool seek_absolute = false ;
if ( ! previously_held )
{
// On initial click calculate the distance between mouse and the center of the grab
if ( clicked_v_norm > = grab_v_norm & & clicked_v_norm < = grab_v_norm + grab_h_norm )
{
* click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f ;
}
else
{
seek_absolute = true ;
* click_delta_to_grab_center_v = 0.0f ;
}
}
// Apply scroll
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position
const float scroll_v_norm = ImSaturate ( ( clicked_v_norm - * click_delta_to_grab_center_v - grab_h_norm * 0.5f ) / ( 1.0f - grab_h_norm ) ) ;
scroll_v = ( float ) ( int ) ( 0.5f + scroll_v_norm * scroll_max ) ; //(win_size_contents_v - win_size_v));
if ( horizontal )
window - > Scroll . x = scroll_v ;
else
window - > Scroll . y = scroll_v ;
// Update values for rendering
scroll_ratio = ImSaturate ( scroll_v / scroll_max ) ;
grab_v_norm = scroll_ratio * ( scrollbar_size_v - grab_h_pixels ) / scrollbar_size_v ;
// Update distance to grab now that we have seeked and saturated
if ( seek_absolute )
* click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f ;
}
// Render
const ImU32 grab_col = GetColorU32 ( held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab ) ;
ImRect grab_rect ;
if ( horizontal )
grab_rect = ImRect ( ImLerp ( bb . Min . x , bb . Max . x , grab_v_norm ) , bb . Min . y , ImMin ( ImLerp ( bb . Min . x , bb . Max . x , grab_v_norm ) + grab_h_pixels , window_rect . Max . x ) , bb . Max . y ) ;
else
grab_rect = ImRect ( bb . Min . x , ImLerp ( bb . Min . y , bb . Max . y , grab_v_norm ) , bb . Max . x , ImMin ( ImLerp ( bb . Min . y , bb . Max . y , grab_v_norm ) + grab_h_pixels , window_rect . Max . y ) ) ;
window - > DrawList - > AddRectFilled ( grab_rect . Min , grab_rect . Max , grab_col , style . ScrollbarRounding ) ;
}
void ImGui : : Image ( ImTextureID user_texture_id , const ImVec2 & size , const ImVec2 & uv0 , const ImVec2 & uv1 , const ImVec4 & tint_col , const ImVec4 & border_col )
void ImGui : : Image ( ImTextureID user_texture_id , const ImVec2 & size , const ImVec2 & uv0 , const ImVec2 & uv1 , const ImVec4 & tint_col , const ImVec4 & border_col )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;