<commit_before>#include "StdAfx.h"
#include "viewport.h"
#include "registry.h"
#include "illa/config.h"
#include "illa/surfacemgr.h"
#include "getevent.h"

const wchar_t* App::ViewPort::ClassName = TX("Pictus ViewPort");

namespace App {
	using namespace Reg::Keys;
	using Geom::RectInt;
	using Geom::PointInt;
	using Geom::SizeInt;

	ViewPort::ViewPort()
		:m_isCursorVisible(true),
		m_cursorMode(CursorShow),
		m_displayZoom(1.0f),
		m_imageZoom(1.0f),
		m_currentPanMonitor(nullptr),
		m_isPanning(false)
	{
		Img::SurfaceFactory(&m_renderTarget);
		OnMouseMove.connect([&](Win::MouseEvent e) { return HandleMouseMove(e); });
		OnMouseButtonDown.connect([&](Win::MouseEvent e) { return HandleMouseDown(e); });
		OnMouseButtonUp.connect([&](Win::MouseEvent e) { return HandleMouseUp(e); });

		m_hideTimer.OnTick.connect([&]() { CursorHideCallback(); });
		m_animationTimer.OnTick.connect([&]() { ImageRefreshCallback(); });
	}

	bool ViewPort::PerformOnCreate() {
		m_hParent = Parent()->Handle();

		// Register the window class (if possible)
		WNDCLASSEX wc;
		ZeroMemory(&wc, sizeof(wc));
		wc.cbSize			= sizeof(wc);					// Set structure size
		wc.hCursor			= LoadCursor(0, IDC_ARROW);
		wc.hInstance		= GetHINSTANCE();				// Current instance's handle
		wc.lpfnWndProc		= WndProcDelegate;				// Use "delegate" as the wndproc
		wc.lpszClassName	= ClassName;					// Class name
		wc.style			= CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;	// Register double clicks and window resizes
		RegisterClassEx(&wc);

		// Create window without any nifty features
		return ConstructWindow(RectInt(PointInt(0, 0), SizeInt(1, 1)), WS_EX_ACCEPTFILES, ClassName, TX(""), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN);
	}

	void ViewPort::setSurface() {
		m_renderTarget.SetSurface(m_image == 0 ? Img::Surface::Ptr() : m_image->CurrentSurface());
	}

	void ViewPort::Image(Img::Image::Ptr image) {
		m_animationTimer.Destroy();
		bool diff = (m_image != image);
		m_image = image;

		setSurface();

		if (m_image != nullptr) {
			m_pan.ResizeConstraints(image->GetSize());
			m_pan.ResizeViewport(m_renderTarget.TransformedSize());

			if (diff) {
				m_image->RestartAnimation();
			}

			if (diff && Reg::Key(DWResetPan)) {
				m_pan.Reset();
			}

			if (m_image->IsHeaderInformationValid() && m_image->Delay() != -1) {
				m_animationTimer.Create(m_image->Delay());	// It's animated, start timer and stuff
			}
			else if (m_image->IsFinished() == false) {
				m_animationTimer.Create(Img::RedrawDelay);	// Not animated or uncertain. Redraw periodically
			}

		}

		InvalidateRect(Handle(), 0, false);
		OnSize(GetSize());
	}

	Img::Image::Ptr ViewPort::Image() const {
		return m_image;
	}

	void ViewPort::BackgroundColor(const Img::Color& col) {
		m_props.BackgroundColor = col;
	}

	const Img::Color& ViewPort::BackgroundColor() const {
		return m_props.BackgroundColor;
	}

	void ViewPort::Rotate(Filter::RotationAngle r) {
		m_props.Angle = r;

		OnSize(GetSize());
	}

	void ViewPort::ActiveCursorMode(const CursorMode m) {
		m_cursorMode = m;
		updateCursor();
	}

	ViewPort::CursorMode ViewPort::ActiveCursorMode() const {
		return m_cursorMode;
	}

	void ViewPort::Pan(const SizeInt& deltaPan) {
		m_pan.Pan(deltaPan);

		Update();
	}

	void ViewPort::ImageRefreshCallback() {
		if (m_image->IsHeaderInformationValid() == false) return;

		if (m_image->Delay() != -1) {
			m_image->NextFrame();
			m_animationTimer.Create(m_image->Delay());
			Redraw();
		}
		else {
			if (m_image && m_image->IsHeaderInformationValid()) {
				ImageUpdated();
			}

			bool status = m_image->IsFinished();
			Redraw();
			if (status) {
				m_animationTimer.Destroy();
			}
		}
	}

