@@ -3953,10 +3953,9 @@ bool PasswordDrawer(char *password, int passwordSize,ImGuiPasswordDrawerFlags fl
39533953unsigned int CheckboxFlags (const char * label,unsigned int * flags,int numFlags,int numRows,int numColumns,unsigned int flagAnnotations,int * itemHoveredOut,const unsigned int * pFlagsValues)
39543954{
39553955 unsigned int itemPressed = 0 ;
3956- if (itemHoveredOut) *itemHoveredOut=0 ;
3956+ if (itemHoveredOut) *itemHoveredOut=- 1 ;
39573957 if (numRows*numColumns*numFlags==0 ) return itemPressed;
39583958
3959-
39603959 ImGuiWindow* window = GetCurrentWindow ();
39613960 if (window->SkipItems ) return itemPressed;
39623961
@@ -3968,7 +3967,6 @@ unsigned int CheckboxFlags(const char* label,unsigned int* flags,int numFlags,in
39683967 int numItemsPerGroup = numItemsPerRow/numColumns;if (numItemsPerRow%numColumns) ++numItemsPerGroup;
39693968 numItemsPerRow = numItemsPerGroup * numColumns;
39703969
3971-
39723970 ImGui::BeginGroup ();
39733971 const ImVec2 startCurPos = window->DC .CursorPos ;
39743972 ImVec2 curPos = startCurPos, maxPos = startCurPos;
@@ -4005,6 +4003,7 @@ unsigned int CheckboxFlags(const char* label,unsigned int* flags,int numFlags,in
40054003 hovered = ItemHoverable (bb, itemID);pressed = buttonPressed && hovered; // Way faster
40064004 if (pressed) {
40074005 v = !v;
4006+ if (!ImGui::GetIO ().KeyShift ) *flags=0 ;
40084007 if (v) *flags |= j;
40094008 else *flags &= ~j;
40104009 itemPressed = j;
@@ -4056,12 +4055,161 @@ unsigned int CheckboxFlags(const char* label,unsigned int* flags,int numFlags,in
40564055 ImGuiID itemID = window->GetID (label);
40574056 ItemSize (text_bb, style.FramePadding .y *numRows);
40584057 if (ItemAdd (text_bb, itemID)) RenderText (text_bb.Min , label);
4059-
4060-
40614058 }
40624059
40634060 return itemPressed;
40644061}
40654062// End CheckboxFlags =================================================================================================
40664063
4064+ // Start CheckBoxStyled ==============================================================================================
4065+ bool CheckboxStyled (const char * label, bool * v)
4066+ {
4067+ ImGuiWindow* window = GetCurrentWindow ();
4068+ if (window->SkipItems )
4069+ return false ;
4070+
4071+ ImGuiContext& g = *GImGui;
4072+ const ImGuiStyle& style = g.Style ;
4073+ const ImGuiID id = window->GetID (label);
4074+ const ImVec2 label_size = CalcTextSize (label, NULL , true );
4075+ const ImVec2 check_size (label_size.y *2 .5f ,label_size.y );
4076+
4077+ const ImRect check_bb (window->DC .CursorPos , window->DC .CursorPos + ImVec2 (check_size.x + style.FramePadding .x *2 , check_size.y + style.FramePadding .y *2 )); // We want a square shape to we use Y twice
4078+ ItemSize (check_bb, style.FramePadding .y );
4079+
4080+ ImRect total_bb = check_bb;
4081+ if (label_size.x > 0 ) SameLine (0 , style.ItemInnerSpacing .x );
4082+ const ImRect text_bb (window->DC .CursorPos + ImVec2 (0 ,style.FramePadding .y ), window->DC .CursorPos + ImVec2 (0 ,style.FramePadding .y ) + label_size);
4083+ if (label_size.x > 0 )
4084+ {
4085+ ItemSize (ImVec2 (text_bb.GetWidth (), check_bb.GetHeight ()), style.FramePadding .y );
4086+ total_bb = ImRect (ImMin (check_bb.Min , text_bb.Min ), ImMax (check_bb.Max , text_bb.Max ));
4087+ }
4088+
4089+ if (!ItemAdd (total_bb, id))
4090+ return false ;
4091+
4092+ bool hovered, held;
4093+ bool pressed = ButtonBehavior (total_bb, id, &hovered, &held);
4094+ static float timeBegin = -1 .f ;
4095+ static ImGuiID timeID = 0 ;
4096+ if (pressed) {
4097+ *v = !(*v);
4098+ timeID = id;
4099+ timeBegin = ImGui::GetTime ();
4100+ }
4101+
4102+ // Widget Look Here ================================================================
4103+ float t = 0 .f ; // In (0,1) 0 = OFF 1 = ON
4104+ if (timeID==id) {
4105+ const float actionTime = 0 .25f ;
4106+ float elapsedTime = ImGui::GetTime ()-timeBegin;
4107+ if (elapsedTime>actionTime) {timeBegin=-1 ;timeID=0 ;}
4108+ else t = 1 .f -elapsedTime/actionTime;
4109+ }
4110+ if (*v) t = 1 .f -t;
4111+ if (t<0 ) t=0 ;
4112+ else if (t>1 ) t=1 ;
4113+ const float check_bb_height = check_bb.GetHeight ();
4114+ const float innerFrameHeight = check_bb_height*0 .5f ;
4115+ const float heightDelta = (check_bb_height-innerFrameHeight)*0 .5f ;
4116+ const float check_bb_width = check_bb.GetWidth ();
4117+ float widthFraction = check_bb_width*t;
4118+ ImU32 baseColor = GetColorU32 ((held || hovered) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
4119+ const float rounding = style.WindowRounding ;// style.FrameRounding;
4120+ ImRect innerFrame0 (ImVec2 (check_bb.Min .x ,check_bb.Min .y +heightDelta),ImVec2 (check_bb.Min .x +widthFraction,check_bb.Max .y -heightDelta));
4121+ ImRect innerFrame1 (ImVec2 (check_bb.Min .x +widthFraction,check_bb.Min .y +heightDelta),ImVec2 (check_bb.Max .x ,check_bb.Max .y -heightDelta));
4122+ if (t>0 ) {
4123+ ImU32 fillColor0 = GetColorU32 ((held || hovered) ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
4124+ window->DrawList ->AddRectFilled (innerFrame0.Min , innerFrame0.Max , fillColor0, rounding, t<1 ? 9 : 15 );
4125+ }
4126+ if (t<1 ) {
4127+ ImU32 fillColor1 = baseColor;// GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
4128+ window->DrawList ->AddRectFilled (innerFrame1.Min , innerFrame1.Max , fillColor1, rounding, t>0 ? 6 : 15 );
4129+ }
4130+ if (window->Flags & ImGuiWindowFlags_ShowBorders) {
4131+ ImRect innerFrame (innerFrame0.Min ,innerFrame1.Max );
4132+ window->DrawList ->AddRect (innerFrame.Min +ImVec2 (1 ,1 ), innerFrame.Max +ImVec2 (1 ,1 ), GetColorU32 (ImGuiCol_BorderShadow), rounding);
4133+ window->DrawList ->AddRect (innerFrame.Min , innerFrame.Max , GetColorU32 (ImGuiCol_Border), rounding);
4134+ }
4135+ // Ideally we need an opaque color here:
4136+ ImU32 circleColor = GetColorU32 ((held || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
4137+ // GetColorU32(ImGuiCol_CheckMark);
4138+ int numSegments = (int )(check_bb_height*0 .8f );if (numSegments<3 ) numSegments=3 ;else if (numSegments>24 ) numSegments = 24 ;
4139+ float radius = check_bb_height*0 .5f ;
4140+ if (widthFraction<radius) widthFraction=radius;
4141+ else if (widthFraction>check_bb_width-radius) widthFraction=check_bb_width-radius;
4142+ ImVec2 center (check_bb.Min .x +widthFraction,check_bb.Min .y +check_bb_height*0 .5f );
4143+ window->DrawList ->AddCircleFilled (center,radius,circleColor,numSegments);
4144+ // ==================================================================================
4145+
4146+ // if (g.LogEnabled) LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]");
4147+ if (label_size.x > 0 .0f ) RenderText (text_bb.Min , label);
4148+
4149+ return pressed;
4150+ }
4151+ bool CheckboxStyledFlags (const char * label, unsigned int * flags, unsigned int flags_value) {
4152+ bool v = ((*flags & flags_value) == flags_value);
4153+ bool pressed = CheckboxStyled (label, &v);
4154+ if (pressed) {
4155+ if (v) *flags |= flags_value;
4156+ else *flags &= ~flags_value;
4157+ }
4158+ return pressed;
4159+ }
4160+ // End CheckBoxStyled ================================================================================================
4161+
4162+ // KnobFloat Starts Here =============================================================================================
4163+ bool KnobFloat (const char * label, float * p_value, float v_min, float v_max,float v_step) {
4164+ // @ocornut https://github.com/ocornut/imgui/issues/942
4165+ ImGuiIO& io = ImGui::GetIO ();
4166+ ImGuiStyle& style = ImGui::GetStyle ();
4167+
4168+ float radius_outer = 20 .0f ;
4169+ ImVec2 pos = ImGui::GetCursorScreenPos ();
4170+ ImVec2 center = ImVec2 (pos.x + radius_outer, pos.y + radius_outer);
4171+ float line_height = ImGui::GetTextLineHeight ();
4172+ ImDrawList* draw_list = ImGui::GetWindowDrawList ();
4173+
4174+ float ANGLE_MIN = 3 .141592f * 0 .75f ;
4175+ float ANGLE_MAX = 3 .141592f * 2 .25f ;
4176+
4177+ ImGui::InvisibleButton (label, ImVec2 (radius_outer*2 , radius_outer*2 + line_height + style.ItemInnerSpacing .y ));
4178+ bool value_changed = false ;
4179+ bool is_active = ImGui::IsItemActive ();
4180+ bool is_hovered = ImGui::IsItemHovered ();
4181+ if (is_active && io.MouseDelta .x != 0 .0f ) {
4182+ if (v_step<=0 ) v_step=50 .f ;
4183+ float step = (v_max - v_min) / v_step;
4184+ *p_value += io.MouseDelta .x * step;
4185+
4186+ if (*p_value < v_min) *p_value = v_min;
4187+ if (*p_value > v_max) *p_value = v_max;
4188+ value_changed = true ;
4189+ }
4190+ else if (is_hovered && (io.MouseDoubleClicked [0 ] || io.MouseClicked [2 ])) {
4191+ *p_value = (v_max + v_min) * 0 .5f ; // reset value
4192+ value_changed = true ;
4193+ }
4194+
4195+ float t = (*p_value - v_min) / (v_max - v_min);
4196+ float angle = ANGLE_MIN + (ANGLE_MAX - ANGLE_MIN) * t;
4197+ float angle_cos = cosf (angle), angle_sin = sinf (angle);
4198+ float radius_inner = radius_outer*0 .40f ;
4199+ draw_list->AddCircleFilled (center, radius_outer, ImGui::GetColorU32 (ImGuiCol_FrameBg), 16 );
4200+ draw_list->AddLine (ImVec2 (center.x + angle_cos*radius_inner, center.y + angle_sin*radius_inner), ImVec2 (center.x + angle_cos*(radius_outer-2 ), center.y + angle_sin*(radius_outer-2 )), ImGui::GetColorU32 (ImGuiCol_SliderGrabActive), 2 .0f );
4201+ draw_list->AddCircleFilled (center, radius_inner, ImGui::GetColorU32 (is_active ? ImGuiCol_FrameBgActive : is_hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16 );
4202+ draw_list->AddText (ImVec2 (pos.x , pos.y + radius_outer * 2 + style.ItemInnerSpacing .y ), ImGui::GetColorU32 (ImGuiCol_Text), label);
4203+
4204+ if (is_active || is_hovered) {
4205+ ImGui::SetNextWindowPos (ImVec2 (pos.x - style.WindowPadding .x , pos.y - line_height - style.ItemInnerSpacing .y - style.WindowPadding .y ));
4206+ ImGui::BeginTooltip ();
4207+ ImGui::Text (" %.3f" , *p_value);
4208+ ImGui::EndTooltip ();
4209+ }
4210+
4211+ return value_changed;
4212+ }
4213+ // ===================================================================================================================
4214+
40674215} // namespace ImGui
0 commit comments