<commit_before>#include <StdAfx.h>
#include <UI/Controls/PaneHeader/PaneHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/strings.h>
#include <UI/DoubleBuffer.h>
#include <core/utility/output.h>
#include <core/utility/registry.h>

namespace controls
{
	static std::wstring CLASS = L"PaneHeader";

	PaneHeader::~PaneHeader()
	{
		TRACE_DESTRUCTOR(CLASS);
		CWnd::DestroyWindow();
	}

	void PaneHeader::Initialize(HWND hWnd, _In_opt_ HDC hdc, _In_ UINT nid)
	{
		m_hWndParent = hWnd;

		// Assign a nID to the collapse button that is IDD_COLLAPSE more than the control's nID
		m_nID = nid;
		m_nIDCollapse = nid + IDD_COLLAPSE;

		WNDCLASSEX wc = {};
		const auto hInst = AfxGetInstanceHandle();
		if (!::GetClassInfoEx(hInst, _T("PaneHeader"), &wc)) // STRING_OK
		{
			wc.cbSize = sizeof wc;
			wc.style = 0; // not passing CS_VREDRAW | CS_HREDRAW fixes flicker
			wc.lpszClassName = _T("PaneHeader"); // STRING_OK
			wc.lpfnWndProc = ::DefWindowProc;
			wc.hbrBackground = GetSysBrush(ui::uiColor::Background); // helps spot flashing

			RegisterClassEx(&wc);
		}

		// WS_CLIPCHILDREN is used to reduce flicker
		EC_B_S(CreateEx(
			0,
			_T("PaneHeader"), // STRING_OK
			_T("PaneHeader"), // STRING_OK
			WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
			0,
			0,
			0,
			0,
			m_hWndParent,
			reinterpret_cast<HMENU>(static_cast<INT_PTR>(IDC_PANE_HEADER)),
			nullptr));

		// Necessary for TAB to work. Without this, all TABS get stuck on the control
		// instead of passing to the children.
		EC_B_S(ModifyStyleEx(0, WS_EX_CONTROLPARENT));

		const auto sizeText = ui::GetTextExtentPoint32(hdc, m_szLabel);
		m_iLabelWidth = sizeText.cx;
		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::Initialize m_iLabelWidth:%d \"%ws\"\n",
			m_iLabelWidth,
			m_szLabel.c_str());
	}

	BEGIN_MESSAGE_MAP(PaneHeader, CWnd)
	ON_WM_CREATE()
	END_MESSAGE_MAP()

	int PaneHeader::OnCreate(LPCREATESTRUCT /*lpCreateStruct*/)
	{
		EC_B_S(m_leftLabel.Create(
			nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CRect(0, 0, 0, 0), this, m_nID));
		::SetWindowTextW(m_leftLabel.m_hWnd, m_szLabel.c_str());
		ui::SubclassLabel(m_leftLabel.m_hWnd);
		if (m_bCollapsible)
		{
			StyleLabel(m_leftLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderLabel);
		}

		EC_B_S(m_rightLabel.Create(
			nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CRect(0, 0, 0, 0), this, IDD_RIGHTLABEL));
		ui::SubclassLabel(m_rightLabel.m_hWnd);
		StyleLabel(m_rightLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderText);

		if (m_bCollapsible)
		{
			EC_B_S(m_CollapseButton.Create(
				nullptr,
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_NOTIFY,
				CRect(0, 0, 0, 0),
				this,
				m_nIDCollapse));
			StyleButton(
				m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		}

		// If we need an action button, go ahead and create it
		if (m_nIDAction)
		{
			EC_B_S(m_actionButton.Create(
				strings::wstringTotstring(m_szActionButton).c_str(),
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_NOTIFY,
				CRect(0, 0, 0, 0),
				this,
				m_nIDAction));
			StyleButton(m_actionButton.m_hWnd, ui::uiButtonStyle::Unstyled);
		}

		m_bInitialized = true;
		return 0;
	}

	LRESULT PaneHeader::WindowProc(const UINT message, const WPARAM wParam, const LPARAM lParam)
	{
		LRESULT lRes = 0;
		if (ui::HandleControlUI(message, wParam, lParam, &lRes)) return lRes;

		switch (message)
		{
		case WM_PAINT:
			auto ps = PAINTSTRUCT{};
			::BeginPaint(m_hWnd, &ps);
			if (ps.hdc)
			{
				auto rcWin = RECT{};
				::GetClientRect(m_hWnd, &rcWin);
				const auto background = registry::uiDiag ? ui::GetSysBrush(ui::uiColor::TestGreen)
														 : ui::GetSysBrush(ui::uiColor::Background);
				FillRect(ps.hdc, &rcWin, background);
			}

			::EndPaint(m_hWnd, &ps);
			return 0;
		case WM_WINDOWPOSCHANGED:
			RecalcLayout();
			return 0;
		case WM_CLOSE:
			::SendMessage(m_hWndParent, message, wParam, lParam);
			return true;
		case WM_HELP:
			return true;
		case WM_COMMAND:
		{
			const auto nCode = HIWORD(wParam);
			switch (nCode)
			{
			// Pass button clicks up to parent
			case BN_CLICKED:
				// Pass focus notifications up to parent
			case BN_SETFOCUS:
			case EN_SETFOCUS:
				return ::SendMessage(m_hWndParent, message, wParam, lParam);
			}

			break;
		}
		}

		return CWnd::WindowProc(message, wParam, lParam);
	}

	int PaneHeader::GetFixedHeight() const noexcept
	{
		int iHeight = 0;
		if (m_bCollapsible || !m_szLabel.empty()) iHeight = max(m_iButtonHeight, m_iLabelHeight);
		if (!m_bCollapsed && iHeight) iHeight += m_iSmallHeightMargin;

		return iHeight;
	}

	// Position collapse button, labels, action button.
	void PaneHeader::RecalcLayout()
	{
		if (!m_bInitialized) return;
		auto hWinPosInfo = WC_D(HDWP, BeginDeferWindowPos(4));
		if (hWinPosInfo)
		{
			auto rcWin = RECT{};
			::GetClientRect(m_hWnd, &rcWin);
			const auto width = rcWin.right - rcWin.left;
			const auto height = rcWin.bottom - rcWin.top;
			output::DebugPrint(
				output::dbgLevel::Draw,
				L"PaneHeader::DeferWindowPos width:%d height:%d v:%d l:\"%ws\"\n",
				width,
				height,
				IsWindowVisible(),
				m_szLabel.c_str());
			auto curX = 0;
			const auto actionButtonWidth =
				!m_bCollapsed && m_actionButtonWidth ? m_actionButtonWidth + 2 * m_iMargin : 0;
			const auto actionButtonAndGutterWidth = actionButtonWidth ? actionButtonWidth + m_iSideMargin : 0;
			if (m_bCollapsible)
			{
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_CollapseButton.GetSafeHwnd(),
					curX,
					0,
					width - actionButtonAndGutterWidth,
					m_iButtonHeight,
					L"PaneHeader::DeferWindowPos::collapseButton");
				curX += m_iButtonHeight;
			}

			hWinPosInfo = ui::DeferWindowPos(
				hWinPosInfo,
				m_leftLabel.GetSafeHwnd(),
				curX,
				1,
				m_iLabelWidth,
				m_iLabelHeight,
				L"PaneHeader::DeferWindowPos::leftLabel");

			auto cmdShow = SW_HIDE;
			if (!m_bCollapsed && m_rightLabelWidth)
			{
				// Drop the count on top of the label we drew above
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_rightLabel.GetSafeHwnd(),
					width - m_rightLabelWidth - actionButtonAndGutterWidth - m_iSideMargin - 1,
					1,
					m_rightLabelWidth,
					m_iLabelHeight,
					L"PaneHeader::DeferWindowPos::rightLabel");
				cmdShow = SW_SHOW;
			}

			WC_B_S(::ShowWindow(m_rightLabel.GetSafeHwnd(), cmdShow));

			if (!m_bCollapsed && m_nIDAction && m_actionButtonWidth)
			{
				// Drop the action button next to the label we drew above
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_actionButton.GetSafeHwnd(),
					width - actionButtonWidth,
					0,
					actionButtonWidth,
					m_iButtonHeight,
					L"PaneHeader::DeferWindowPos::actionButton");
				cmdShow = SW_SHOW;
			}
			else
			{
				cmdShow = SW_HIDE;
			}

			WC_B_S(::ShowWindow(m_actionButton.GetSafeHwnd(), cmdShow));

			output::DebugPrint(output::dbgLevel::Draw, L"PaneHeader::DeferWindowPos end\n");
			EC_B_S(EndDeferWindowPos(hWinPosInfo));
		}
	}

	int PaneHeader::GetMinWidth()
	{
		auto cx = m_iLabelWidth;
		if (m_bCollapsible) cx += m_iButtonHeight;
		if (m_rightLabelWidth)
		{
			cx += m_iSideMargin * 2;
			cx += m_rightLabelWidth;
		}

		if (m_actionButtonWidth)
		{
			cx += m_iSideMargin;
			cx += m_actionButtonWidth + 2 * m_iMargin;
		}

		return cx;
	}

	void PaneHeader::SetRightLabel(const std::wstring szLabel)
	{
		if (!m_bInitialized) return;
		EC_B_S(::SetWindowTextW(m_rightLabel.m_hWnd, szLabel.c_str()));

		const auto hdc = ::GetDC(m_rightLabel.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szLabel);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_rightLabel.GetSafeHwnd(), hdc);
		m_rightLabelWidth = sizeText.cx;

		RecalcLayout();
	}

	void PaneHeader::SetActionButton(const std::wstring szActionButton)
	{
		// Don't bother if we never enabled the button
		if (m_nIDAction == 0) return;

		EC_B_S(::SetWindowTextW(m_actionButton.GetSafeHwnd(), szActionButton.c_str()));

		m_szActionButton = szActionButton;
		const auto hdc = ::GetDC(m_actionButton.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szActionButton);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_actionButton.GetSafeHwnd(), hdc);
		m_actionButtonWidth = sizeText.cx;

		RecalcLayout();
	}

	bool PaneHeader::HandleChange(UINT nID)
	{
		// Collapse buttons have a nID IDD_COLLAPSE higher than nID of the pane they toggle.
		// So if we get asked about one that matches, we can assume it's time to toggle our collapse.
		if (m_nIDCollapse == nID)
		{
			OnToggleCollapse();
			return true;
		}

		return false;
	}

	void PaneHeader::OnToggleCollapse()
	{
		if (!m_bCollapsible) return;
		m_bCollapsed = !m_bCollapsed;

		StyleButton(m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);

		// Trigger a redraw
		::PostMessage(m_hWndParent, WM_COMMAND, IDD_RECALCLAYOUT, NULL);
	}

	void PaneHeader::SetMargins(
		int iMargin,
		int iSideMargin,
		int iLabelHeight, // Height of the label
		int iSmallHeightMargin,
		int iButtonHeight) // Height of button
	{
		m_iMargin = iMargin;
		m_iSideMargin = iSideMargin;
		m_iLabelHeight = iLabelHeight;
		m_iSmallHeightMargin = iSmallHeightMargin;
		m_iButtonHeight = iButtonHeight;
	}

	bool PaneHeader::containsWindow(HWND hWnd) const noexcept
	{
		if (GetSafeHwnd() == hWnd) return true;
		if (m_leftLabel.GetSafeHwnd() == hWnd) return true;
		if (m_rightLabel.GetSafeHwnd() == hWnd) return true;
		if (m_actionButton.GetSafeHwnd() == hWnd) return true;
		if (m_CollapseButton.GetSafeHwnd() == hWnd) return true;
		return false;
	}
} // namespace controls<commit_msg>ensure pane header arrows always draw the right direction<commit_after>#include <StdAfx.h>
#include <UI/Controls/PaneHeader/PaneHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/strings.h>
#include <UI/DoubleBuffer.h>
#include <core/utility/output.h>
#include <core/utility/registry.h>

