@ -4402,17 +4402,19 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU
}
// Helper for ColorPicker4()
static void RenderArrowsForVerticalBar ( ImDrawList * draw_list , ImVec2 pos , ImVec2 half_sz , float bar_w )
static void RenderArrowsForVerticalBar ( ImDrawList * draw_list , ImVec2 pos , ImVec2 half_sz , float bar_w , float alpha )
{
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + half_sz . x + 1 , pos . y ) , ImVec2 ( half_sz . x + 2 , half_sz . y + 1 ) , ImGuiDir_Right , IM_COL32_BLACK ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + half_sz . x , pos . y ) , half_sz , ImGuiDir_Right , IM_COL32_WHITE ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + bar_w - half_sz . x - 1 , pos . y ) , ImVec2 ( half_sz . x + 2 , half_sz . y + 1 ) , ImGuiDir_Left , IM_COL32_BLACK ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + bar_w - half_sz . x , pos . y ) , half_sz , ImGuiDir_Left , IM_COL32_WHITE ) ;
ImU32 alpha8 = IM_F32_TO_INT8_SAT ( alpha ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + half_sz . x + 1 , pos . y ) , ImVec2 ( half_sz . x + 2 , half_sz . y + 1 ) , ImGuiDir_Right , IM_COL32 ( 0 , 0 , 0 , alpha8 ) ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + half_sz . x , pos . y ) , half_sz , ImGuiDir_Right , IM_COL32 ( 255 , 255 , 255 , alpha8 ) ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + bar_w - half_sz . x - 1 , pos . y ) , ImVec2 ( half_sz . x + 2 , half_sz . y + 1 ) , ImGuiDir_Left , IM_COL32 ( 0 , 0 , 0 , alpha8 ) ) ;
ImGui : : RenderArrowPointingAt ( draw_list , ImVec2 ( pos . x + bar_w - half_sz . x , pos . y ) , half_sz , ImGuiDir_Left , IM_COL32 ( 255 , 255 , 255 , alpha8 ) ) ;
}
// Note: ColorPicker4() only accesses 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
// (In C++ the 'float col[4]' notation for a function argument is equivalent to 'float* col', we only specify a size to facilitate understanding of the code.)
// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..)
// FIXME: this is trying to be aware of style.Alpha but not fully correct. Also, the color wheel will have overlapping glitches with (style.Alpha < 1.0)
bool ImGui : : ColorPicker4 ( const char * label , float col [ 4 ] , ImGuiColorEditFlags flags , const float * ref_col )
{
ImGuiContext & g = * GImGui ;
@ -4662,17 +4664,22 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
}
}
ImVec4 hue_color_f ( 1 , 1 , 1 , 1 ) ; ColorConvertHSVtoRGB ( H , 1 , 1 , hue_color_f . x , hue_color_f . y , hue_color_f . z ) ;
const int style_alpha8 = IM_F32_TO_INT8_SAT ( style . Alpha ) ;
const ImU32 col_black = IM_COL32 ( 0 , 0 , 0 , style_alpha8 ) ;
const ImU32 col_white = IM_COL32 ( 255 , 255 , 255 , style_alpha8 ) ;
const ImU32 col_midgrey = IM_COL32 ( 128 , 128 , 128 , style_alpha8 ) ;
const ImU32 col_hues [ 6 + 1 ] = { IM_COL32 ( 255 , 0 , 0 , style_alpha8 ) , IM_COL32 ( 255 , 255 , 0 , style_alpha8 ) , IM_COL32 ( 0 , 255 , 0 , style_alpha8 ) , IM_COL32 ( 0 , 255 , 255 , style_alpha8 ) , IM_COL32 ( 0 , 0 , 255 , style_alpha8 ) , IM_COL32 ( 255 , 0 , 255 , style_alpha8 ) , IM_COL32 ( 255 , 0 , 0 , style_alpha8 ) } ;
ImVec4 hue_color_f ( 1 , 1 , 1 , style . Alpha ) ; ColorConvertHSVtoRGB ( H , 1 , 1 , hue_color_f . x , hue_color_f . y , hue_color_f . z ) ;
ImU32 hue_color32 = ColorConvertFloat4ToU32 ( hue_color_f ) ;
ImU32 col32_no_alpha = ColorConvertFloat4ToU32 ( ImVec4 ( R , G , B , 1.0f ) ) ;
ImU32 user_col32_striped_of _alpha = ColorConvertFloat4ToU32 ( ImVec4 ( R , G , B , style . Alpha ) ) ; // Important: this is still including the main rendering/style alpha!!
const ImU32 hue_colors [ 6 + 1 ] = { IM_COL32 ( 255 , 0 , 0 , 255 ) , IM_COL32 ( 255 , 255 , 0 , 255 ) , IM_COL32 ( 0 , 255 , 0 , 255 ) , IM_COL32 ( 0 , 255 , 255 , 255 ) , IM_COL32 ( 0 , 0 , 255 , 255 ) , IM_COL32 ( 255 , 0 , 255 , 255 ) , IM_COL32 ( 255 , 0 , 0 , 255 ) } ;
ImVec2 sv_cursor_pos ;
if ( flags & ImGuiColorEditFlags_PickerHueWheel )
{
// Render Hue Wheel
const float aeps = 1 .5f / wheel_r_outer ; // Half a pixel arc length in radians (2pi cancels out).
const float aeps = 0 .5f / wheel_r_outer ; // Half a pixel arc length in radians (2pi cancels out).
const int segment_per_arc = ImMax ( 4 , ( int ) wheel_r_outer / 12 ) ;
for ( int n = 0 ; n < 6 ; n + + )
{
@ -4680,13 +4687,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
const float a1 = ( n + 1.0f ) / 6.0f * 2.0f * IM_PI + aeps ;
const int vert_start_idx = draw_list - > VtxBuffer . Size ;
draw_list - > PathArcTo ( wheel_center , ( wheel_r_inner + wheel_r_outer ) * 0.5f , a0 , a1 , segment_per_arc ) ;
draw_list - > PathStroke ( IM_COL32_WHITE , false , wheel_thickness ) ;
draw_list - > PathStroke ( col_white , false , wheel_thickness ) ;
const int vert_end_idx = draw_list - > VtxBuffer . Size ;
// Paint colors over existing vertices
ImVec2 gradient_p0 ( wheel_center . x + ImCos ( a0 ) * wheel_r_inner , wheel_center . y + ImSin ( a0 ) * wheel_r_inner ) ;
ImVec2 gradient_p1 ( wheel_center . x + ImCos ( a1 ) * wheel_r_inner , wheel_center . y + ImSin ( a1 ) * wheel_r_inner ) ;
ShadeVertsLinearColorGradientKeepAlpha ( draw_list , vert_start_idx , vert_end_idx , gradient_p0 , gradient_p1 , hue_colors[ n ] , hue_color s[ n + 1 ] ) ;
ShadeVertsLinearColorGradientKeepAlpha ( draw_list , vert_start_idx , vert_end_idx , gradient_p0 , gradient_p1 , col_hues[ n ] , col_hue s[ n + 1 ] ) ;
}
// Render Cursor + preview on Hue Wheel
@ -4696,8 +4703,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f ;
int hue_cursor_segments = ImClamp ( ( int ) ( hue_cursor_rad / 1.4f ) , 9 , 32 ) ;
draw_list - > AddCircleFilled ( hue_cursor_pos , hue_cursor_rad , hue_color32 , hue_cursor_segments ) ;
draw_list - > AddCircle ( hue_cursor_pos , hue_cursor_rad + 1 , IM_COL32( 128 , 128 , 128 , 255 ) , hue_cursor_segments ) ;
draw_list - > AddCircle ( hue_cursor_pos , hue_cursor_rad , IM_COL32_WHITE , hue_cursor_segments ) ;
draw_list - > AddCircle ( hue_cursor_pos , hue_cursor_rad + 1 , col_midgrey , hue_cursor_segments ) ;
draw_list - > AddCircle ( hue_cursor_pos , hue_cursor_rad , col_white , hue_cursor_segments ) ;
// Render SV triangle (rotated according to hue)
ImVec2 tra = wheel_center + ImRotate ( triangle_pa , cos_hue_angle , sin_hue_angle ) ;
@ -4707,46 +4714,46 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
draw_list - > PrimReserve ( 6 , 6 ) ;
draw_list - > PrimVtx ( tra , uv_white , hue_color32 ) ;
draw_list - > PrimVtx ( trb , uv_white , hue_color32 ) ;
draw_list - > PrimVtx ( trc , uv_white , IM_COL32_WHITE ) ;
draw_list - > PrimVtx ( tra , uv_white , IM_COL32_BLACK_TRANS ) ;
draw_list - > PrimVtx ( trb , uv_white , IM_COL32_BLACK ) ;
draw_list - > PrimVtx ( trc , uv_white , IM_COL32_BLACK_TRANS ) ;
draw_list - > AddTriangle ( tra , trb , trc , IM_COL32( 128 , 128 , 128 , 255 ) , 1.5f ) ;
draw_list - > PrimVtx ( trc , uv_white , col_white ) ;
draw_list - > PrimVtx ( tra , uv_white , 0 ) ;
draw_list - > PrimVtx ( trb , uv_white , col_white ) ;
draw_list - > PrimVtx ( trc , uv_white , 0 ) ;
draw_list - > AddTriangle ( tra , trb , trc , col_midgrey , 1.5f ) ;
sv_cursor_pos = ImLerp ( ImLerp ( trc , tra , ImSaturate ( S ) ) , trb , ImSaturate ( 1 - V ) ) ;
}
else if ( flags & ImGuiColorEditFlags_PickerHueBar )
{
// Render SV Square
draw_list - > AddRectFilledMultiColor ( picker_pos , picker_pos + ImVec2 ( sv_picker_size , sv_picker_size ) , IM_COL32_WHITE , hue_color32 , hue_color32 , IM_COL32_WHITE ) ;
draw_list - > AddRectFilledMultiColor ( picker_pos , picker_pos + ImVec2 ( sv_picker_size , sv_picker_size ) , IM_COL32_BLACK_TRANS , IM_COL32_BLACK_TRANS , IM_COL32_BLACK , IM_COL32_BLACK ) ;
draw_list - > AddRectFilledMultiColor ( picker_pos , picker_pos + ImVec2 ( sv_picker_size , sv_picker_size ) , col_white , hue_color32 , hue_color32 , col_white ) ;
draw_list - > AddRectFilledMultiColor ( picker_pos , picker_pos + ImVec2 ( sv_picker_size , sv_picker_size ) , 0 , 0 , col_black , col_black ) ;
RenderFrameBorder ( picker_pos , picker_pos + ImVec2 ( sv_picker_size , sv_picker_size ) , 0.0f ) ;
sv_cursor_pos . x = ImClamp ( ( float ) ( int ) ( picker_pos . x + ImSaturate ( S ) * sv_picker_size + 0.5f ) , picker_pos . x + 2 , picker_pos . x + sv_picker_size - 2 ) ; // Sneakily prevent the circle to stick out too much
sv_cursor_pos . y = ImClamp ( ( float ) ( int ) ( picker_pos . y + ImSaturate ( 1 - V ) * sv_picker_size + 0.5f ) , picker_pos . y + 2 , picker_pos . y + sv_picker_size - 2 ) ;
// Render Hue Bar
for ( int i = 0 ; i < 6 ; + + i )
draw_list - > AddRectFilledMultiColor ( ImVec2 ( bar0_pos_x , picker_pos . y + i * ( sv_picker_size / 6 ) ) , ImVec2 ( bar0_pos_x + bars_width , picker_pos . y + ( i + 1 ) * ( sv_picker_size / 6 ) ) , hue_colors[ i ] , hue_colors [ i ] , hue_colors [ i + 1 ] , hue_color s[ i + 1 ] ) ;
draw_list - > AddRectFilledMultiColor ( ImVec2 ( bar0_pos_x , picker_pos . y + i * ( sv_picker_size / 6 ) ) , ImVec2 ( bar0_pos_x + bars_width , picker_pos . y + ( i + 1 ) * ( sv_picker_size / 6 ) ) , col_hues[ i ] , col_hues [ i ] , col_hues [ i + 1 ] , col_hue s[ i + 1 ] ) ;
float bar0_line_y = ( float ) ( int ) ( picker_pos . y + H * sv_picker_size + 0.5f ) ;
RenderFrameBorder ( ImVec2 ( bar0_pos_x , picker_pos . y ) , ImVec2 ( bar0_pos_x + bars_width , picker_pos . y + sv_picker_size ) , 0.0f ) ;
RenderArrowsForVerticalBar ( draw_list , ImVec2 ( bar0_pos_x - 1 , bar0_line_y ) , ImVec2 ( bars_triangles_half_sz + 1 , bars_triangles_half_sz ) , bars_width + 2.0f );
RenderArrowsForVerticalBar ( draw_list , ImVec2 ( bar0_pos_x - 1 , bar0_line_y ) , ImVec2 ( bars_triangles_half_sz + 1 , bars_triangles_half_sz ) , bars_width + 2.0f , style . Alpha );
}
// Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range)
float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f ;
draw_list - > AddCircleFilled ( sv_cursor_pos , sv_cursor_rad , col32_no _alpha, 12 ) ;
draw_list - > AddCircle ( sv_cursor_pos , sv_cursor_rad + 1 , IM_COL32( 128 , 128 , 128 , 255 ) , 12 ) ;
draw_list - > AddCircle ( sv_cursor_pos , sv_cursor_rad , IM_COL32_WHITE , 12 ) ;
draw_list - > AddCircleFilled ( sv_cursor_pos , sv_cursor_rad , user_col32_striped_of _alpha, 12 ) ;
draw_list - > AddCircle ( sv_cursor_pos , sv_cursor_rad + 1 , col_midgrey , 12 ) ;
draw_list - > AddCircle ( sv_cursor_pos , sv_cursor_rad , col_white , 12 ) ;
// Render alpha bar
if ( alpha_bar )
{
float alpha = ImSaturate ( col [ 3 ] ) ;
ImRect bar1_bb ( bar1_pos_x , picker_pos . y , bar1_pos_x + bars_width , picker_pos . y + sv_picker_size ) ;
RenderColorRectWithAlphaCheckerboard ( bar1_bb . Min , bar1_bb . Max , IM_COL32 ( 0 , 0 , 0 , 0 ) , bar1_bb . GetWidth ( ) / 2.0f , ImVec2 ( 0.0f , 0.0f ) ) ;
draw_list - > AddRectFilledMultiColor ( bar1_bb . Min , bar1_bb . Max , col32_no_alpha, col32_no_alpha , col32_no_alpha & ~ IM_COL32_A_MASK , col32_no _alpha & ~ IM_COL32_A_MASK ) ;
RenderColorRectWithAlphaCheckerboard ( bar1_bb . Min , bar1_bb . Max , 0 , bar1_bb . GetWidth ( ) / 2.0f , ImVec2 ( 0.0f , 0.0f ) ) ;
draw_list - > AddRectFilledMultiColor ( bar1_bb . Min , bar1_bb . Max , user_col32_striped_of_alpha, user_col32_striped_of_alpha , user_col32_striped_of_alpha & ~ IM_COL32_A_MASK , user_col32_striped_of _alpha & ~ IM_COL32_A_MASK ) ;
float bar1_line_y = ( float ) ( int ) ( picker_pos . y + ( 1.0f - alpha ) * sv_picker_size + 0.5f ) ;
RenderFrameBorder ( bar1_bb . Min , bar1_bb . Max , 0.0f ) ;
RenderArrowsForVerticalBar ( draw_list , ImVec2 ( bar1_pos_x - 1 , bar1_line_y ) , ImVec2 ( bars_triangles_half_sz + 1 , bars_triangles_half_sz ) , bars_width + 2.0f );
RenderArrowsForVerticalBar ( draw_list , ImVec2 ( bar1_pos_x - 1 , bar1_line_y ) , ImVec2 ( bars_triangles_half_sz + 1 , bars_triangles_half_sz ) , bars_width + 2.0f , style . Alpha );
}
EndGroup ( ) ;