mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Inputs: Mouse: Amend c8e3a01 for tracking multiple clicks, renaming. (#3229)
This commit is contained in:
		| @@ -38,6 +38,7 @@ Breaking Changes: | ||||
|  | ||||
| Other Changes: | ||||
|  | ||||
| - Added IsMouseTripleClicked() function. Tracking multi-click count in IO structure. (#3229) [@kudaba] | ||||
| - Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce | ||||
|   likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling | ||||
|   vkCmdSetScissor() explicitly every frame. (#4644) | ||||
|   | ||||
							
								
								
									
										33
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -3692,29 +3692,26 @@ static void ImGui::UpdateMouseInputs() | ||||
|     for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) | ||||
|     { | ||||
|         g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f; | ||||
|         g.IO.MouseClickedCount[i] = 0; // Will be filled below | ||||
|         g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f; | ||||
|         g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i]; | ||||
|         g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f; | ||||
|         g.IO.MouseMultiClickCount[i] = 0; | ||||
|         if (g.IO.MouseClicked[i]) | ||||
|         { | ||||
|             bool is_repeated_click = false; | ||||
|             if ((float)(g.Time - g.IO.MouseClickedTime[i]) < g.IO.MouseDoubleClickTime) | ||||
|             { | ||||
|                 ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); | ||||
|                 if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) | ||||
|                     g.IO.MouseMultiClickTracker[i]++; | ||||
|                 else | ||||
|                     g.IO.MouseMultiClickTracker[i] = 1; | ||||
|                     is_repeated_click = true; | ||||
|             } | ||||
|             if (is_repeated_click) | ||||
|                 g.IO.MouseClickedLastCount[i]++; | ||||
|             else | ||||
|             { | ||||
|                 g.IO.MouseMultiClickTracker[i] = 1; | ||||
|             } | ||||
|  | ||||
|                 g.IO.MouseClickedLastCount[i] = 1; | ||||
|             g.IO.MouseClickedTime[i] = g.Time; | ||||
|             g.IO.MouseClickedPos[i] = g.IO.MousePos; | ||||
|             g.IO.MouseMultiClickCount[i] = g.IO.MouseMultiClickTracker[i]; | ||||
|             g.IO.MouseDownMultiClickCount[i] = g.IO.MouseMultiClickTracker[i]; | ||||
|             g.IO.MouseClickedCount[i] = g.IO.MouseClickedLastCount[i]; | ||||
|             g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); | ||||
|             g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; | ||||
|         } | ||||
| @@ -3727,9 +3724,11 @@ static void ImGui::UpdateMouseInputs() | ||||
|             g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, delta_from_click_pos.y < 0.0f ? -delta_from_click_pos.y : delta_from_click_pos.y); | ||||
|         } | ||||
|  | ||||
|         if (!g.IO.MouseDown[i] && !g.IO.MouseReleased[i]) | ||||
|             g.IO.MouseDownMultiClickCount[i] = 0; | ||||
|         if (g.IO.MouseClicked[i]) // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation | ||||
|         // We provide io.MouseDoubleClicked[] as a legacy service | ||||
|         g.IO.MouseDoubleClicked[i] = (g.IO.MouseClickedCount[i] == 2); | ||||
|  | ||||
|         // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation | ||||
|         if (g.IO.MouseClicked[i]) | ||||
|             g.NavDisableMouseHover = false; | ||||
|     } | ||||
| } | ||||
| @@ -4770,14 +4769,14 @@ bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); | ||||
|     return g.IO.MouseMultiClickCount[button] == 2; | ||||
|     return g.IO.MouseClickedCount[button] == 2; | ||||
| } | ||||
|  | ||||
| bool ImGui::IsMouseTripleClicked(ImGuiMouseButton button) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); | ||||
|     return g.IO.MouseMultiClickCount[button] == 3; | ||||
|     return g.IO.MouseClickedCount[button] == 3; | ||||
| } | ||||
|  | ||||
| // Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame. | ||||
| @@ -5457,7 +5456,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s | ||||
|         if (hovered || held) | ||||
|             g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; | ||||
|  | ||||
|         if (held && g.IO.MouseMultiClickCount[0] == 2 && resize_grip_n == 0) | ||||
|         if (held && g.IO.MouseClickedCount[0] == 2 && resize_grip_n == 0) | ||||
|         { | ||||
|             // Manual auto-fit when double-clicking | ||||
|             size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit); | ||||
| @@ -5992,7 +5991,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|         { | ||||
|             // We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar. | ||||
|             ImRect title_bar_rect = window->TitleBarRect(); | ||||
|             if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseMultiClickCount[0] == 2) | ||||
|             if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseClickedCount[0] == 2) | ||||
|                 window->WantCollapseToggle = true; | ||||
|             if (window->WantCollapseToggle) | ||||
|             { | ||||
|   | ||||
							
								
								
									
										8
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1931,13 +1931,13 @@ struct ImGuiIO | ||||
|     ImVec2      MousePosPrev;                   // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) | ||||
|     ImVec2      MouseClickedPos[5];             // Position at time of clicking | ||||
|     double      MouseClickedTime[5];            // Time of last click (used to figure out double-click) | ||||
|     bool        MouseClicked[5];                // Mouse button went from !Down to Down | ||||
|     char        MouseMultiClickTracker[5];      // Track multiple clicks over multiple frames | ||||
|     char        MouseMultiClickCount[5];        // Has mouse button been clicked multiple times in a row? | ||||
|     bool        MouseClicked[5];                // Mouse button went from !Down to Down (same as MouseClickedCount[x] != 0) | ||||
|     bool        MouseDoubleClicked[5];          // Has mouse button been double-clicked? (same as MouseClickedCount[x] == 2) | ||||
|     ImU16       MouseClickedCount[5];           // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down | ||||
|     ImU16       MouseClickedLastCount[5];       // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done. | ||||
|     bool        MouseReleased[5];               // Mouse button went from Down to !Down | ||||
|     bool        MouseDownOwned[5];              // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. | ||||
|     bool        MouseDownOwnedUnlessPopupClose[5];//Track if button was clicked inside a dear imgui window. | ||||
|     char        MouseDownMultiClickCount[5];    // Track number of mouse down clicks in a row | ||||
|     float       MouseDownDuration[5];           // Duration the mouse button has been down (0.0f == just clicked) | ||||
|     float       MouseDownDurationPrev[5];       // Previous time the mouse button has been down | ||||
|     ImVec2      MouseDragMaxDistanceAbs[5];     // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point | ||||
|   | ||||
| @@ -5518,12 +5518,16 @@ static void ShowDemoWindowMisc() | ||||
|             else | ||||
|                 ImGui::Text("Mouse pos: <INVALID>"); | ||||
|             ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y); | ||||
|             ImGui::Text("Mouse down:");         for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i))         { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } | ||||
|             ImGui::Text("Mouse clicked:");      for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i))      { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text("Mouse dblclick:");     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)){ ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text("Mouse tripleclick:");  for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseTripleClicked(i)){ ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text("Mouse clickcount:");   for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseMultiClickTracker[i])  { ImGui::SameLine(); ImGui::Text("b%d (%d)", i, io.MouseMultiClickTracker[i]); } | ||||
|             ImGui::Text("Mouse released:");     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i))     { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|  | ||||
|             int count = IM_ARRAYSIZE(io.MouseDown); | ||||
|             ImGui::Text("Mouse down:");         for (int i = 0; i < count; i++) if (ImGui::IsMouseDown(i))          { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } | ||||
|             ImGui::Text("Mouse clicked:");      for (int i = 0; i < count; i++) if (ImGui::IsMouseClicked(i))       { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text(" - clicked double:");  for (int i = 0; i < count; i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text(" - clicked triple:");  for (int i = 0; i < count; i++) if (ImGui::IsMouseTripleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text(" - clicked count:");   for (int i = 0; i < count; i++) if (io.MouseClickedCount[i])        { ImGui::SameLine(); ImGui::Text("b%d (%d)", i, io.MouseClickedCount[i]); } | ||||
|             //ImGui::Text(" - last count:");    for (int i = 0; i < count; i++) if (io.MouseClickedLastCount[i])    { ImGui::SameLine(); ImGui::Text("b%d (%d)", i, io.MouseClickedLastCount[i]); } | ||||
|  | ||||
|             ImGui::Text("Mouse released:");     for (int i = 0; i < count; i++) if (ImGui::IsMouseReleased(i))      { ImGui::SameLine(); ImGui::Text("b%d", i); } | ||||
|             ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); | ||||
|             ImGui::Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused | ||||
|             ImGui::TreePop(); | ||||
|   | ||||
| @@ -564,7 +564,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool | ||||
|                         SetFocusID(id, window); | ||||
|                     FocusWindow(window); | ||||
|                 } | ||||
|                 if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseMultiClickCount[mouse_button_clicked] == 2)) | ||||
|                 if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseClickedCount[mouse_button_clicked] == 2)) | ||||
|                 { | ||||
|                     pressed = true; | ||||
|                     if (flags & ImGuiButtonFlags_NoHoldingActiveId) | ||||
| @@ -641,7 +641,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool | ||||
|                 if ((release_in || release_anywhere) && !g.DragDropActive) | ||||
|                 { | ||||
|                     // Report as pressed when releasing the mouse (this is the most common path) | ||||
|                     bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownMultiClickCount[mouse_button] == 2; | ||||
|                     bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2; | ||||
|                     bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release> | ||||
|                     if (!is_double_click_release && !is_repeating_already) | ||||
|                         pressed = true; | ||||
| @@ -2409,7 +2409,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, | ||||
|     { | ||||
|         const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; | ||||
|         const bool clicked = (hovered && g.IO.MouseClicked[0]); | ||||
|         const bool double_clicked = (hovered && g.IO.MouseMultiClickCount[0] == 2); | ||||
|         const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2); | ||||
|         if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id) | ||||
|         { | ||||
|             SetActiveID(id, window); | ||||
| @@ -4176,12 +4176,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ | ||||
|         const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f)); | ||||
|  | ||||
|         const bool is_osx = io.ConfigMacOSXBehaviors; | ||||
|         if (select_all || (hovered && !is_osx && io.MouseMultiClickCount[0] == 2)) | ||||
|         if (select_all || (hovered && !is_osx && io.MouseClickedCount[0] == 2)) | ||||
|         { | ||||
|             state->SelectAll(); | ||||
|             state->SelectedAllMouseLock = true; | ||||
|         } | ||||
|         else if (hovered && is_osx && io.MouseMultiClickCount[0] == 2) | ||||
|         else if (hovered && is_osx && io.MouseClickedCount[0] == 2) | ||||
|         { | ||||
|             // Double-click select a word only, OS X style (by simulating keystrokes) | ||||
|             state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); | ||||
| @@ -5919,7 +5919,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l | ||||
|                 toggled = true; | ||||
|             if (flags & ImGuiTreeNodeFlags_OpenOnArrow) | ||||
|                 toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job | ||||
|             if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseMultiClickCount[0] == 2) | ||||
|             if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseClickedCount[0] == 2) | ||||
|                 toggled = true; | ||||
|         } | ||||
|         else if (pressed && g.DragDropHoldJustPressedId == id) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user