namespace controls
{
	static std::wstring CLASS = L"PaneHeader";

	PaneHeader::~PaneHeader()
	{
		TRACE_DESTRUCTOR(CLASS);
		CWnd::DestroyWindow();
	}

	void PaneHeader::Initialize(HWND hWnd, _In_opt_ HDC hdc, _In_ UINT nid)
	{
		m_hWndParent = hWnd;

		// Assign a nID to the collapse button that is IDD_COLLAPSE more than the control's nID
		m_nID = nid;
		m_nIDCollapse = nid + IDD_COLLAPSE;

		WNDCLASSEX wc = {};
		const auto hInst = AfxGetInstanceHandle();
		if (!::GetClassInfoEx(hInst, _T("PaneHeader"), &wc)) // STRING_OK
		{
			wc.cbSize = sizeof wc;
			wc.style = 0; // not passing CS_VREDRAW | CS_HREDRAW fixes flicker
			wc.lpszClassName = _T("PaneHeader"); // STRING_OK
			wc.lpfnWndProc = ::DefWindowProc;
			wc.hbrBackground = GetSysBrush(ui::uiColor::Background); // helps spot flashing

			RegisterClassEx(&wc);
		}

		// WS_CLIPCHILDREN is used to reduce flicker
		EC_B_S(CreateEx(
			0,
			_T("PaneHeader"), // STRING_OK
			_T("PaneHeader"), // STRING_OK
			WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
			0,
			0,
			0,
			0,
			m_hWndParent,
			reinterpret_cast<HMENU>(static_cast<INT_PTR>(IDC_PANE_HEADER)),
			nullptr));

		// Necessary for TAB to work. Without this, all TABS get stuck on the control
		// instead of passing to the children.
		EC_B_S(ModifyStyleEx(0, WS_EX_CONTROLPARENT));

		const auto sizeText = ui::GetTextExtentPoint32(hdc, m_szLabel);
		m_iLabelWidth = sizeText.cx;
		output::DebugPrint(
			output::dbgLevel::Draw,
			L"PaneHeader::Initialize m_iLabelWidth:%d \"%ws\"\n",
			m_iLabelWidth,
			m_szLabel.c_str());
	}

	BEGIN_MESSAGE_MAP(PaneHeader, CWnd)
	ON_WM_CREATE()
	END_MESSAGE_MAP()

	int PaneHeader::OnCreate(LPCREATESTRUCT /*lpCreateStruct*/)
	{
		EC_B_S(m_leftLabel.Create(nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CRect(0, 0, 0, 0), this, m_nID));
		::SetWindowTextW(m_leftLabel.m_hWnd, m_szLabel.c_str());
		ui::SubclassLabel(m_leftLabel.m_hWnd);
		if (m_bCollapsible)
		{
			StyleLabel(m_leftLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderLabel);
		}

		EC_B_S(m_rightLabel.Create(
			nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CRect(0, 0, 0, 0), this, IDD_RIGHTLABEL));
		ui::SubclassLabel(m_rightLabel.m_hWnd);
		StyleLabel(m_rightLabel.m_hWnd, ui::uiLabelStyle::PaneHeaderText);

		if (m_bCollapsible)
		{
			EC_B_S(m_CollapseButton.Create(
				nullptr,
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_NOTIFY,
				CRect(0, 0, 0, 0),
				this,
				m_nIDCollapse));
			StyleButton(
				m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);
		}

		// If we need an action button, go ahead and create it
		if (m_nIDAction)
		{
			EC_B_S(m_actionButton.Create(
				strings::wstringTotstring(m_szActionButton).c_str(),
				WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_NOTIFY,
				CRect(0, 0, 0, 0),
				this,
				m_nIDAction));
			StyleButton(m_actionButton.m_hWnd, ui::uiButtonStyle::Unstyled);
		}

		m_bInitialized = true;
		return 0;
	}

	LRESULT PaneHeader::WindowProc(const UINT message, const WPARAM wParam, const LPARAM lParam)
	{
		LRESULT lRes = 0;
		if (ui::HandleControlUI(message, wParam, lParam, &lRes)) return lRes;

		switch (message)
		{
		case WM_PAINT:
			auto ps = PAINTSTRUCT{};
			::BeginPaint(m_hWnd, &ps);
			if (ps.hdc)
			{
				auto rcWin = RECT{};
				::GetClientRect(m_hWnd, &rcWin);
				const auto background = registry::uiDiag ? ui::GetSysBrush(ui::uiColor::TestGreen)
														 : ui::GetSysBrush(ui::uiColor::Background);
				FillRect(ps.hdc, &rcWin, background);
			}

			::EndPaint(m_hWnd, &ps);
			return 0;
		case WM_WINDOWPOSCHANGED:
			RecalcLayout();
			return 0;
		case WM_CLOSE:
			::SendMessage(m_hWndParent, message, wParam, lParam);
			return true;
		case WM_HELP:
			return true;
		case WM_COMMAND:
		{
			const auto nCode = HIWORD(wParam);
			switch (nCode)
			{
			// Pass button clicks up to parent
			case BN_CLICKED:
				// Pass focus notifications up to parent
			case BN_SETFOCUS:
			case EN_SETFOCUS:
				return ::SendMessage(m_hWndParent, message, wParam, lParam);
			}

			break;
		}
		}

		return CWnd::WindowProc(message, wParam, lParam);
	}

	int PaneHeader::GetFixedHeight() const noexcept
	{
		int iHeight = 0;
		if (m_bCollapsible || !m_szLabel.empty()) iHeight = max(m_iButtonHeight, m_iLabelHeight);
		if (!m_bCollapsed && iHeight) iHeight += m_iSmallHeightMargin;

		return iHeight;
	}

	// Position collapse button, labels, action button.
	void PaneHeader::RecalcLayout()
	{
		if (!m_bInitialized) return;
		auto hWinPosInfo = WC_D(HDWP, BeginDeferWindowPos(4));
		if (hWinPosInfo)
		{
			auto rcWin = RECT{};
			::GetClientRect(m_hWnd, &rcWin);
			const auto width = rcWin.right - rcWin.left;
			const auto height = rcWin.bottom - rcWin.top;
			output::DebugPrint(
				output::dbgLevel::Draw,
				L"PaneHeader::DeferWindowPos width:%d height:%d v:%d l:\"%ws\"\n",
				width,
				height,
				IsWindowVisible(),
				m_szLabel.c_str());
			auto curX = 0;
			const auto actionButtonWidth =
				!m_bCollapsed && m_actionButtonWidth ? m_actionButtonWidth + 2 * m_iMargin : 0;
			const auto actionButtonAndGutterWidth = actionButtonWidth ? actionButtonWidth + m_iSideMargin : 0;
			if (m_bCollapsible)
			{
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_CollapseButton.GetSafeHwnd(),
					curX,
					0,
					width - actionButtonAndGutterWidth,
					m_iButtonHeight,
					L"PaneHeader::DeferWindowPos::collapseButton");
				curX += m_iButtonHeight;
			}

			hWinPosInfo = ui::DeferWindowPos(
				hWinPosInfo,
				m_leftLabel.GetSafeHwnd(),
				curX,
				1,
				m_iLabelWidth,
				m_iLabelHeight,
				L"PaneHeader::DeferWindowPos::leftLabel");

			auto cmdShow = SW_HIDE;
			if (!m_bCollapsed && m_rightLabelWidth)
			{
				// Drop the count on top of the label we drew above
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_rightLabel.GetSafeHwnd(),
					width - m_rightLabelWidth - actionButtonAndGutterWidth - m_iSideMargin - 1,
					1,
					m_rightLabelWidth,
					m_iLabelHeight,
					L"PaneHeader::DeferWindowPos::rightLabel");
				cmdShow = SW_SHOW;
			}

			WC_B_S(::ShowWindow(m_rightLabel.GetSafeHwnd(), cmdShow));

			if (!m_bCollapsed && m_nIDAction && m_actionButtonWidth)
			{
				// Drop the action button next to the label we drew above
				hWinPosInfo = ui::DeferWindowPos(
					hWinPosInfo,
					m_actionButton.GetSafeHwnd(),
					width - actionButtonWidth,
					0,
					actionButtonWidth,
					m_iButtonHeight,
					L"PaneHeader::DeferWindowPos::actionButton");
				cmdShow = SW_SHOW;
			}
			else
			{
				cmdShow = SW_HIDE;
			}

			WC_B_S(::ShowWindow(m_actionButton.GetSafeHwnd(), cmdShow));

			output::DebugPrint(output::dbgLevel::Draw, L"PaneHeader::DeferWindowPos end\n");
			EC_B_S(EndDeferWindowPos(hWinPosInfo));
		}
	}

	int PaneHeader::GetMinWidth()
	{
		auto cx = m_iLabelWidth;
		if (m_bCollapsible) cx += m_iButtonHeight;
		if (m_rightLabelWidth)
		{
			cx += m_iSideMargin * 2;
			cx += m_rightLabelWidth;
		}

		if (m_actionButtonWidth)
		{
			cx += m_iSideMargin;
			cx += m_actionButtonWidth + 2 * m_iMargin;
		}

		return cx;
	}

	void PaneHeader::SetRightLabel(const std::wstring szLabel)
	{
		if (!m_bInitialized) return;
		EC_B_S(::SetWindowTextW(m_rightLabel.m_hWnd, szLabel.c_str()));

		const auto hdc = ::GetDC(m_rightLabel.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szLabel);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_rightLabel.GetSafeHwnd(), hdc);
		m_rightLabelWidth = sizeText.cx;

		RecalcLayout();
	}

	void PaneHeader::SetActionButton(const std::wstring szActionButton)
	{
		// Don't bother if we never enabled the button
		if (m_nIDAction == 0) return;

		EC_B_S(::SetWindowTextW(m_actionButton.GetSafeHwnd(), szActionButton.c_str()));

		m_szActionButton = szActionButton;
		const auto hdc = ::GetDC(m_actionButton.GetSafeHwnd());
		const auto hfontOld = SelectObject(hdc, ui::GetSegoeFont());
		const auto sizeText = ui::GetTextExtentPoint32(hdc, szActionButton);
		static_cast<void>(SelectObject(hdc, hfontOld));
		::ReleaseDC(m_actionButton.GetSafeHwnd(), hdc);
		m_actionButtonWidth = sizeText.cx;

		RecalcLayout();
	}

	bool PaneHeader::HandleChange(UINT nID)
	{
		// Collapse buttons have a nID IDD_COLLAPSE higher than nID of the pane they toggle.
		// So if we get asked about one that matches, we can assume it's time to toggle our collapse.
		if (m_nIDCollapse == nID)
		{
			OnToggleCollapse();
			return true;
		}

		return false;
	}

	void PaneHeader::OnToggleCollapse()
	{
		if (!m_bCollapsible) return;
		m_bCollapsed = !m_bCollapsed;

		StyleButton(m_CollapseButton.m_hWnd, m_bCollapsed ? ui::uiButtonStyle::UpArrow : ui::uiButtonStyle::DownArrow);

		// Trigger a redraw
		::PostMessage(m_hWndParent, WM_COMMAND, IDD_RECALCLAYOUT, NULL);

		// When we toggle because of VK_ENTER, we don't redraw - signal one just in case
		::RedrawWindow(m_CollapseButton.m_hWnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
	}

	void PaneHeader::SetMargins(
		int iMargin,
		int iSideMargin,
		int iLabelHeight, // Height of the label
		int iSmallHeightMargin,
		int iButtonHeight) // Height of button
	{
		m_iMargin = iMargin;
		m_iSideMargin = iSideMargin;
		m_iLabelHeight = iLabelHeight;
		m_iSmallHeightMargin = iSmallHeightMargin;
		m_iButtonHeight = iButtonHeight;
	}

	bool PaneHeader::containsWindow(HWND hWnd) const noexcept
	{
		if (GetSafeHwnd() == hWnd) return true;
		if (m_leftLabel.GetSafeHwnd() == hWnd) return true;
		if (m_rightLabel.GetSafeHwnd() == hWnd) return true;
		if (m_actionButton.GetSafeHwnd() == hWnd) return true;
		if (m_CollapseButton.GetSafeHwnd() == hWnd) return true;
		return false;
	}
} // namespace controls<|endoftext|>


