How to create a hovering layer?


#1

Hi,

I’d like to draw a zoomed in portion of an image when I hover over an image in my ImGui window. The following code works, but it alternates between being drawn and not being drawn, causing it to appear as if drawn at 50% opacity:

// Get actual width and height.
const int width = image->getWidth();
const int height = image->getHeight();

// Calculate size at which to draw the image, so that it fits.
const auto size = ImVec2( ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvailWidth() * height / width );

// Draw the image.
ImGui::Image( reinterpret_cast<void *>( intptr_t( image->getId() ) ), size );

// Render zoomed in image at the position of the cursor.
if( ImGui::IsItemHovered() ) {
	const auto cursor = ImGui::GetCurrentContext()->IO.MousePos;
	const auto offset = ImGui::GetItemRectMin();
	const auto center = ImVec2( width, height ) * ( cursor - offset ) / size;
	const auto uv0 = ( center - ImVec2( 32, 32 ) ) / ImVec2( width, height );
	const auto uv1 = ( center + ImVec2( 32, 32 ) ) / ImVec2( width, height );

	ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, ImVec2( 0, 0 ) );
	ImGui::SetNextWindowPos( cursor - ImVec2( 32, 32 ) );
	ImGui::Begin( "Zoom", 0, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar );
	ImGui::Image( reinterpret_cast<void *>( intptr_t( texture->getId() ) ), ImVec2( 64, 64 ), uv0, uv1 );
	ImGui::End();
	ImGui::PopStyleVar();
}

The problem is of course related to the call to ImGui::IsItemHovered(). The window should be ignored by the check to IsItemHovered() (is that possible?) or should I not use a window but something else instead?

-Paul


#2

By default windows are taking the focus.
Use a tooltip window (BeginTooltip()) as shown in the demo.