	bool ViewPort::PerformOnPaint() {
		setSurface();

		// TODO: This may call BEFORE the surface is allocated, and will thus fail when attempting to lock.
		if (m_image && m_image->IsHeaderInformationValid() && AreaNonZero(ZoomedImageSize()) && (AreaNonZero(GetSize()))) {
			bool status = m_image->IsFinished();

			m_props.ResampleFilter = ActiveFilterMode();
			m_renderTarget.Render(m_pan.TopLeft(), m_props);

			if ((m_image->Delay() == -1) && status)
				m_animationTimer.Destroy();

			return true;
		}
		else {
			PAINTSTRUCT ps;
			BeginPaint(Handle(), &ps);
			HBRUSH brush = CreateSolidBrush(Img::ABGR_ARGB(ToARGBDWORD(m_props.BackgroundColor)));

			FillRect(ps.hdc, &ps.rcPaint, brush);<commit_msg>Fix WM_PAINT spam.<commit_after>#include "StdAfx.h"
#include "viewport.h"
#include "registry.h"
#include "illa/config.h"
#include "illa/surfacemgr.h"
#include "getevent.h"

const wchar_t* App::ViewPort::ClassName = TX("Pictus ViewPort");

namespace App {
	using namespace Reg::Keys;
	using Geom::RectInt;
	using Geom::PointInt;
	using Geom::SizeInt;

	ViewPort::ViewPort()
		:m_isCursorVisible(true),
		m_cursorMode(CursorShow),
		m_displayZoom(1.0f),
		m_imageZoom(1.0f),
		m_currentPanMonitor(nullptr),
		m_isPanning(false)
	{
		Img::SurfaceFactory(&m_renderTarget);
		OnMouseMove.connect([&](Win::MouseEvent e) { return HandleMouseMove(e); });
		OnMouseButtonDown.connect([&](Win::MouseEvent e) { return HandleMouseDown(e); });
		OnMouseButtonUp.connect([&](Win::MouseEvent e) { return HandleMouseUp(e); });

		m_hideTimer.OnTick.connect([&]() { CursorHideCallback(); });
		m_animationTimer.OnTick.connect([&]() { ImageRefreshCallback(); });
	}

	bool ViewPort::PerformOnCreate() {
		m_hParent = Parent()->Handle();

		// Register the window class (if possible)
		WNDCLASSEX wc;
		ZeroMemory(&wc, sizeof(wc));
		wc.cbSize			= sizeof(wc);					// Set structure size
		wc.hCursor			= LoadCursor(0, IDC_ARROW);
		wc.hInstance		= GetHINSTANCE();				// Current instance's handle
		wc.lpfnWndProc		= WndProcDelegate;				// Use "delegate" as the wndproc
		wc.lpszClassName	= ClassName;					// Class name
		wc.style			= CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;	// Register double clicks and window resizes
		RegisterClassEx(&wc);

		// Create window without any nifty features
		return ConstructWindow(RectInt(PointInt(0, 0), SizeInt(1, 1)), WS_EX_ACCEPTFILES, ClassName, TX(""), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN);
	}

	void ViewPort::setSurface() {
		m_renderTarget.SetSurface(m_image == 0 ? Img::Surface::Ptr() : m_image->CurrentSurface());
	}

	void ViewPort::Image(Img::Image::Ptr image) {
		m_animationTimer.Destroy();
		bool diff = (m_image != image);
		m_image = image;

		setSurface();

		if (m_image != nullptr) {
			m_pan.ResizeConstraints(image->GetSize());
			m_pan.ResizeViewport(m_renderTarget.TransformedSize());

			if (diff) {
				m_image->RestartAnimation();
			}

			if (diff && Reg::Key(DWResetPan)) {
				m_pan.Reset();
			}

			if (m_image->IsHeaderInformationValid() && m_image->Delay() != -1) {
				m_animationTimer.Create(m_image->Delay());	// It's animated, start timer and stuff
			}
			else if (m_image->IsFinished() == false) {
				m_animationTimer.Create(Img::RedrawDelay);	// Not animated or uncertain. Redraw periodically
			}

		}

		InvalidateRect(Handle(), 0, false);
		OnSize(GetSize());
	}

	Img::Image::Ptr ViewPort::Image() const {
		return m_image;
	}

	void ViewPort::BackgroundColor(const Img::Color& col) {
		m_props.BackgroundColor = col;
	}

	const Img::Color& ViewPort::BackgroundColor() const {
		return m_props.BackgroundColor;
	}

	void ViewPort::Rotate(Filter::RotationAngle r) {
		m_props.Angle = r;

		OnSize(GetSize());
	}

	void ViewPort::ActiveCursorMode(const CursorMode m) {
		m_cursorMode = m;
		updateCursor();
	}

	ViewPort::CursorMode ViewPort::ActiveCursorMode() const {
		return m_cursorMode;
	}

	void ViewPort::Pan(const SizeInt& deltaPan) {
		m_pan.Pan(deltaPan);

		Update();
	}

	void ViewPort::ImageRefreshCallback() {
		if (m_image->IsHeaderInformationValid() == false) return;

		if (m_image->Delay() != -1) {
			m_image->NextFrame();
			m_animationTimer.Create(m_image->Delay());
			Redraw();
		}
		else {
			if (m_image && m_image->IsHeaderInformationValid()) {
				ImageUpdated();
			}

			bool status = m_image->IsFinished();
			Redraw();
			if (status) {
				m_animationTimer.Destroy();
			}
		}
	}

	bool ViewPort::PerformOnPaint() {
		setSurface();

		// TODO: This may call BEFORE the surface is allocated, and will thus fail when attempting to lock.
		if (m_image && m_image->IsHeaderInformationValid() && AreaNonZero(ZoomedImageSize()) && (AreaNonZero(GetSize()))) {
			bool status = m_image->IsFinished();

			m_props.ResampleFilter = ActiveFilterMode();
			m_renderTarget.Render(m_pan.TopLeft(), m_props);

			if ((m_image->Delay() == -1) && status)
				m_animationTimer.Destroy();

			// Direct3D9 Ex (with FLIPEX) doesn't seem to validate the window the same way as vanilla D3D9.
			// Therefore we do it ourselves to prevent WM_PAINT spam.
			ValidateRect(Handle(), nullptr);

			return true;
		}
		else {
			PAINTSTRUCT ps;
			BeginPaint(Handle(), &ps);
			HBRUSH brush = CreateSolidBrush(Img::ABGR_ARGB(ToARGBDWORD(m_props.BackgroundColor)));

			FillRect(ps.hdc, &ps.rcPaint, brush);
{'fraction_non_alphanumeric': 0.15171179234728127, 'fraction_numerical': 0.0035802192884314163, 'mean_word_length': 4.528138528138528, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4792989', 'n_tokens_mistral': 3504, 'n_tokens_neox': 3114, 'n_words': 604}