<commit_before>#include "segment.h"
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include "size_types.h"

namespace project {

const size_t Segment::kMaxCars = 5;

Segment::Segment(size_t capacity, Segment* prev, int ready_percent,
                 size_t num_junctions, size_t pass_limit)
    : capacity_(capacity),
      entrance_(new Junction(num_junctions, pass_limit)),
      next_(NULL),
      prev_(prev),
      ready_percent_(ready_percent) {
  size_t num_cars = std::min(capacity_, rand() % kMaxCars + 1);
  cars_.resize(num_cars);
  for (size_t i = 0; i < cars_.size(); ++i) {
    size_t exit = rand() % (num_junctions - entrance_->id() - 1) +
                  entrance_->id() + 1;
    cars_[i] = new Car(exit, NULL);
  }
  Ready();
}

Segment::~Segment() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    delete cars_[i];
  }
  delete entrance_;
}

void Segment::Enter() {
  size_t max_cars, ready_cars_before_pass = 0, num_passed_cars = 0;
  if (prev_ != NULL) {
    size_t num_cars_before_pass = cars_.size();
    ready_cars_before_pass = prev_->ready_cars().size();
    max_cars = capacity_ - cars_.size();
    prev_->Pass(max_cars);
    num_passed_cars = cars_.size() - num_cars_before_pass;
  }

  size_t cars_before_enter = entrance_->Cars().size();
  max_cars = capacity_ - cars_.size();
  std::vector<Car*> cars = entrance_->Operate(max_cars);
  if (cars.size() < cars_before_enter) {
    printf("Kathysteriseis stin eisodo tou komvou %" PRIuS "\n",
           entrance_->id());

    if (num_passed_cars < ready_cars_before_pass) {
      printf("Kathysteriseis meta ton komvo %" PRIuS "\n", entrance_->id());
    }
  } else {
    printf("Tireite tis apostaseis asfaleias sto tmima meta ton komvo %" PRIuS
           "\n", entrance_->id());
  }
  cars_.insert(cars_.end(), cars.begin(), cars.end());
}

void Segment::Exit() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready() && cars_[i]->exit() == entrance_->id() + 1) {
      delete cars_[i];
      cars_.erase(cars_.begin() + i);
    }
  }
}

void Segment::Operate() {
  Exit();
  Enter();
  Ready();
  for (std::vector<Car*>::reverse_iterator it = cars_.rbegin();
       it != cars_.rend(); ++it ) {
    if ((*it)->segment() != this) {
      (*it)->set_segment(this);
    } else {
      break;
    }
  }
}

void Segment::Pass(size_t max_cars) {
  size_t passed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (passed_cars == max_cars) {
      break;
    }
    if (cars_[i]->ready() && cars_[i]->exit() != entrance_->id() + 1) {
      cars_[i]->set_ready(false);
      next_->cars_.push_back(cars_[i]);
      cars_.erase(cars_.begin() + i);
      ++passed_cars;
    }
  }
}

const std::vector<Car*>& Segment::cars() const {
  return cars_;
}

size_t Segment::num_cars() const {
  return cars_.size();
}

const std::vector<Car*> Segment::ready_cars() const {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready()) {
      ret.push_back(cars_[i]);
    }
  }
  return ret;
}

size_t Segment::capacity() const {
  return capacity_;
}

size_t Segment::entrance() const {
  return entrance_->id();
}

void Segment::set_next(Segment* next) {
  next_ = next;
}

void Segment::Ready() {
  std::random_shuffle(cars_.begin(), cars_.end());
  size_t num_new_ready = ready_percent_ * cars_.size() / 100;
  size_t num_changed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (num_changed_cars == num_new_ready) {
      break;
    }
    if (!cars_[i]->ready()) {
      cars_[i]->set_ready(true);
      ++num_changed_cars;
    }
  }
}

}  // namespace project
<commit_msg>Style fixes<commit_after>#include "segment.h"
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include "size_types.h"

namespace project {

const size_t Segment::kMaxCars = 5;

Segment::Segment(size_t capacity, Segment* prev, int ready_percent,
                 size_t num_junctions, size_t pass_limit)
    : capacity_(capacity),
      entrance_(new Junction(num_junctions, pass_limit)),
      next_(NULL),
      prev_(prev),
      ready_percent_(ready_percent) {
  size_t num_cars = std::min(capacity_, rand() % kMaxCars + 1);
  cars_.resize(num_cars);
  for (size_t i = 0; i < cars_.size(); ++i) {
    size_t exit = rand() % (num_junctions - entrance_->id() - 1) +
                  entrance_->id() + 1;
    cars_[i] = new Car(exit, NULL);
  }
  Ready();
}

Segment::~Segment() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    delete cars_[i];
  }
  delete entrance_;
}

void Segment::Enter() {
  size_t max_cars, ready_cars_before_pass = 0, num_passed_cars = 0;
  if (prev_ != NULL) {
    size_t num_cars_before_pass = cars_.size();
    ready_cars_before_pass = prev_->ready_cars().size();
    max_cars = capacity_ - cars_.size();
    prev_->Pass(max_cars);
    num_passed_cars = cars_.size() - num_cars_before_pass;
  }

  size_t cars_before_enter = entrance_->Cars().size();
  max_cars = capacity_ - cars_.size();
  std::vector<Car*> cars = entrance_->Operate(max_cars);
  if (cars.size() < cars_before_enter) {
    printf("Kathysteriseis stin eisodo tou komvou %" PRIuS "\n",
           entrance_->id());

    if (num_passed_cars < ready_cars_before_pass) {
      printf("Kathysteriseis meta ton komvo %" PRIuS "\n", entrance_->id());
    }
  } else {
    printf("Tireite tis apostaseis asfaleias sto tmima meta ton komvo %" PRIuS
           "\n", entrance_->id());
  }
  cars_.insert(cars_.end(), cars.begin(), cars.end());
}

void Segment::Exit() {
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready() && cars_[i]->exit() == entrance_->id() + 1) {
      delete cars_[i];
      cars_.erase(cars_.begin() + i);
    }
  }
}

void Segment::Operate() {
  Exit();
  Enter();
  Ready();
  for (std::vector<Car*>::reverse_iterator it = cars_.rbegin();
       it != cars_.rend(); ++it) {
    if ((*it)->segment() = this) {
      break;
    }
    (*it)->set_segment(this);
  }
}

void Segment::Pass(size_t max_cars) {
  size_t passed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (passed_cars == max_cars) {
      break;
    }
    if (cars_[i]->ready() && cars_[i]->exit() != entrance_->id() + 1) {
      cars_[i]->set_ready(false);
      next_->cars_.push_back(cars_[i]);
      cars_.erase(cars_.begin() + i);
      ++passed_cars;
    }
  }
}

const std::vector<Car*>& Segment::cars() const {
  return cars_;
}

size_t Segment::num_cars() const {
  return cars_.size();
}

const std::vector<Car*> Segment::ready_cars() const {
  std::vector<Car*> ret;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (cars_[i]->ready()) {
      ret.push_back(cars_[i]);
    }
  }
  return ret;
}

size_t Segment::capacity() const {
  return capacity_;
}

size_t Segment::entrance() const {
  return entrance_->id();
}

void Segment::set_next(Segment* next) {
  next_ = next;
}

void Segment::Ready() {
  std::random_shuffle(cars_.begin(), cars_.end());
  size_t num_new_ready = ready_percent_ * cars_.size() / 100;
  size_t num_changed_cars = 0;
  for (size_t i = 0; i < cars_.size(); ++i) {
    if (num_changed_cars == num_new_ready) {
      break;
    }
    if (!cars_[i]->ready()) {
      cars_[i]->set_ready(true);
      ++num_changed_cars;
    }
  }
}

}  // namespace project
<|endoftext|>


<commit_before>/*************************************************************************/
/*  editor_plugin_settings.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "editor_plugin_settings.h"

#include "core/io/config_file.h"
#include "core/os/file_access.h"
#include "core/os/main_loop.h"
#include "core/project_settings.h"
#include "editor_node.h"
#include "scene/gui/margin_container.h"

void EditorPluginSettings::_notification(int p_what) {

	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
		update_plugins();
	} else if (p_what == Node::NOTIFICATION_READY) {
		plugin_config_dialog->connect("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
		plugin_list->connect("button_pressed", this, "_cell_button_pressed");
	}
}

void EditorPluginSettings::update_plugins() {

	plugin_list->clear();

	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
	Error err = da->change_dir("res://addons");
	if (err != OK) {
		memdelete(da);
		return;
	}

	updating = true;

	TreeItem *root = plugin_list->create_item();

	da->list_dir_begin();

	String d = da->get_next();

	Vector<String> plugins;

	while (d != String()) {

		bool dir = da->current_is_dir();
		String path = "res://addons/" + d + "/plugin.cfg";

		if (dir && FileAccess::exists(path)) {

			plugins.push_back(d);
		}

		d = da->get_next();
	}

	da->list_dir_end();
	memdelete(da);

	plugins.sort();

	for (int i = 0; i < plugins.size(); i++) {

		Ref<ConfigFile> cf;
		cf.instance();
		String path = "res://addons/" + plugins[i] + "/plugin.cfg";

		Error err2 = cf->load(path);

		if (err2 != OK) {
			WARN_PRINTS("Can't load plugin config: " + path);
		} else if (!cf->has_section_key("plugin", "name")) {
			WARN_PRINTS("Plugin misses plugin/name: " + path);
		} else if (!cf->has_section_key("plugin", "author")) {
			WARN_PRINTS("Plugin misses plugin/author: " + path);
		} else if (!cf->has_section_key("plugin", "version")) {
			WARN_PRINTS("Plugin misses plugin/version: " + path);
		} else if (!cf->has_section_key("plugin", "description")) {
			WARN_PRINTS("Plugin misses plugin/description: " + path);
		} else if (!cf->has_section_key("plugin", "script")) {
			WARN_PRINTS("Plugin misses plugin/script: " + path);
		} else {

			String d2 = plugins[i];
			String name = cf->get_value("plugin", "name");
			String author = cf->get_value("plugin", "author");
			String version = cf->get_value("plugin", "version");
			String description = cf->get_value("plugin", "description");
			String script = cf->get_value("plugin", "script");

			TreeItem *item = plugin_list->create_item(root);
			item->set_text(0, name);
			item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script + "\nDescription: " + description);
			item->set_metadata(0, d2);
			item->set_text(1, version);
			item->set_metadata(1, script);
			item->set_text(2, author);
			item->set_metadata(2, description);
			item->set_cell_mode(3, TreeItem::CELL_MODE_RANGE);
			item->set_range_config(3, 0, 1, 1);
			item->set_text(3, "Inactive,Active");
			item->set_editable(3, true);
			item->add_button(4, get_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));

			if (EditorNode::get_singleton()->is_addon_plugin_enabled(d2)) {
				item->set_custom_color(3, get_color("success_color", "Editor"));
				item->set_range(3, 1);
			} else {
				item->set_custom_color(3, get_color("disabled_font_color", "Editor"));
				item->set_range(3, 0);
			}
		}
	}

	updating = false;
}

void EditorPluginSettings::_plugin_activity_changed() {

	if (updating)
		return;

	TreeItem *ti = plugin_list->get_edited();
	ERR_FAIL_COND(!ti);
	bool active = ti->get_range(3);
	String name = ti->get_metadata(0);

	EditorNode::get_singleton()->set_addon_plugin_enabled(name, active, true);

	bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(name);

	if (is_active != active) {
		updating = true;
		ti->set_range(3, is_active ? 1 : 0);
		updating = false;
	}

	if (is_active)
		ti->set_custom_color(3, get_color("success_color", "Editor"));
	else
		ti->set_custom_color(3, get_color("disabled_font_color", "Editor"));
}

void EditorPluginSettings::_create_clicked() {
	plugin_config_dialog->config("");
	plugin_config_dialog->popup_centered();
}

void EditorPluginSettings::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
	TreeItem *item = Object::cast_to<TreeItem>(p_item);
	if (!item)
		return;
	if (p_id == BUTTON_PLUGIN_EDIT) {
		if (p_column == 4) {
			String dir = item->get_metadata(0);
			plugin_config_dialog->config("res://addons/" + dir + "/plugin.cfg");
			plugin_config_dialog->popup_centered();
		}
	}
}

void EditorPluginSettings::_bind_methods() {

	ClassDB::bind_method("update_plugins", &EditorPluginSettings::update_plugins);
	ClassDB::bind_method("_create_clicked", &EditorPluginSettings::_create_clicked);
	ClassDB::bind_method("_plugin_activity_changed", &EditorPluginSettings::_plugin_activity_changed);
	ClassDB::bind_method("_cell_button_pressed", &EditorPluginSettings::_cell_button_pressed);
}

EditorPluginSettings::EditorPluginSettings() {

	plugin_config_dialog = memnew(PluginConfigDialog);
	plugin_config_dialog->config("");
	add_child(plugin_config_dialog);

	HBoxContainer *title_hb = memnew(HBoxContainer);
	title_hb->add_child(memnew(Label(TTR("Installed Plugins:"))));
	title_hb->add_spacer();
	create_plugin = memnew(Button(TTR("Create")));
	create_plugin->connect("pressed", this, "_create_clicked");
	title_hb->add_child(create_plugin);
	update_list = memnew(Button(TTR("Update")));
	update_list->connect("pressed", this, "update_plugins");
	title_hb->add_child(update_list);
	add_child(title_hb);

	plugin_list = memnew(Tree);
	plugin_list->set_v_size_flags(SIZE_EXPAND_FILL);
	plugin_list->set_columns(5);
	plugin_list->set_column_titles_visible(true);
	plugin_list->set_column_title(0, TTR("Name:"));
	plugin_list->set_column_title(1, TTR("Version:"));
	plugin_list->set_column_title(2, TTR("Author:"));
	plugin_list->set_column_title(3, TTR("Status:"));
	plugin_list->set_column_title(4, TTR("Edit:"));
	plugin_list->set_column_expand(0, true);
	plugin_list->set_column_expand(1, false);
	plugin_list->set_column_expand(2, false);
	plugin_list->set_column_expand(3, false);
	plugin_list->set_column_expand(4, false);
	plugin_list->set_column_min_width(1, 100 * EDSCALE);
	plugin_list->set_column_min_width(2, 250 * EDSCALE);
	plugin_list->set_column_min_width(3, 80 * EDSCALE);
	plugin_list->set_column_min_width(4, 40 * EDSCALE);
	plugin_list->set_hide_root(true);
	plugin_list->connect("item_edited", this, "_plugin_activity_changed");

	VBoxContainer *mc = memnew(VBoxContainer);
	mc->add_child(plugin_list);
	mc->set_v_size_flags(SIZE_EXPAND_FILL);
	mc->set_h_size_flags(SIZE_EXPAND_FILL);

	add_child(mc);

	updating = false;
}
<commit_msg>Warn about all missing keys in plugin.cfg<commit_after>/*************************************************************************/
/*  editor_plugin_settings.cpp                                           */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "editor_plugin_settings.h"

#include "core/io/config_file.h"
#include "core/os/file_access.h"
#include "core/os/main_loop.h"
#include "core/project_settings.h"
#include "editor_node.h"
#include "scene/gui/margin_container.h"

void EditorPluginSettings::_notification(int p_what) {

	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
		update_plugins();
	} else if (p_what == Node::NOTIFICATION_READY) {
		plugin_config_dialog->connect("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
		plugin_list->connect("button_pressed", this, "_cell_button_pressed");
	}
}

void EditorPluginSettings::update_plugins() {

	plugin_list->clear();

	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
	Error err = da->change_dir("res://addons");
	if (err != OK) {
		memdelete(da);
		return;
	}

	updating = true;

	TreeItem *root = plugin_list->create_item();

	da->list_dir_begin();

	String d = da->get_next();

	Vector<String> plugins;

	while (d != String()) {

		bool dir = da->current_is_dir();
		String path = "res://addons/" + d + "/plugin.cfg";

		if (dir && FileAccess::exists(path)) {

			plugins.push_back(d);
		}

		d = da->get_next();
	}

	da->list_dir_end();
	memdelete(da);

	plugins.sort();

	for (int i = 0; i < plugins.size(); i++) {

		Ref<ConfigFile> cf;
		cf.instance();
		String path = "res://addons/" + plugins[i] + "/plugin.cfg";

		Error err2 = cf->load(path);

		if (err2 != OK) {
			WARN_PRINTS("Can't load plugin config: " + path);
		} else {
			bool key_missing = false;

			if (!cf->has_section_key("plugin", "name")) {
				WARN_PRINTS("Plugin config misses \"plugin/name\" key: " + path);
				key_missing = true;
			}
			if (!cf->has_section_key("plugin", "author")) {
				WARN_PRINTS("Plugin config misses \"plugin/author\" key: " + path);
				key_missing = true;
			}
			if (!cf->has_section_key("plugin", "version")) {
				WARN_PRINTS("Plugin config misses \"plugin/version\" key: " + path);
				key_missing = true;
			}
			if (!cf->has_section_key("plugin", "description")) {
				WARN_PRINTS("Plugin config misses \"plugin/description\" key: " + path);
				key_missing = true;
			}
			if (!cf->has_section_key("plugin", "script")) {
				WARN_PRINTS("Plugin config misses \"plugin/script\" key: " + path);
				key_missing = true;
			}

			if (!key_missing) {
				String d2 = plugins[i];
				String name = cf->get_value("plugin", "name");
				String author = cf->get_value("plugin", "author");
				String version = cf->get_value("plugin", "version");
				String description = cf->get_value("plugin", "description");
				String script = cf->get_value("plugin", "script");

				TreeItem *item = plugin_list->create_item(root);
				item->set_text(0, name);
				item->set_tooltip(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description);
				item->set_metadata(0, d2);
				item->set_text(1, version);
				item->set_metadata(1, script);
				item->set_text(2, author);
				item->set_metadata(2, description);
				item->set_cell_mode(3, TreeItem::CELL_MODE_RANGE);
				item->set_range_config(3, 0, 1, 1);
				item->set_text(3, "Inactive,Active");
				item->set_editable(3, true);
				item->add_button(4, get_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));

				if (EditorNode::get_singleton()->is_addon_plugin_enabled(d2)) {
					item->set_custom_color(3, get_color("success_color", "Editor"));
					item->set_range(3, 1);
				} else {
					item->set_custom_color(3, get_color("disabled_font_color", "Editor"));
					item->set_range(3, 0);
				}
			}
		}
	}

	updating = false;
}

void EditorPluginSettings::_plugin_activity_changed() {

	if (updating)
		return;

	TreeItem *ti = plugin_list->get_edited();
	ERR_FAIL_COND(!ti);
	bool active = ti->get_range(3);
	String name = ti->get_metadata(0);

	EditorNode::get_singleton()->set_addon_plugin_enabled(name, active, true);

	bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(name);

	if (is_active != active) {
		updating = true;
		ti->set_range(3, is_active ? 1 : 0);
		updating = false;
	}

	if (is_active)
		ti->set_custom_color(3, get_color("success_color", "Editor"));
	else
		ti->set_custom_color(3, get_color("disabled_font_color", "Editor"));
}

void EditorPluginSettings::_create_clicked() {
	plugin_config_dialog->config("");
	plugin_config_dialog->popup_centered();
}

void EditorPluginSettings::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
	TreeItem *item = Object::cast_to<TreeItem>(p_item);
	if (!item)
		return;
	if (p_id == BUTTON_PLUGIN_EDIT) {
		if (p_column == 4) {
			String dir = item->get_metadata(0);
			plugin_config_dialog->config("res://addons/" + dir + "/plugin.cfg");
			plugin_config_dialog->popup_centered();
		}
	}
}

void EditorPluginSettings::_bind_methods() {

	ClassDB::bind_method("update_plugins", &EditorPluginSettings::update_plugins);
	ClassDB::bind_method("_create_clicked", &EditorPluginSettings::_create_clicked);
	ClassDB::bind_method("_plugin_activity_changed", &EditorPluginSettings::_plugin_activity_changed);
	ClassDB::bind_method("_cell_button_pressed", &EditorPluginSettings::_cell_button_pressed);
}

EditorPluginSettings::EditorPluginSettings() {

	plugin_config_dialog = memnew(PluginConfigDialog);
	plugin_config_dialog->config("");
	add_child(plugin_config_dialog);

	HBoxContainer *title_hb = memnew(HBoxContainer);
	title_hb->add_child(memnew(Label(TTR("Installed Plugins:"))));
	title_hb->add_spacer();
	create_plugin = memnew(Button(TTR("Create")));
	create_plugin->connect("pressed", this, "_create_clicked");
	title_hb->add_child(create_plugin);
	update_list = memnew(Button(TTR("Update")));
	update_list->connect("pressed", this, "update_plugins");
	title_hb->add_child(update_list);
	add_child(title_hb);

	plugin_list = memnew(Tree);
	plugin_list->set_v_size_flags(SIZE_EXPAND_FILL);
	plugin_list->set_columns(5);
	plugin_list->set_column_titles_visible(true);
	plugin_list->set_column_title(0, TTR("Name:"));
	plugin_list->set_column_title(1, TTR("Version:"));
	plugin_list->set_column_title(2, TTR("Author:"));
	plugin_list->set_column_title(3, TTR("Status:"));
	plugin_list->set_column_title(4, TTR("Edit:"));
	plugin_list->set_column_expand(0, true);
	plugin_list->set_column_expand(1, false);
	plugin_list->set_column_expand(2, false);
	plugin_list->set_column_expand(3, false);
	plugin_list->set_column_expand(4, false);
	plugin_list->set_column_min_width(1, 100 * EDSCALE);
	plugin_list->set_column_min_width(2, 250 * EDSCALE);
	plugin_list->set_column_min_width(3, 80 * EDSCALE);
	plugin_list->set_column_min_width(4, 40 * EDSCALE);
	plugin_list->set_hide_root(true);
	plugin_list->connect("item_edited", this, "_plugin_activity_changed");

	VBoxContainer *mc = memnew(VBoxContainer);
	mc->add_child(plugin_list);
	mc->set_v_size_flags(SIZE_EXPAND_FILL);
	mc->set_h_size_flags(SIZE_EXPAND_FILL);

	add_child(mc);

	updating = false;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   KWSys - Kitware System Library
  Module:    testDynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"

#include KWSYS_HEADER(DynamicLoader.hxx)
#include KWSYS_HEADER(ios/iostream)
#include KWSYS_HEADER(stl/string)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "kwsys_ios_iostream.h.in"
# include "kwsys_stl_string.hxx.in"
#endif

#include "testSystemTools.h"

kwsys_stl::string GetLibName(const char* lname)
{
  // Construct proper name of lib
  kwsys_stl::string slname;
  slname = EXECUTABLE_OUTPUT_PATH;
#ifdef CMAKE_INTDIR
  slname += "/";
  slname += CMAKE_INTDIR;
#endif
  slname += "/";
  slname += kwsys::DynamicLoader::LibPrefix();
  slname += lname;
  slname += kwsys::DynamicLoader::LibExtension();

  return slname;
}

/* libname = Library name (proper prefix, proper extension)
 * System  = symbol to lookup in libname
 * r1: should OpenLibrary succeed ?
 * r2: should GetSymbolAddress succeed ?
 * r3: should CloseLibrary succeed ?
 */
int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
{
  kwsys_ios::cerr << "Testing: " << libname << kwsys_ios::endl;
  kwsys::LibHandle l = kwsys::DynamicLoader::OpenLibrary(libname);
  // If result is incompatible with expectation just fails (xor):
  if( (r1 && !l) || (!r1 && l) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  kwsys::DynamicLoaderFunction f = kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
  if( (r2 && !f) || (!r2 && f) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  int s = kwsys::DynamicLoader::CloseLibrary(l);
  if( (r3 && !s) || (!r3 && s) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  return 0;
}

int main(int , char *[])
{
  int res;
  // Make sure that inexistant lib is giving correct result
  res = TestDynamicLoader("azerty_", "foo_bar",0,0,0);
  // Make sure that random binary file cannnot be assimilated as dylib
  res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
#ifdef __linux__
  // This one is actually fun to test, since dlopen is by default loaded...wonder why :)
  res += TestDynamicLoader("foobar.lib", "dlopen",0,1,0);
  res += TestDynamicLoader("libdl.so", "dlopen",1,1,1);
  res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
#endif
  // Now try on the generated library
  kwsys_stl::string libname = GetLibName("testDynload");
  res += TestDynamicLoader(libname.c_str(), "dummy",1,0,1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderFunction",1,1,1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderFunction",1,0,1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData",1,1,1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData",1,0,1);

  return res;
}
<commit_msg>ENH: Make test usable from command line<commit_after>/*=========================================================================

  Program:   KWSys - Kitware System Library
  Module:    testDynamicLoader.cxx

  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsysPrivate.h"

#include KWSYS_HEADER(DynamicLoader.hxx)
#include KWSYS_HEADER(ios/iostream)
#include KWSYS_HEADER(stl/string)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
# include "kwsys_ios_iostream.h.in"
# include "kwsys_stl_string.hxx.in"
#endif

#include "testSystemTools.h"

kwsys_stl::string GetLibName(const char* lname)
{
  // Construct proper name of lib
  kwsys_stl::string slname;
  slname = EXECUTABLE_OUTPUT_PATH;
#ifdef CMAKE_INTDIR
  slname += "/";
  slname += CMAKE_INTDIR;
#endif
  slname += "/";
  slname += kwsys::DynamicLoader::LibPrefix();
  slname += lname;
  slname += kwsys::DynamicLoader::LibExtension();

  return slname;
}

/* libname = Library name (proper prefix, proper extension)
 * System  = symbol to lookup in libname
 * r1: should OpenLibrary succeed ?
 * r2: should GetSymbolAddress succeed ?
 * r3: should CloseLibrary succeed ?
 */
int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
{
  kwsys_ios::cerr << "Testing: " << libname << kwsys_ios::endl;
  kwsys::LibHandle l = kwsys::DynamicLoader::OpenLibrary(libname);
  // If result is incompatible with expectation just fails (xor):
  if( (r1 && !l) || (!r1 && l) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  kwsys::DynamicLoaderFunction f = kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
  if( (r2 && !f) || (!r2 && f) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  int s = kwsys::DynamicLoader::CloseLibrary(l);
  if( (r3 && !s) || (!r3 && s) )
    {
    kwsys_ios::cerr
      << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
    return 1;
    }
  return 0;
}

int main(int argc, char *argv[])
{
  int res;
  if( argc == 3 )
    {
    // User specify a libname and symbol to check.
    res = TestDynamicLoader(argv[1], argv[2],1,1,1);
    return res;
    }
  // Make sure that inexistant lib is giving correct result
  res = TestDynamicLoader("azerty_", "foo_bar",0,0,0);
  // Make sure that random binary file cannnot be assimilated as dylib
  res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
#ifdef __linux__
  // This one is actually fun to test, since dlopen is by default loaded...wonder why :)
  res += TestDynamicLoader("foobar.lib", "dlopen",0,1,0);
  res += TestDynamicLoader("libdl.so", "dlopen",1,1,1);
  res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
#endif
  // Now try on the generated library
  kwsys_stl::string libname = GetLibName("testDynload");
  res += TestDynamicLoader(libname.c_str(), "dummy",1,0,1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderFunction",1,1,1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderFunction",1,0,1);
  res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData",1,1,1);
  res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData",1,0,1);

  return res;
}
<|endoftext|>


<commit_before>/*
 * CameraParamsTileRectOverride.cpp
 *
 * Copyright (C) 2006 - 2007 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 * Copyright (C) 2007, Sebastian Grottel. All rights reserved.
 */

#include "vislib/graphics/CameraParamsTileRectOverride.h"
#include "vislib/assert.h"
#include "vislib/math/mathfunctions.h"

/*
 * vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride(void)
        : CameraParamsOverride(), fullSize(true), tileRect() {
}

/*
 * vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride(
        const vislib::SmartPtr<vislib::graphics::CameraParameters>& params)
        : CameraParamsOverride(params), fullSize(true), tileRect(params->TileRect()) {
    this->fullSize = (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(), params->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(), params->VirtualViewSize().Height()));
    this->indicateValueChange();
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::~CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::~CameraParamsTileRectOverride(void) {
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::ResetTileRect
 */
void vislib::graphics::CameraParamsTileRectOverride::ResetTileRect(void) {
    ASSERT(!this->paramsBase().IsNull());
    this->fullSize = true;
    this->tileRect.SetNull();
    this->tileRect.SetSize(this->paramsBase()->VirtualViewSize());
    this->indicateValueChange();
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::SetTileRect
 */
void vislib::graphics::CameraParamsTileRectOverride::SetTileRect(
        const vislib::math::Rectangle<vislib::graphics::ImageSpaceType>& tileRect) {
    ASSERT(!this->paramsBase().IsNull());
    this->tileRect = tileRect;
    this->fullSize = (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(), this->paramsBase()->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(), this->paramsBase()->VirtualViewSize().Height()));
    this->indicateValueChange();
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::TileRect
 */
const vislib::math::Rectangle<vislib::graphics::ImageSpaceType>&
vislib::graphics::CameraParamsTileRectOverride::TileRect(void) const {
    ASSERT(!this->paramsBase().IsNull());
    if (this->fullSize) {
        this->tileRect.SetNull();
        this->tileRect.SetSize(this->paramsBase()->VirtualViewSize());
    }
    return this->tileRect;
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::operator=
 */
vislib::graphics::CameraParamsTileRectOverride&
vislib::graphics::CameraParamsTileRectOverride::operator=(
        const vislib::graphics::CameraParamsTileRectOverride& rhs) {
    CameraParamsOverride::operator=(rhs);
    this->tileRect = rhs.tileRect;
    this->fullSize = rhs.fullSize;
    this->indicateValueChange();
    return *this;
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::operator==
 */
bool vislib::graphics::CameraParamsTileRectOverride::operator==(
        const vislib::graphics::CameraParamsTileRectOverride& rhs) const {
    return (CameraParamsOverride::operator==(rhs)
        && (this->tileRect == rhs.tileRect)
        && (this->fullSize == rhs.fullSize));
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::preBaseSet
 */
void vislib::graphics::CameraParamsTileRectOverride::preBaseSet(
        const SmartPtr<CameraParameters>& params) {
    if (params.IsNull()) {
        return;
    }

    if (this->fullSize) {
        this->tileRect.SetNull();
        this->tileRect.SetSize(params->VirtualViewSize());
        this->indicateValueChange();

    } else if (!this->paramsBase().IsNull()) {
        // scale the tile from the old view size to the new view size and hope
        // that the caller will set a tile making more sense.
        ImageSpaceType scaleX = params->VirtualViewSize().Width()
            / this->paramsBase()->VirtualViewSize().Width();
        ImageSpaceType scaleY = params->VirtualViewSize().Height()
            / this->paramsBase()->VirtualViewSize().Height();
        this->tileRect.Set(this->tileRect.Left() * scaleX,
            this->tileRect.Bottom() * scaleY,
            this->tileRect.Right() * scaleX,
            this->tileRect.Top() * scaleY);
        this->indicateValueChange();
    }
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::resetOverride
 */
void vislib::graphics::CameraParamsTileRectOverride::resetOverride(void) {
    ASSERT(!this->paramsBase().IsNull());
    this->tileRect = this->paramsBase()->TileRect();
    this->fullSize = (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(),
            this->paramsBase()->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(),
            this->paramsBase()->VirtualViewSize().Height()));
    this->indicateValueChange();
}
<commit_msg>assign_and_sync in CameraParamsTileRectOverride<commit_after>/*
 * CameraParamsTileRectOverride.cpp
 *
 * Copyright (C) 2006 - 2007 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 * Copyright (C) 2007, Sebastian Grottel. All rights reserved.
 */

#include "vislib/graphics/CameraParamsTileRectOverride.h"
#include "vislib/assert.h"
#include "vislib/math/mathfunctions.h"

/*
 * vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride(void)
        : CameraParamsOverride(), fullSize(true), tileRect() {
}

/*
 * vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::CameraParamsTileRectOverride(
        const vislib::SmartPtr<vislib::graphics::CameraParameters>& params)
        : CameraParamsOverride(params), fullSize(true), tileRect(params->TileRect()) {
    this->fullSize = (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(), params->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(), params->VirtualViewSize().Height()));
    this->indicateValueChange();
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::~CameraParamsTileRectOverride
 */
vislib::graphics::CameraParamsTileRectOverride::~CameraParamsTileRectOverride(void) {
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::ResetTileRect
 */
void vislib::graphics::CameraParamsTileRectOverride::ResetTileRect(void) {
    ASSERT(!this->paramsBase().IsNull());
    assign_and_sync(this->fullSize, true);
    if (this->TileRect().Width() != this->paramsBase()->VirtualViewSize().Width() ||
        this->TileRect().Height() != this->paramsBase()->VirtualViewSize().Height()) {
        this->tileRect.SetNull();
        this->tileRect.SetSize(this->paramsBase()->VirtualViewSize());
        this->indicateValueChange();
    }
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::SetTileRect
 */
void vislib::graphics::CameraParamsTileRectOverride::SetTileRect(
        const vislib::math::Rectangle<vislib::graphics::ImageSpaceType>& tileRect) {
    ASSERT(!this->paramsBase().IsNull());
    assign_and_sync(this->tileRect, tileRect);
    assign_and_sync(this->fullSize, (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(), this->paramsBase()->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(), this->paramsBase()->VirtualViewSize().Height())));
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::TileRect
 */
const vislib::math::Rectangle<vislib::graphics::ImageSpaceType>&
vislib::graphics::CameraParamsTileRectOverride::TileRect(void) const {
    ASSERT(!this->paramsBase().IsNull());
    if (this->fullSize) {
        if (this->tileRect.Width() != this->paramsBase()->VirtualViewSize().Width() ||
            this->tileRect.Height() != this->paramsBase()->VirtualViewSize().Height()) {
            this->tileRect.SetNull();
            this->tileRect.SetSize(this->paramsBase()->VirtualViewSize());
            this->indicateValueChange_Const();
        }
    }
    return this->tileRect;
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::operator=
 */
vislib::graphics::CameraParamsTileRectOverride&
vislib::graphics::CameraParamsTileRectOverride::operator=(
        const vislib::graphics::CameraParamsTileRectOverride& rhs) {
    CameraParamsOverride::operator=(rhs);
    this->tileRect = rhs.tileRect;
    this->fullSize = rhs.fullSize;
    this->indicateValueChange();
    return *this;
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::operator==
 */
bool vislib::graphics::CameraParamsTileRectOverride::operator==(
        const vislib::graphics::CameraParamsTileRectOverride& rhs) const {
    return (CameraParamsOverride::operator==(rhs)
        && (this->tileRect == rhs.tileRect)
        && (this->fullSize == rhs.fullSize));
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::preBaseSet
 */
void vislib::graphics::CameraParamsTileRectOverride::preBaseSet(
        const SmartPtr<CameraParameters>& params) {
    if (params.IsNull()) {
        return;
    }

    if (this->fullSize) {
        if (this->tileRect.Width() != params->VirtualViewSize().Width() ||
            this->tileRect.Height() != params->VirtualViewSize().Height()) {
            this->tileRect.SetNull();
            this->tileRect.SetSize(params->VirtualViewSize());
            this->indicateValueChange();
        }

    } else if (!this->paramsBase().IsNull()) {
        // scale the tile from the old view size to the new view size and hope
        // that the caller will set a tile making more sense.
        ImageSpaceType const scaleX = params->VirtualViewSize().Width()
            / this->paramsBase()->VirtualViewSize().Width();
        ImageSpaceType const scaleY = params->VirtualViewSize().Height()
            / this->paramsBase()->VirtualViewSize().Height();
        if (!vislib::math::almost_equal(scaleX, static_cast<ImageSpaceType>(1.0f)) ||
            !vislib::math::almost_equal(scaleY, static_cast<ImageSpaceType>(1.0f))) {
            this->tileRect.Set(this->tileRect.Left() * scaleX, this->tileRect.Bottom() * scaleY,
                this->tileRect.Right() * scaleX, this->tileRect.Top() * scaleY);
            this->indicateValueChange();
        }
    }
}

/*
 *  vislib::graphics::CameraParamsTileRectOverride::resetOverride
 */
void vislib::graphics::CameraParamsTileRectOverride::resetOverride(void) {
    ASSERT(!this->paramsBase().IsNull());
    assign_and_sync(this->tileRect, this->paramsBase()->TileRect());
    assign_and_sync(this->fullSize, (math::IsEqual(this->tileRect.GetLeft(), 0.0f)
        && math::IsEqual(this->tileRect.GetBottom(), 0.0f)
        && math::IsEqual(this->tileRect.GetRight(),
            this->paramsBase()->VirtualViewSize().Width())
        && math::IsEqual(this->tileRect.GetTop(),
            this->paramsBase()->VirtualViewSize().Height())));
}
<|endoftext|>


<commit_before>// Windowmenu.cc for Fluxbox
// Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org)
// Windowmenu.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Windowmenu.cc,v 1.12 2002/04/09 23:19:02 fluxgen Exp $

//use GNU extensions
#ifndef	 _GNU_SOURCE
#define	 _GNU_SOURCE
#endif // _GNU_SOURCE

#ifdef		HAVE_CONFIG_H
#	include "../config.h"
#endif // HAVE_CONFIG_H

#include "i18n.hh"
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "Windowmenu.hh"
#include "Workspace.hh"

#ifdef		STDC_HEADERS
#	include <string.h>
#endif // STDC_HEADERS

Windowmenu::Windowmenu(FluxboxWindow *win) : Basemenu(win->getScreen()),
window(win),
screen(window->getScreen()){

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();

	I18n *i18n = I18n::instance();

	sendToMenu = new SendtoWorkspacemenu(this);
	sendGroupToMenu = new SendGroupToWorkspacemenu(this);
	using namespace FBNLS;
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendTo,
		"Send To ..."),
	 sendToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendGroupTo,
		"Send Group To ..."),
	sendGroupToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuShade,
		"Shade"),
	 BScreen::WINDOWSHADE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuIconify,
		"Iconify"),
	 BScreen::WINDOWICONIFY);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuMaximize,
		"Maximize"),
	 BScreen::WINDOWMAXIMIZE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuRaise,
		"Raise"),
	 BScreen::WINDOWRAISE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuLower,
		"Lower"),
	 BScreen::WINDOWLOWER);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuStick,
		"Stick"),
	 BScreen::WINDOWSTICK);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuKillClient,
		"Kill Client"),
	 BScreen::WINDOWKILL);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuClose,
		"Close"),
	 BScreen::WINDOWCLOSE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuTab,
		"Tab"),
	 BScreen::WINDOWTAB);

	update();

	setItemEnabled(2, window->hasTitlebar());
	setItemEnabled(3, window->isIconifiable());
	setItemEnabled(4, window->isMaximizable());
	setItemEnabled(9, window->isClosable());
	setItemEnabled(10, window->hasTab());

}

Windowmenu::~Windowmenu(void) {
	delete sendToMenu;
	delete sendGroupToMenu;
}

void Windowmenu::show(void) {
	if (isItemEnabled(2)) setItemSelected(2, window->isShaded());
	if (isItemEnabled(4)) setItemSelected(4, window->isMaximized());
	if (isItemEnabled(7)) setItemSelected(7, window->isStuck());

	Basemenu::show();
}

void Windowmenu::itemSelected(int button, unsigned int index) {
	BasemenuItem *item = find(index);

	switch (item->function()) {
	case BScreen::WINDOWSHADE:
		hide();

		window->shade();
		if (window->hasTab())
			window->getTab()->shade();
		break;

	case BScreen::WINDOWICONIFY:
		hide();
		window->iconify();
		break;

	case BScreen::WINDOWMAXIMIZE:
		hide();
		window->maximize((unsigned int) button);
		break;

	case BScreen::WINDOWCLOSE:
		hide();
		window->close();
		break;

	case BScreen::WINDOWRAISE:
		hide();
		if (window->hasTab())
			window->getTab()->raise(); //raise tabs
		screen->getWorkspace(window->getWorkspaceNumber())->raiseWindow(window);
		break;

	case BScreen::WINDOWLOWER:
		hide();
	 	screen->getWorkspace(window->getWorkspaceNumber())->lowerWindow(window);
		if (window->hasTab())
			window->getTab()->lower(); //lower tabs AND all it's windows
		break;

	case BScreen::WINDOWSTICK:
		hide();
		window->stick();
		break;

	case BScreen::WINDOWKILL:
		hide();
		XKillClient(screen->getBaseDisplay()->getXDisplay(),
								window->getClientWindow());
		break;
	case BScreen::WINDOWTAB:
		hide();
		window->setTab(!window->hasTab());
		break;
	}
}

void Windowmenu::reconfigure(void) {
	setItemEnabled(1, window->hasTitlebar());
	setItemEnabled(2, window->isIconifiable());
	setItemEnabled(3, window->isMaximizable());
	setItemEnabled(8, window->isClosable());

	sendToMenu->reconfigure();
	sendGroupToMenu->reconfigure();

	Basemenu::reconfigure();
}

Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu *w)
	: Basemenu(w->screen)
{
	windowmenu = w;

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();
	update();
}

void Windowmenu::SendtoWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2) return;

	if (index <= windowmenu->screen->getCount()) {
		if (index == windowmenu->screen->getCurrentWorkspaceID()) return;
		if (windowmenu->window->isStuck()) windowmenu->window->stick();

		if (button == 1)
			windowmenu->screen->sendToWorkspace(index, False);
		else if (button == 2)
			windowmenu->screen->sendToWorkspace(index);
	}

	hide();
}

void Windowmenu::SendtoWorkspacemenu::update(void) {
	unsigned int i, r = numberOfItems();

	if (numberOfItems() != 0) {
		for (i = 0; i < r; ++i)
			remove(0);
	}
	for (i = 0; i < windowmenu->screen->getCount(); ++i)
		insert(windowmenu->screen->getWorkspace(i)->name().c_str());

	Basemenu::update();
}

void Windowmenu::SendtoWorkspacemenu::show(void) {
	update();

	Basemenu::show();
}

void Windowmenu::SendGroupToWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2)
		return;

	if (index <= getWindowMenu()->screen->getCount()) {
		if (index == getWindowMenu()->screen->getCurrentWorkspaceID())
			return;
		if (getWindowMenu()->window->isStuck())
			getWindowMenu()->window->stick();

		if (button == 1) {
			if (getWindowMenu()->window->hasTab()) {
				for (Tab *first = Tab::getFirst(getWindowMenu()->window->getTab());
						first!=0; first=first->next()) {
					first->withdraw();
					first->getWindow()->withdraw();
					getWindowMenu()->screen->reassociateWindow(first->getWindow(), index, True);

				}
			} else	{
				getWindowMenu()->window->withdraw();
				getWindowMenu()->screen->reassociateWindow(getWindowMenu()->window, index, True);
			}

		}

		if (button == 2)
			getWindowMenu()->screen->changeWorkspaceID(index);
	}
	hide();
}

Windowmenu::SendGroupToWorkspacemenu::SendGroupToWorkspacemenu(Windowmenu *w):SendtoWorkspacemenu(w)
{

}

<commit_msg>always true on tab<commit_after>// Windowmenu.cc for Fluxbox
// Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org)
// Windowmenu.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Windowmenu.cc,v 1.13 2002/04/14 22:26:43 fluxgen Exp $

//use GNU extensions
#ifndef	 _GNU_SOURCE
#define	 _GNU_SOURCE
#endif // _GNU_SOURCE

#ifdef		HAVE_CONFIG_H
#	include "../config.h"
#endif // HAVE_CONFIG_H

#include "i18n.hh"
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "Windowmenu.hh"
#include "Workspace.hh"

#ifdef		STDC_HEADERS
#	include <string.h>
#endif // STDC_HEADERS

Windowmenu::Windowmenu(FluxboxWindow *win) : Basemenu(win->getScreen()),
window(win),
screen(window->getScreen()){

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();

	I18n *i18n = I18n::instance();

	sendToMenu = new SendtoWorkspacemenu(this);
	sendGroupToMenu = new SendGroupToWorkspacemenu(this);
	using namespace FBNLS;
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendTo,
		"Send To ..."),
	 sendToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendGroupTo,
		"Send Group To ..."),
	sendGroupToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuShade,
		"Shade"),
	 BScreen::WINDOWSHADE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuIconify,
		"Iconify"),
	 BScreen::WINDOWICONIFY);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuMaximize,
		"Maximize"),
	 BScreen::WINDOWMAXIMIZE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuRaise,
		"Raise"),
	 BScreen::WINDOWRAISE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuLower,
		"Lower"),
	 BScreen::WINDOWLOWER);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuStick,
		"Stick"),
	 BScreen::WINDOWSTICK);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuKillClient,
		"Kill Client"),
	 BScreen::WINDOWKILL);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuClose,
		"Close"),
	 BScreen::WINDOWCLOSE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuTab,
		"Tab"),
	 BScreen::WINDOWTAB);

	update();

	setItemEnabled(2, window->hasTitlebar());
	setItemEnabled(3, window->isIconifiable());
	setItemEnabled(4, window->isMaximizable());
	setItemEnabled(9, window->isClosable());
	setItemEnabled(10, true); //we should always be able to enable the tab

}

Windowmenu::~Windowmenu(void) {
	delete sendToMenu;
	delete sendGroupToMenu;
}

void Windowmenu::show(void) {
	if (isItemEnabled(2)) setItemSelected(2, window->isShaded());
	if (isItemEnabled(4)) setItemSelected(4, window->isMaximized());
	if (isItemEnabled(7)) setItemSelected(7, window->isStuck());

	Basemenu::show();
}

void Windowmenu::itemSelected(int button, unsigned int index) {
	BasemenuItem *item = find(index);

	switch (item->function()) {
	case BScreen::WINDOWSHADE:
		hide();

		window->shade();
		if (window->hasTab())
			window->getTab()->shade();
		break;

	case BScreen::WINDOWICONIFY:
		hide();
		window->iconify();
		break;

	case BScreen::WINDOWMAXIMIZE:
		hide();
		window->maximize((unsigned int) button);
		break;

	case BScreen::WINDOWCLOSE:
		hide();
		window->close();
		break;

	case BScreen::WINDOWRAISE:
		hide();
		if (window->hasTab())
			window->getTab()->raise(); //raise tabs
		screen->getWorkspace(window->getWorkspaceNumber())->raiseWindow(window);
		break;

	case BScreen::WINDOWLOWER:
		hide();
	 	screen->getWorkspace(window->getWorkspaceNumber())->lowerWindow(window);
		if (window->hasTab())
			window->getTab()->lower(); //lower tabs AND all it's windows
		break;

	case BScreen::WINDOWSTICK:
		hide();
		window->stick();
		break;

	case BScreen::WINDOWKILL:
		hide();
		XKillClient(screen->getBaseDisplay()->getXDisplay(),
								window->getClientWindow());
		break;
	case BScreen::WINDOWTAB:
		hide();
		window->setTab(!window->hasTab());
		break;
	}
}

void Windowmenu::reconfigure(void) {
	setItemEnabled(1, window->hasTitlebar());
	setItemEnabled(2, window->isIconifiable());
	setItemEnabled(3, window->isMaximizable());
	setItemEnabled(8, window->isClosable());

	sendToMenu->reconfigure();
	sendGroupToMenu->reconfigure();

	Basemenu::reconfigure();
}

Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu *w)
	: Basemenu(w->screen)
{
	windowmenu = w;

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();
	update();
}

void Windowmenu::SendtoWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2) return;

	if (index <= windowmenu->screen->getCount()) {
		if (index == windowmenu->screen->getCurrentWorkspaceID()) return;
		if (windowmenu->window->isStuck()) windowmenu->window->stick();

		if (button == 1)
			windowmenu->screen->sendToWorkspace(index, False);
		else if (button == 2)
			windowmenu->screen->sendToWorkspace(index);
	}

	hide();
}

void Windowmenu::SendtoWorkspacemenu::update(void) {
	unsigned int i, r = numberOfItems();

	if (numberOfItems() != 0) {
		for (i = 0; i < r; ++i)
			remove(0);
	}
	for (i = 0; i < windowmenu->screen->getCount(); ++i)
		insert(windowmenu->screen->getWorkspace(i)->name().c_str());

	Basemenu::update();
}

void Windowmenu::SendtoWorkspacemenu::show(void) {
	update();

	Basemenu::show();
}

void Windowmenu::SendGroupToWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2)
		return;

	if (index <= getWindowMenu()->screen->getCount()) {
		if (index == getWindowMenu()->screen->getCurrentWorkspaceID())
			return;
		if (getWindowMenu()->window->isStuck())
			getWindowMenu()->window->stick();

		if (button == 1) {
			if (getWindowMenu()->window->hasTab()) {
				for (Tab *first = Tab::getFirst(getWindowMenu()->window->getTab());
						first!=0; first=first->next()) {
					first->withdraw();
					first->getWindow()->withdraw();
					getWindowMenu()->screen->reassociateWindow(first->getWindow(), index, True);

				}
			} else	{
				getWindowMenu()->window->withdraw();
				getWindowMenu()->screen->reassociateWindow(getWindowMenu()->window, index, True);
			}

		}

		if (button == 2)
			getWindowMenu()->screen->changeWorkspaceID(index);
	}
	hide();
}

Windowmenu::SendGroupToWorkspacemenu::SendGroupToWorkspacemenu(Windowmenu *w):SendtoWorkspacemenu(w)
{

}

<|endoftext|>


<commit_before>// Windowmenu.cc for Fluxbox
// Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org)
// Windowmenu.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Windowmenu.cc,v 1.15 2002/07/23 13:49:01 fluxgen Exp $

//use GNU extensions
#ifndef	 _GNU_SOURCE
#define	 _GNU_SOURCE
#endif // _GNU_SOURCE

#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif // HAVE_CONFIG_H

#include "i18n.hh"
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "Windowmenu.hh"
#include "Workspace.hh"

#ifdef STDC_HEADERS
#include <string.h>
#endif // STDC_HEADERS

Windowmenu::Windowmenu(FluxboxWindow *win) : Basemenu(win->getScreen()),
window(win),
screen(window->getScreen()){

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();

	I18n *i18n = I18n::instance();

	sendToMenu = new SendtoWorkspacemenu(this);
	sendGroupToMenu = new SendGroupToWorkspacemenu(this);
	using namespace FBNLS;
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendTo,
		"Send To ..."),
	 sendToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendGroupTo,
		"Send Group To ..."),
	sendGroupToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuShade,
		"Shade"),
	 BScreen::WINDOWSHADE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuIconify,
		"Iconify"),
	 BScreen::WINDOWICONIFY);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuMaximize,
		"Maximize"),
	 BScreen::WINDOWMAXIMIZE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuRaise,
		"Raise"),
	 BScreen::WINDOWRAISE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuLower,
		"Lower"),
	 BScreen::WINDOWLOWER);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuStick,
		"Stick"),
	 BScreen::WINDOWSTICK);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuKillClient,
		"Kill Client"),
	 BScreen::WINDOWKILL);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuClose,
		"Close"),
	 BScreen::WINDOWCLOSE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuTab,
		"Tab"),
	 BScreen::WINDOWTAB);

	update();

	setItemEnabled(2, window->hasTitlebar());
	setItemEnabled(3, window->isIconifiable());
	setItemEnabled(4, window->isMaximizable());
	setItemEnabled(9, window->isClosable());
	setItemEnabled(10, true); //we should always be able to enable the tab

}

Windowmenu::~Windowmenu(void) {
	delete sendToMenu;
	delete sendGroupToMenu;
}

void Windowmenu::show(void) {
	if (isItemEnabled(2)) setItemSelected(2, window->isShaded());
	if (isItemEnabled(4)) setItemSelected(4, window->isMaximized());
	if (isItemEnabled(7)) setItemSelected(7, window->isStuck());

	Basemenu::show();
}

void Windowmenu::itemSelected(int button, unsigned int index) {
	BasemenuItem *item = find(index);

	switch (item->function()) {
	case BScreen::WINDOWSHADE:
		hide();

		window->shade();
		if (window->hasTab())
			window->getTab()->shade();
		break;

	case BScreen::WINDOWICONIFY:
		hide();
		window->iconify();
		break;

	case BScreen::WINDOWMAXIMIZE:
		hide();
		window->maximize((unsigned int) button);
		break;

	case BScreen::WINDOWCLOSE:
		hide();
		window->close();
		break;

	case BScreen::WINDOWRAISE:
		hide();
		if (window->hasTab())
			window->getTab()->raise(); //raise tabs
		screen->getWorkspace(window->getWorkspaceNumber())->raiseWindow(window);
		break;

	case BScreen::WINDOWLOWER:
		hide();
	 	screen->getWorkspace(window->getWorkspaceNumber())->lowerWindow(window);
		if (window->hasTab())
			window->getTab()->lower(); //lower tabs AND all it's windows
		break;

	case BScreen::WINDOWSTICK:
		hide();
		window->stick();
		break;

	case BScreen::WINDOWKILL:
		hide();
		XKillClient(screen->getBaseDisplay()->getXDisplay(),
								window->getClientWindow());
		break;
	case BScreen::WINDOWTAB:
		hide();
		window->setTab(!window->hasTab());
		break;
	}
}

void Windowmenu::reconfigure(void) {
	setItemEnabled(1, window->hasTitlebar());
	setItemEnabled(2, window->isIconifiable());
	setItemEnabled(3, window->isMaximizable());
	setItemEnabled(8, window->isClosable());

	sendToMenu->reconfigure();
	sendGroupToMenu->reconfigure();

	Basemenu::reconfigure();
}

Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu *w)
	: Basemenu(w->screen)
{
	windowmenu = w;

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();
	update();
}

void Windowmenu::SendtoWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2) return;

	if (index <= windowmenu->screen->getCount()) {

		// no need to send it to a workspace it already exist on
		if (index == windowmenu->screen->getCurrentWorkspaceID())
			return;

		// if the window is stuck then unstick it
		if (windowmenu->window->isStuck())
			windowmenu->window->stick();

		if (button == 1) { // send to workspace without changing workspace
			windowmenu->screen->sendToWorkspace(index,
				windowmenu->window, false);
		} else if (button == 2) { // send to workspace and change workspace
			windowmenu->screen->sendToWorkspace(index,
				windowmenu->window, true);
		}
	}

	hide();
}

void Windowmenu::SendtoWorkspacemenu::update(void) {
	unsigned int i, r = numberOfItems();

	if (numberOfItems() != 0) {
		for (i = 0; i < r; ++i)
			remove(0);
	}
	for (i = 0; i < windowmenu->screen->getCount(); ++i)
		insert(windowmenu->screen->getWorkspace(i)->name().c_str());

	Basemenu::update();
}

void Windowmenu::SendtoWorkspacemenu::show(void) {
	update();

	Basemenu::show();
}

void Windowmenu::SendGroupToWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2)
		return;

	if (index <= getWindowMenu()->screen->getCount()) {
		if (index == getWindowMenu()->screen->getCurrentWorkspaceID())
			return;
		if (getWindowMenu()->window->isStuck())
			getWindowMenu()->window->stick();

		if (button == 1) {
			if (getWindowMenu()->window->hasTab()) {
				for (Tab *first = Tab::getFirst(getWindowMenu()->window->getTab());
						first!=0; first=first->next()) {
					first->withdraw();
					first->getWindow()->withdraw();
					getWindowMenu()->screen->reassociateWindow(first->getWindow(), index, True);

				}
			} else	{
				getWindowMenu()->window->withdraw();
				getWindowMenu()->screen->reassociateWindow(getWindowMenu()->window, index, True);
			}

		}

		if (button == 2)
			getWindowMenu()->screen->changeWorkspaceID(index);
	}
	hide();
}

Windowmenu::SendGroupToWorkspacemenu::SendGroupToWorkspacemenu(Windowmenu *w):SendtoWorkspacemenu(w)
{

}

<commit_msg>fixed checking on iconified when selecting item<commit_after>// Windowmenu.cc for Fluxbox
// Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org)
// Windowmenu.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Windowmenu.cc,v 1.16 2002/08/12 03:27:31 fluxgen Exp $

//use GNU extensions
#ifndef	 _GNU_SOURCE
#define	 _GNU_SOURCE
#endif // _GNU_SOURCE

#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif // HAVE_CONFIG_H

#include "i18n.hh"
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "Windowmenu.hh"
#include "Workspace.hh"

#ifdef STDC_HEADERS
#include <string.h>
#endif // STDC_HEADERS

Windowmenu::Windowmenu(FluxboxWindow *win) : Basemenu(win->getScreen()),
window(win),
screen(window->getScreen()){

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();

	I18n *i18n = I18n::instance();

	sendToMenu = new SendtoWorkspacemenu(this);
	sendGroupToMenu = new SendGroupToWorkspacemenu(this);
	using namespace FBNLS;
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendTo,
		"Send To ..."),
	 sendToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuSendGroupTo,
		"Send Group To ..."),
	sendGroupToMenu);

	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuShade,
		"Shade"),
	 BScreen::WINDOWSHADE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuIconify,
		"Iconify"),
	 BScreen::WINDOWICONIFY);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuMaximize,
		"Maximize"),
	 BScreen::WINDOWMAXIMIZE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuRaise,
		"Raise"),
	 BScreen::WINDOWRAISE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuLower,
		"Lower"),
	 BScreen::WINDOWLOWER);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuStick,
		"Stick"),
	 BScreen::WINDOWSTICK);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuKillClient,
		"Kill Client"),
	 BScreen::WINDOWKILL);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuClose,
		"Close"),
	 BScreen::WINDOWCLOSE);
	insert(i18n->getMessage(
		WindowmenuSet, WindowmenuTab,
		"Tab"),
	 BScreen::WINDOWTAB);

	update();

	setItemEnabled(2, window->hasTitlebar());
	setItemEnabled(3, window->isIconifiable());
	setItemEnabled(4, window->isMaximizable());
	setItemEnabled(9, window->isClosable());
	setItemEnabled(10, true); //we should always be able to enable the tab

}

Windowmenu::~Windowmenu(void) {
	delete sendToMenu;
	delete sendGroupToMenu;
}

void Windowmenu::show(void) {
	if (isItemEnabled(2)) setItemSelected(2, window->isShaded());
	if (isItemEnabled(4)) setItemSelected(4, window->isMaximized());
	if (isItemEnabled(7)) setItemSelected(7, window->isStuck());

	Basemenu::show();
}

void Windowmenu::itemSelected(int button, unsigned int index) {
	BasemenuItem *item = find(index);
	hide();
	switch (item->function()) {
	case BScreen::WINDOWSHADE:
		if (window->isIconic())
			break;

		window->shade();
		if (window->hasTab())
			window->getTab()->shade();
	break;

	case BScreen::WINDOWICONIFY:
		if (!window->isIconic())
			window->iconify();
		else
			window->deiconify(); // restore window

	break;

	case BScreen::WINDOWMAXIMIZE:
		window->maximize((unsigned int) button);
	break;

	case BScreen::WINDOWCLOSE:
		window->close();
	break;

	case BScreen::WINDOWRAISE:
		if (window->isIconic())
			break;

		if (window->hasTab())
			window->getTab()->raise(); //raise tabs
		screen->getWorkspace(window->getWorkspaceNumber())->raiseWindow(window);
	break;

	case BScreen::WINDOWLOWER:
	 	if (window->isIconic())
			break;

		screen->getWorkspace(window->getWorkspaceNumber())->lowerWindow(window);
		if (window->hasTab())
			window->getTab()->lower(); //lower tabs AND all it's windows
		break;

	case BScreen::WINDOWSTICK:
		window->stick();
		break;

	case BScreen::WINDOWKILL:
		XKillClient(screen->getBaseDisplay()->getXDisplay(),
								window->getClientWindow());
		break;
	case BScreen::WINDOWTAB:
		window->setTab(!window->hasTab());
		break;
	}
}

void Windowmenu::reconfigure(void) {
	setItemEnabled(1, window->hasTitlebar());
	setItemEnabled(2, window->isIconifiable());
	setItemEnabled(3, window->isMaximizable());
	setItemEnabled(8, window->isClosable());

	sendToMenu->reconfigure();
	sendGroupToMenu->reconfigure();

	Basemenu::reconfigure();
}

Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu *w)
	: Basemenu(w->screen)
{
	windowmenu = w;

	setTitleVisibility(False);
	setMovable(False);
	setInternalMenu();
	update();
}

void Windowmenu::SendtoWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2) return;

	if (index <= windowmenu->screen->getCount()) {

		// no need to send it to a workspace it already exist on
		if (index == windowmenu->screen->getCurrentWorkspaceID())
			return;

		// if the window is stuck then unstick it
		if (windowmenu->window->isStuck())
			windowmenu->window->stick();

		if (button == 1) { // send to workspace without changing workspace
			windowmenu->screen->sendToWorkspace(index,
				windowmenu->window, false);
		} else if (button == 2) { // send to workspace and change workspace
			windowmenu->screen->sendToWorkspace(index,
				windowmenu->window, true);
		}
	}

	hide();
}

void Windowmenu::SendtoWorkspacemenu::update(void) {
	unsigned int i, r = numberOfItems();

	if (numberOfItems() != 0) {
		for (i = 0; i < r; ++i)
			remove(0);
	}
	for (i = 0; i < windowmenu->screen->getCount(); ++i)
		insert(windowmenu->screen->getWorkspace(i)->name().c_str());

	Basemenu::update();
}

void Windowmenu::SendtoWorkspacemenu::show(void) {
	update();

	Basemenu::show();
}

void Windowmenu::SendGroupToWorkspacemenu::itemSelected(int button, unsigned int index) {
	if (button > 2)
		return;

	if (index <= getWindowMenu()->screen->getCount()) {
		if (index == getWindowMenu()->screen->getCurrentWorkspaceID())
			return;
		if (getWindowMenu()->window->isStuck())
			getWindowMenu()->window->stick();

		if (button == 1) {
			if (getWindowMenu()->window->hasTab()) {
				for (Tab *first = Tab::getFirst(getWindowMenu()->window->getTab());
						first!=0; first=first->next()) {
					first->withdraw();
					first->getWindow()->withdraw();
					getWindowMenu()->screen->reassociateWindow(first->getWindow(), index, True);

				}
			} else	{
				getWindowMenu()->window->withdraw();
				getWindowMenu()->screen->reassociateWindow(getWindowMenu()->window, index, True);
			}

		}

		if (button == 2)
			getWindowMenu()->screen->changeWorkspaceID(index);
	}
	hide();
}

Windowmenu::SendGroupToWorkspacemenu::SendGroupToWorkspacemenu(Windowmenu *w):SendtoWorkspacemenu(w)
{

}

<|endoftext|>


<commit_before>#include <pybind11/pybind11.h>

#include "encoder/encoder_sample.h"
#include "clustering/cpp_implemented_clustering_sample.h"

namespace py = pybind11;

PYBIND11_PLUGIN(_pqkmeans) {
    py::module m("_pqkemeans", "internal module for PQk-means");

    py::class_<EncoderSample>(m, "EncoderSample")
            .def(py::init<>())
            .def("fit_generator", &EncoderSample::fit_generator)
            .def("transform_one", &EncoderSample::transform_one)
            .def("inverse_transform_one", &EncoderSample::inverse_transform_one);

    py::class_<CppImplementedClusteringSample>(m, "CppImplementedClusteringSample")
            .def(py::init<>())
            .def("fit_one", &CppImplementedClusteringSample::fit_one)
            .def("predict_one", &CppImplementedClusteringSample::predict_one);

    return m.ptr();
}<commit_msg>:art: new style pybind<commit_after>#include <pybind11/pybind11.h>

#include "encoder/encoder_sample.h"
#include "clustering/cpp_implemented_clustering_sample.h"

namespace py = pybind11;

PYBIND11_MODULE(_pqkmeans, m) {
    py::class_<EncoderSample>(m, "EncoderSample")
            .def(py::init<>())
            .def("fit_generator", &EncoderSample::fit_generator)
            .def("transform_one", &EncoderSample::transform_one)
            .def("inverse_transform_one", &EncoderSample::inverse_transform_one);

    py::class_<CppImplementedClusteringSample>(m, "CppImplementedClusteringSample")
            .def(py::init<>())
            .def("fit_one", &CppImplementedClusteringSample::fit_one)
            .def("predict_one", &CppImplementedClusteringSample::predict_one);
}<|endoftext|>