<commit_before>
#include "../../Flare.h"
#include "FlareSpacecraftInfo.h"
#include "../../Player/FlarePlayerController.h"

#define LOCTEXT_NAMESPACE "FlareSpacecraftInfo"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareSpacecraftInfo::Construct(const FArguments& InArgs)
{
	// Data
	PC = InArgs._Player;
	NoInspect = InArgs._NoInspect;
	Minimized = InArgs._Minimized;
	AFlareGame* Game = InArgs._Player->GetGame();
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	// Create the layout
	ChildSlot
	.VAlign(VAlign_Top)
	.HAlign(HAlign_Left)
	[
		SNew(SVerticalBox)

		// Header container
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SBox)
			.WidthOverride(Theme.ContentWidth)
			[
				SNew(SHorizontalBox)

				// Data block
				+ SHorizontalBox::Slot()
				[
					SNew(SVerticalBox)

					// Main line
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SNew(SHorizontalBox)

						// Class icon
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						.VAlign(VAlign_Center)
						[
							SNew(SImage).Image(this, &SFlareSpacecraftInfo::GetClassIcon)
						]

						// Ship name
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(10))
						.VAlign(VAlign_Center)
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetName)
							.TextStyle(&Theme.NameFont)
						]

						// Ship class
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(12))
						.VAlign(VAlign_Center)
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetDescription)
							.TextStyle(&Theme.TextFont)
						]

						// Status
						+ SHorizontalBox::Slot()
						.HAlign(HAlign_Right)
						[
							SAssignNew(ShipStatus, SFlareShipStatus)
						]
					]

					// Company line
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SNew(SHorizontalBox)

						// Company flag
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						[
							SAssignNew(CompanyFlag, SFlareCompanyFlag)
							.Player(InArgs._Player)
						]

						// Company name
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetCompanyName)
							.TextStyle(&Theme.TextFont)
						]
					]

					// Cargo bay block
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SAssignNew(CargoBay, SVerticalBox)
					]
				]

				// Icon
				+ SHorizontalBox::Slot()
				.AutoWidth()
				.HAlign(HAlign_Right)
				[
					SNew(SImage).Image(this, &SFlareSpacecraftInfo::GetIcon)
					.Visibility(InArgs._NoInspect ? EVisibility::Hidden : EVisibility::Visible)
				]
			]
		]

		// General purpose container 1 (full, can always have 3 buttons)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SHorizontalBox)

			// Inspect
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(InspectButton, SFlareButton)
				.Text(LOCTEXT("Inspect", "INSPECT"))
				.HelpText(LOCTEXT("InspectInfo", "Take a closer look at this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnInspect)
				.Width(4)
			]

			// Fly this ship
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(FlyButton, SFlareButton)
				.Text(LOCTEXT("ShipFly", "FLY"))
				.HelpText(LOCTEXT("ShipFlyInfo", "Take command of this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnFly)
				.Width(4)
			]

			// Select this ship
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(SelectButton, SFlareButton)
				.Text(LOCTEXT("ShipSelect", "SELECT"))
				.HelpText(LOCTEXT("ShipSelectInfo", "Select this ship"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnSelect)
				.Width(4)
			]

			// Dock here
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(DockButton, SFlareButton)
				.Text(LOCTEXT("Dock", "DOCK HERE"))
				.HelpText(LOCTEXT("DockInfo", "Try to dock at this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnDockAt)
				.Width(4)
			]

			// Undock
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(UndockButton, SFlareButton)
				.Text(LOCTEXT("Undock", "UNDOCK"))
				.HelpText(LOCTEXT("UndockInfo", "Undock from this spacecraft and go back to flying the ship"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnUndock)
				.Width(4)
			]
		]

		// General purpose container (not full)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SHorizontalBox)

			// Trade
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(TradeButton, SFlareButton)
				.Text(LOCTEXT("Trade", "TRADE"))
				.HelpText(LOCTEXT("TradeInfo", "Trade with this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnTrade)
				.Width(4)
			]
		]
	];

	// Setup
	if (InArgs._Spacecraft)
	{
		SetSpacecraft(InArgs._Spacecraft);
	}
	if (InArgs._Visible && TargetSpacecraft)
	{
		Show();
	}
	else
	{
		Hide();
	}
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareSpacecraftInfo::SetSpacecraft(IFlareSpacecraftInterface* Target)
{
	TargetSpacecraft = Target;
	ShipStatus->SetTargetShip(Target);

	// Get the save data info to retrieve the class data
	if (Target && PC)
	{
		CompanyFlag->SetCompany(Target->GetCompany());
		TargetName = Target->GetImmatriculation().ToString();
		FFlareSpacecraftSave* SaveData = Target->Save();
		if (SaveData)
		{
			TargetSpacecraftDesc = PC->GetGame()->GetSpacecraftCatalog()->Get(SaveData->Identifier);
		}

		CargoBay->ClearChildren();
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(Target);

		if (SimulatedSpacecraft)
		{
			const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

			TArray<FFlareCargo>& SpacecraftCargoBay = SimulatedSpacecraft->GetCargoBay();
			for (int CargoIndex = 0; CargoIndex < SpacecraftCargoBay.Num() ; CargoIndex++)
			{
				FFlareCargo* Cargo = &SpacecraftCargoBay[CargoIndex];
				FString ResourceString = FString::Printf(TEXT("- %s (%u/%u)"), (Cargo->Resource ? *Cargo->Resource->Name.ToString() : TEXT("[Empty]")), Cargo->Quantity, Cargo->Capacity);

				CargoBay->AddSlot()
				[
					SNew(STextBlock)
					.TextStyle(&Theme.TextFont)
					.Text(FText::FromString(ResourceString))
				];
			}
		}
	}
}

void SFlareSpacecraftInfo::SetNoInspect(bool NewState)
{
	NoInspect = NewState;
}

void SFlareSpacecraftInfo::SetMinimized(bool NewState)
{
	Minimized = NewState;

	if (GetVisibility() == EVisibility::Visible)
	{
		Show();
	}
}

void SFlareSpacecraftInfo::Show()
{
	SetVisibility(EVisibility::Visible);

	if (Minimized)
	{
		InspectButton->SetVisibility(EVisibility::Collapsed);
		TradeButton->SetVisibility(EVisibility::Collapsed);
		FlyButton->SetVisibility(EVisibility::Collapsed);
		SelectButton->SetVisibility(EVisibility::Collapsed);
		DockButton->SetVisibility(EVisibility::Collapsed);
		UndockButton->SetVisibility(EVisibility::Collapsed);
	}
	else if (TargetSpacecraft)
	{
		// Useful data
		IFlareSpacecraftDockingSystemInterface* TargetDockingSystem = TargetSpacecraft->GetDockingSystem();
		bool OwnedAndNotSelf = TargetSpacecraft != PC->GetShipPawn() && TargetSpacecraft->GetCompany()->GetPlayerHostility() == EFlareHostility::Owned;
		bool IsDocked = TargetDockingSystem->IsDockedShip(PC->GetShipPawn());
		bool CanDock = OwnedAndNotSelf && TargetDockingSystem->HasCompatibleDock(PC->GetShipPawn()) && !IsDocked;
		bool CanTrade = OwnedAndNotSelf && !TargetSpacecraft->IsStation();

		// Button states
		InspectButton->SetVisibility(NoInspect ? EVisibility::Collapsed : EVisibility::Visible);
		TradeButton->SetVisibility(CanTrade ? EVisibility::Visible : EVisibility::Collapsed);
		DockButton->SetVisibility(CanDock ? EVisibility::Visible : EVisibility::Collapsed);
		UndockButton->SetVisibility(IsDocked ? EVisibility::Visible : EVisibility::Collapsed);

		// Flyable ships
		if (OwnedAndNotSelf && TargetSpacecraft->CanBeFlown())
		{
			FlyButton->SetVisibility(EVisibility::Visible);
			SelectButton->SetVisibility(EVisibility::Visible);
		}
		else
		{
			FlyButton->SetVisibility(EVisibility::Collapsed);
			SelectButton->SetVisibility(EVisibility::Collapsed);
		}
	}
}

void SFlareSpacecraftInfo::Hide()
{
	TargetSpacecraft = NULL;
	TargetSpacecraftDesc = NULL;
	SetVisibility(EVisibility::Collapsed);
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareSpacecraftInfo::OnInspect()
{
	if (PC && TargetSpacecraft)
	{
		FLOGV("OnInspect OpenMenu TargetSpacecraft=%p", TargetSpacecraft);
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);
		if(SimulatedSpacecraft)
		{
			FLOGV("Is UFlareSimulatedSpacecraft Immatriculation=%s parentSector=%p", *SimulatedSpacecraft->GetImmatriculation().ToString(), SimulatedSpacecraft->GetCurrentSector());
		}

		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Ship, TargetSpacecraft);
	}
}

void SFlareSpacecraftInfo::OnTrade()
{
	if (PC && TargetSpacecraft)
	{
		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Trade, TargetSpacecraft);
	}
}

void SFlareSpacecraftInfo::OnFly()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->CanBeFlown())
	{
		// Check if a simulated spacecraft
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);

		if (SimulatedSpacecraft)
		{
			SimulatedSpacecraft->GetCurrentSector()->SetShipToFly(SimulatedSpacecraft);
			PC->GetGame()->ActivateSector(PC, SimulatedSpacecraft->GetCurrentSector());
		}
		else
		{
			PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_FlyShip, Cast<AFlareSpacecraft>(TargetSpacecraft));
		}
	}
}

void SFlareSpacecraftInfo::OnSelect()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->CanBeFlown())
	{
		// Check if a simulated spacecraft
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);

		if (!SimulatedSpacecraft)
		{
			SimulatedSpacecraft = PC->GetGame()->GetGameWorld()->FindSpacecraft(TargetSpacecraft->GetImmatriculation());
		}

		PC->SelectFleet(SimulatedSpacecraft->GetCurrentFleet());
		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Orbit);
	}
}

void SFlareSpacecraftInfo::OnDockAt()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->GetDockingSystem()->GetDockCount() > 0)
	{
		PC->GetShipPawn()->GetNavigationSystem()->DockAt(TargetSpacecraft);
		PC->GetMenuManager()->CloseMenu();
	}
}

void SFlareSpacecraftInfo::OnUndock()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->GetDockingSystem()->GetDockCount() > 0)
	{
		PC->GetShipPawn()->GetNavigationSystem()->Undock();
		PC->GetMenuManager()->CloseMenu();
	}
}

/*----------------------------------------------------
	Content
----------------------------------------------------*/

FText SFlareSpacecraftInfo::GetName() const
{
	return FText::FromString(TargetName);
}

FText SFlareSpacecraftInfo::GetDescription() const
{
	// Common text
	FText DefaultText = LOCTEXT("Default", "UNKNOWN OBJECT");

	// Description builder
	if (TargetSpacecraftDesc)
	{
		return FText::FromString("(" + TargetSpacecraftDesc->Name.ToString() + ")");
	}

	return DefaultText;
}

const FSlateBrush* SFlareSpacecraftInfo::GetIcon() const
{
	if (TargetSpacecraftDesc)
	{
		return &TargetSpacecraftDesc->MeshPreviewBrush;
	}
	return NULL;
}

const FSlateBrush* SFlareSpacecraftInfo::GetClassIcon() const
{
	if (TargetSpacecraftDesc)
	{
		return IFlareSpacecraftInterface::GetIcon(TargetSpacecraftDesc);
	}
	return NULL;
}

FText SFlareSpacecraftInfo::GetCompanyName() const
{
	if (TargetSpacecraft)
	{
		UFlareCompany* TargetCompany = TargetSpacecraft->GetCompany();

		if (TargetCompany)
		{
			return FText::FromString(LOCTEXT("OwnedBy", "Owned by ").ToString() + TargetCompany->GetShortInfoText().ToString());
		}
	}

	return FText();
}

#undef LOCTEXT_NAMESPACE
<commit_msg>Fixed menu rendering issues<commit_after>
#include "../../Flare.h"
#include "FlareSpacecraftInfo.h"
#include "../../Player/FlarePlayerController.h"

#define LOCTEXT_NAMESPACE "FlareSpacecraftInfo"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareSpacecraftInfo::Construct(const FArguments& InArgs)
{
	// Data
	PC = InArgs._Player;
	NoInspect = InArgs._NoInspect;
	Minimized = InArgs._Minimized;
	AFlareGame* Game = InArgs._Player->GetGame();
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	// Create the layout
	ChildSlot
	.VAlign(VAlign_Top)
	.HAlign(HAlign_Left)
	[
		SNew(SVerticalBox)

		// Header container
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SBox)
			.WidthOverride(Theme.ContentWidth)
			[
				SNew(SHorizontalBox)

				// Data block
				+ SHorizontalBox::Slot()
				[
					SNew(SVerticalBox)

					// Main line
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SNew(SHorizontalBox)

						// Class icon
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						.VAlign(VAlign_Center)
						[
							SNew(SImage).Image(this, &SFlareSpacecraftInfo::GetClassIcon)
						]

						// Ship name
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(10))
						.VAlign(VAlign_Center)
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetName)
							.TextStyle(&Theme.NameFont)
						]

						// Ship class
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(12))
						.VAlign(VAlign_Center)
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetDescription)
							.TextStyle(&Theme.TextFont)
						]

						// Status
						+ SHorizontalBox::Slot()
						.HAlign(HAlign_Right)
						[
							SAssignNew(ShipStatus, SFlareShipStatus)
						]
					]

					// Company line
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SNew(SHorizontalBox)

						// Company flag
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						[
							SAssignNew(CompanyFlag, SFlareCompanyFlag)
							.Player(InArgs._Player)
						]

						// Company name
						+ SHorizontalBox::Slot()
						.AutoWidth()
						.Padding(FMargin(8))
						[
							SNew(STextBlock)
							.Text(this, &SFlareSpacecraftInfo::GetCompanyName)
							.TextStyle(&Theme.TextFont)
						]
					]

					// Cargo bay block
					+ SVerticalBox::Slot()
					.AutoHeight()
					[
						SAssignNew(CargoBay, SVerticalBox)
					]
				]

				// Icon
				+ SHorizontalBox::Slot()
				.AutoWidth()
				.HAlign(HAlign_Right)
				.VAlign(VAlign_Top)
				[
					SNew(SImage).Image(this, &SFlareSpacecraftInfo::GetIcon)
					.Visibility(InArgs._NoInspect ? EVisibility::Hidden : EVisibility::Visible)
				]
			]
		]

		// General purpose container 1 (full, can always have 3 buttons)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SHorizontalBox)

			// Inspect
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(InspectButton, SFlareButton)
				.Text(LOCTEXT("Inspect", "INSPECT"))
				.HelpText(LOCTEXT("InspectInfo", "Take a closer look at this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnInspect)
				.Width(4)
			]

			// Fly this ship
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(FlyButton, SFlareButton)
				.Text(LOCTEXT("ShipFly", "FLY"))
				.HelpText(LOCTEXT("ShipFlyInfo", "Take command of this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnFly)
				.Width(4)
			]

			// Select this ship
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(SelectButton, SFlareButton)
				.Text(LOCTEXT("ShipSelect", "SELECT"))
				.HelpText(LOCTEXT("ShipSelectInfo", "Select this ship"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnSelect)
				.Width(4)
			]

			// Dock here
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(DockButton, SFlareButton)
				.Text(LOCTEXT("Dock", "DOCK HERE"))
				.HelpText(LOCTEXT("DockInfo", "Try to dock at this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnDockAt)
				.Width(4)
			]

			// Undock
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(UndockButton, SFlareButton)
				.Text(LOCTEXT("Undock", "UNDOCK"))
				.HelpText(LOCTEXT("UndockInfo", "Undock from this spacecraft and go back to flying the ship"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnUndock)
				.Width(4)
			]
		]

		// General purpose container (not full)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SHorizontalBox)

			// Trade
			+ SHorizontalBox::Slot()
			.AutoWidth()
			[
				SAssignNew(TradeButton, SFlareButton)
				.Text(LOCTEXT("Trade", "TRADE"))
				.HelpText(LOCTEXT("TradeInfo", "Trade with this spacecraft"))
				.OnClicked(this, &SFlareSpacecraftInfo::OnTrade)
				.Width(4)
			]
		]
	];

	// Setup
	if (InArgs._Spacecraft)
	{
		SetSpacecraft(InArgs._Spacecraft);
	}
	if (InArgs._Visible && TargetSpacecraft)
	{
		Show();
	}
	else
	{
		Hide();
	}
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareSpacecraftInfo::SetSpacecraft(IFlareSpacecraftInterface* Target)
{
	TargetSpacecraft = Target;
	ShipStatus->SetTargetShip(Target);

	// Get the save data info to retrieve the class data
	if (Target && PC)
	{
		CompanyFlag->SetCompany(Target->GetCompany());
		TargetName = Target->GetImmatriculation().ToString();
		FFlareSpacecraftSave* SaveData = Target->Save();
		if (SaveData)
		{
			TargetSpacecraftDesc = PC->GetGame()->GetSpacecraftCatalog()->Get(SaveData->Identifier);
		}

		CargoBay->ClearChildren();
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(Target);

		if (SimulatedSpacecraft)
		{
			const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

			TArray<FFlareCargo>& SpacecraftCargoBay = SimulatedSpacecraft->GetCargoBay();
			for (int CargoIndex = 0; CargoIndex < SpacecraftCargoBay.Num() ; CargoIndex++)
			{
				FFlareCargo* Cargo = &SpacecraftCargoBay[CargoIndex];
				FString ResourceString = FString::Printf(TEXT("- %s (%u/%u)"), (Cargo->Resource ? *Cargo->Resource->Name.ToString() : TEXT("[Empty]")), Cargo->Quantity, Cargo->Capacity);

				CargoBay->AddSlot()
				[
					SNew(STextBlock)
					.TextStyle(&Theme.TextFont)
					.Text(FText::FromString(ResourceString))
				];
			}
		}
	}
}

void SFlareSpacecraftInfo::SetNoInspect(bool NewState)
{
	NoInspect = NewState;
}

void SFlareSpacecraftInfo::SetMinimized(bool NewState)
{
	Minimized = NewState;

	if (GetVisibility() == EVisibility::Visible)
	{
		Show();
	}
}

void SFlareSpacecraftInfo::Show()
{
	SetVisibility(EVisibility::Visible);

	if (Minimized)
	{
		InspectButton->SetVisibility(EVisibility::Collapsed);
		TradeButton->SetVisibility(EVisibility::Collapsed);
		FlyButton->SetVisibility(EVisibility::Collapsed);
		SelectButton->SetVisibility(EVisibility::Collapsed);
		DockButton->SetVisibility(EVisibility::Collapsed);
		UndockButton->SetVisibility(EVisibility::Collapsed);
	}
	else if (TargetSpacecraft)
	{
		// Useful data
		IFlareSpacecraftDockingSystemInterface* TargetDockingSystem = TargetSpacecraft->GetDockingSystem();
		bool OwnedAndNotSelf = TargetSpacecraft != PC->GetShipPawn() && TargetSpacecraft->GetCompany()->GetPlayerHostility() == EFlareHostility::Owned;
		bool IsDocked = TargetDockingSystem->IsDockedShip(PC->GetShipPawn());
		bool CanDock = OwnedAndNotSelf && TargetDockingSystem->HasCompatibleDock(PC->GetShipPawn()) && !IsDocked;
		bool CanTrade = OwnedAndNotSelf && !TargetSpacecraft->IsStation();

		// Button states
		InspectButton->SetVisibility(NoInspect ? EVisibility::Collapsed : EVisibility::Visible);
		TradeButton->SetVisibility(CanTrade ? EVisibility::Visible : EVisibility::Collapsed);
		DockButton->SetVisibility(CanDock ? EVisibility::Visible : EVisibility::Collapsed);
		UndockButton->SetVisibility(IsDocked ? EVisibility::Visible : EVisibility::Collapsed);

		// Flyable ships
		if (OwnedAndNotSelf && TargetSpacecraft->CanBeFlown())
		{
			FlyButton->SetVisibility(EVisibility::Visible);
			SelectButton->SetVisibility(EVisibility::Visible);
		}
		else
		{
			FlyButton->SetVisibility(EVisibility::Collapsed);
			SelectButton->SetVisibility(EVisibility::Collapsed);
		}
	}
}

void SFlareSpacecraftInfo::Hide()
{
	TargetSpacecraft = NULL;
	TargetSpacecraftDesc = NULL;
	SetVisibility(EVisibility::Collapsed);
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

void SFlareSpacecraftInfo::OnInspect()
{
	if (PC && TargetSpacecraft)
	{
		FLOGV("OnInspect OpenMenu TargetSpacecraft=%p", TargetSpacecraft);
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);
		if(SimulatedSpacecraft)
		{
			FLOGV("Is UFlareSimulatedSpacecraft Immatriculation=%s parentSector=%p", *SimulatedSpacecraft->GetImmatriculation().ToString(), SimulatedSpacecraft->GetCurrentSector());
		}

		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Ship, TargetSpacecraft);
	}
}

void SFlareSpacecraftInfo::OnTrade()
{
	if (PC && TargetSpacecraft)
	{
		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Trade, TargetSpacecraft);
	}
}

void SFlareSpacecraftInfo::OnFly()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->CanBeFlown())
	{
		// Check if a simulated spacecraft
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);

		if (SimulatedSpacecraft)
		{
			SimulatedSpacecraft->GetCurrentSector()->SetShipToFly(SimulatedSpacecraft);
			PC->GetGame()->ActivateSector(PC, SimulatedSpacecraft->GetCurrentSector());
		}
		else
		{
			PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_FlyShip, Cast<AFlareSpacecraft>(TargetSpacecraft));
		}
	}
}

void SFlareSpacecraftInfo::OnSelect()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->CanBeFlown())
	{
		// Check if a simulated spacecraft
		UFlareSimulatedSpacecraft* SimulatedSpacecraft = Cast<UFlareSimulatedSpacecraft>(TargetSpacecraft);

		if (!SimulatedSpacecraft)
		{
			SimulatedSpacecraft = PC->GetGame()->GetGameWorld()->FindSpacecraft(TargetSpacecraft->GetImmatriculation());
		}

		PC->SelectFleet(SimulatedSpacecraft->GetCurrentFleet());
		PC->GetMenuManager()->OpenMenu(EFlareMenu::MENU_Orbit);
	}
}

void SFlareSpacecraftInfo::OnDockAt()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->GetDockingSystem()->GetDockCount() > 0)
	{
		PC->GetShipPawn()->GetNavigationSystem()->DockAt(TargetSpacecraft);
		PC->GetMenuManager()->CloseMenu();
	}
}

void SFlareSpacecraftInfo::OnUndock()
{
	if (PC && TargetSpacecraft && TargetSpacecraft->GetDockingSystem()->GetDockCount() > 0)
	{
		PC->GetShipPawn()->GetNavigationSystem()->Undock();
		PC->GetMenuManager()->CloseMenu();
	}
}

/*----------------------------------------------------
	Content
----------------------------------------------------*/

FText SFlareSpacecraftInfo::GetName() const
{
	return FText::FromString(TargetName);
}

FText SFlareSpacecraftInfo::GetDescription() const
{
	// Common text
	FText DefaultText = LOCTEXT("Default", "UNKNOWN OBJECT");

	// Description builder
	if (TargetSpacecraftDesc)
	{
		return FText::FromString("(" + TargetSpacecraftDesc->Name.ToString() + ")");
	}

	return DefaultText;
}

const FSlateBrush* SFlareSpacecraftInfo::GetIcon() const
{
	if (TargetSpacecraftDesc)
	{
		return &TargetSpacecraftDesc->MeshPreviewBrush;
	}
	return NULL;
}

const FSlateBrush* SFlareSpacecraftInfo::GetClassIcon() const
{
	if (TargetSpacecraftDesc)
	{
		return IFlareSpacecraftInterface::GetIcon(TargetSpacecraftDesc);
	}
	return NULL;
}

FText SFlareSpacecraftInfo::GetCompanyName() const
{
	if (TargetSpacecraft)
	{
		UFlareCompany* TargetCompany = TargetSpacecraft->GetCompany();

		if (TargetCompany)
		{
			return FText::FromString(LOCTEXT("OwnedBy", "Owned by ").ToString() + TargetCompany->GetShortInfoText().ToString());
		}
	}

	return FText();
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>


<commit_before>// Copyright 2014 Vladimir Alyamkin. All Rights Reserved.

#include "VaOceanPluginPrivatePCH.h"
#include "VaOceanStateActor.h"

AVaOceanStateActor::AVaOceanStateActor(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
#if WITH_EDITORONLY_DATA
	// Structure to hold one-time initialization
	struct FConstructorStatics
	{
		// A helper class object we use to find target UTexture2D object in resource package
		ConstructorHelpers::FObjectFinderOptional<UTexture2D> NoteTextureObject;

		// Icon sprite category name
		FName ID_Notes;

		// Icon sprite display name
		FText NAME_Notes;

		FConstructorStatics()
			// Use helper class object to find the texture
			// "/Engine/EditorResources/S_Note" is resource path
			: NoteTextureObject(TEXT("/Engine/EditorResources/S_Note"))
			, ID_Notes(TEXT("Notes"))
			, NAME_Notes(NSLOCTEXT("SpriteCategory", "Notes", "Notes"))
		{
		}
	};
	static FConstructorStatics ConstructorStatics;
#endif // WITH_EDITORONLY_DATA

	// We need a scene component to attach Icon sprite
	TSubobjectPtr<USceneComponent> SceneComponent = PCIP.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComp"));
	RootComponent = SceneComponent;
	RootComponent->Mobility = EComponentMobility::Static;

#if WITH_EDITORONLY_DATA
	SpriteComponent = PCIP.CreateEditorOnlyDefaultSubobject<UBillboardComponent>(this, TEXT("Sprite"));
	if (SpriteComponent)
	{
		SpriteComponent->Sprite = ConstructorStatics.NoteTextureObject.Get();		// Get the sprite texture from helper class object
		SpriteComponent->SpriteInfo.Category = ConstructorStatics.ID_Notes;			// Assign sprite category name
		SpriteComponent->SpriteInfo.DisplayName = ConstructorStatics.NAME_Notes;	// Assign sprite display name
		SpriteComponent->AttachParent = RootComponent;								// Attach sprite to scene component
		SpriteComponent->Mobility = EComponentMobility::Static;
	}
#endif // WITH_EDITORONLY_DATA

	OceanSimulator = NULL;

	// Enable to see debug spheres
	//PrimaryActorTick.bCanEverTick = true;
}

void AVaOceanStateActor::PreInitializeComponents()
{
	OceanSimulator = FindComponentByClass<UVaOceanSimulatorComponent>();

	Super::PreInitializeComponents();
}

void AVaOceanStateActor::PostInitializeComponents()
{
	Super::PostInitializeComponents();
}

//////////////////////////////////////////////////////////////////////////
// Ocean state API

const FSpectrumData& AVaOceanStateActor::GetSpectrumConfig() const
{
	return SpectrumConfig;
}

float AVaOceanStateActor::GetOceanLevelAtLocation(FVector& Location) const
{
	// @TODO Get altitute from ocean simulation component

	if (OceanSimulator)
	{
		return OceanSimulator->GetOceanLevelAtLocation(Location);
	}

	return GetGlobalOceanLevel();
}

FLinearColor AVaOceanStateActor::GetOceanSurfaceNormal(FVector& Location) const
{
	// @TODO Get surface normals from ocean simulation component

	return FLinearColor::Blue;
}

FVector AVaOceanStateActor::GetOceanWaveVelocity(FVector& Location) const
{
	// @TODO Velocity should be calculated in ocean simulation component

	return FVector::UpVector;
}

int32 AVaOceanStateActor::GetOceanWavesNum() const
{
	return 1;
}

//////////////////////////////////////////////////////////////////////////
// Parameters access (get/set)

void AVaOceanStateActor::SetGlobalOceanLevel(float OceanLevel)
{
	GlobalOceanLevel = OceanLevel;
}

float AVaOceanStateActor::GetGlobalOceanLevel() const
{
	return GlobalOceanLevel;
}

void AVaOceanStateActor::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	// draw debug speheres
	/*for (int i = -5; i < 5; ++i)
	{
		for (int j = -5; j < 5; ++j)
		{
			FVector SpherePoint = FVector(250.0f * i, 250.0f * j, 0.0f);
			float OceanHeight = GetOceanLevelAtLocation(SpherePoint);
			DrawDebugSphere(GetWorld(), SpherePoint + (FVector::UpVector * OceanHeight), 10.0f, 4, FColor::White, false, -1.0f, 0);
		}
	}*/
}
<commit_msg>Can now move ocean with boat<commit_after>// Copyright 2014 Vladimir Alyamkin. All Rights Reserved.

#include "VaOceanPluginPrivatePCH.h"
#include "VaOceanStateActor.h"

AVaOceanStateActor::AVaOceanStateActor(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
#if WITH_EDITORONLY_DATA
	// Structure to hold one-time initialization
	struct FConstructorStatics
	{
		// A helper class object we use to find target UTexture2D object in resource package
		ConstructorHelpers::FObjectFinderOptional<UTexture2D> NoteTextureObject;

		// Icon sprite category name
		FName ID_Notes;

		// Icon sprite display name
		FText NAME_Notes;

		FConstructorStatics()
			// Use helper class object to find the texture
			// "/Engine/EditorResources/S_Note" is resource path
			: NoteTextureObject(TEXT("/Engine/EditorResources/S_Note"))
			, ID_Notes(TEXT("Notes"))
			, NAME_Notes(NSLOCTEXT("SpriteCategory", "Notes", "Notes"))
		{
		}
	};
	static FConstructorStatics ConstructorStatics;
#endif // WITH_EDITORONLY_DATA

	// We need a scene component to attach Icon sprite
	TSubobjectPtr<USceneComponent> SceneComponent = PCIP.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComp"));
	RootComponent = SceneComponent;
	RootComponent->Mobility = EComponentMobility::Movable;

#if WITH_EDITORONLY_DATA
	SpriteComponent = PCIP.CreateEditorOnlyDefaultSubobject<UBillboardComponent>(this, TEXT("Sprite"));
	if (SpriteComponent)
	{
		SpriteComponent->Sprite = ConstructorStatics.NoteTextureObject.Get();		// Get the sprite texture from helper class object
		SpriteComponent->SpriteInfo.Category = ConstructorStatics.ID_Notes;			// Assign sprite category name
		SpriteComponent->SpriteInfo.DisplayName = ConstructorStatics.NAME_Notes;	// Assign sprite display name
		SpriteComponent->AttachParent = RootComponent;								// Attach sprite to scene component
		SpriteComponent->Mobility = EComponentMobility::Static;
	}
#endif // WITH_EDITORONLY_DATA

	OceanSimulator = NULL;

	// Enable to see debug spheres
	PrimaryActorTick.bCanEverTick = true;
}

void AVaOceanStateActor::PreInitializeComponents()
{
	OceanSimulator = FindComponentByClass<UVaOceanSimulatorComponent>();

	Super::PreInitializeComponents();
}

void AVaOceanStateActor::PostInitializeComponents()
{
	Super::PostInitializeComponents();
}

//////////////////////////////////////////////////////////////////////////
// Ocean state API

const FSpectrumData& AVaOceanStateActor::GetSpectrumConfig() const
{
	return SpectrumConfig;
}

float AVaOceanStateActor::GetOceanLevelAtLocation(FVector& Location) const
{
	// @TODO Get altitute from ocean simulation component

	if (OceanSimulator)
	{
		return OceanSimulator->GetOceanLevelAtLocation(Location);
	}

	return GetGlobalOceanLevel();
}

FLinearColor AVaOceanStateActor::GetOceanSurfaceNormal(FVector& Location) const
{
	// @TODO Get surface normals from ocean simulation component

	return FLinearColor::Blue;
}

FVector AVaOceanStateActor::GetOceanWaveVelocity(FVector& Location) const
{
	// @TODO Velocity should be calculated in ocean simulation component

	return FVector::UpVector;
}

int32 AVaOceanStateActor::GetOceanWavesNum() const
{
	return 1;
}

//////////////////////////////////////////////////////////////////////////
// Parameters access (get/set)

void AVaOceanStateActor::SetGlobalOceanLevel(float OceanLevel)
{
	GlobalOceanLevel = OceanLevel;
}

float AVaOceanStateActor::GetGlobalOceanLevel() const
{
	return GlobalOceanLevel;
}

void AVaOceanStateActor::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	// draw debug speheres
	for (int i = -5; i < 5; ++i)
	{
		for (int j = -5; j < 5; ++j)
		{
			FVector SpherePoint = GetActorLocation() + FVector(250.0f * i, 250.0f * j, 0.0f);
			float OceanHeight = GetOceanLevelAtLocation(SpherePoint);
			DrawDebugSphere(GetWorld(), SpherePoint + (FVector::UpVector * OceanHeight), 10.0f, 4, FColor::White, false, -1.0f, 0);
		}
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT{
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,{
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "platform/scroll/ScrollbarThemeGtkOrAura.h"

#include "RuntimeEnabledFeatures.h"
#include "platform/LayoutTestSupport.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/scroll/ScrollbarThemeClient.h"
#include "platform/scroll/ScrollbarThemeOverlay.h"
#include "public/platform/Platform.h"
#include "public/platform/WebRect.h"
#include "public/platform/default/WebThemeEngine.h"

namespace WebCore {

static bool useMockTheme()
{
    return isRunningLayoutTest();
}

ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
    if (RuntimeEnabledFeatures::overlayScrollbarsEnabled()) {
        DEFINE_STATIC_LOCAL(ScrollbarThemeOverlay, theme, (10, 0, ScrollbarThemeOverlay::AllowHitTest, Color(128, 128, 128, 192)));
        return &theme;
    }

    DEFINE_STATIC_LOCAL(ScrollbarThemeGtkOrAura, theme, ());
    return &theme;
}

int ScrollbarThemeGtkOrAura::scrollbarThickness(ScrollbarControlSize controlSize)
{
    // Horiz and Vert scrollbars are the same thickness.
    IntSize scrollbarSize = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarVerticalTrack);
    return scrollbarSize.width();
}

void ScrollbarThemeGtkOrAura::paintTrackPiece(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
    blink::WebThemeEngine::State state = scrollbar->hoveredPart() == partType ? blink::WebThemeEngine::StateHover : blink::WebThemeEngine::StateNormal;

    if (useMockTheme() && !scrollbar->enabled())
        state = blink::WebThemeEngine::StateDisabled;

    IntRect alignRect = trackRect(scrollbar, false);
    blink::WebThemeEngine::ExtraParams extraParams;
    blink::WebCanvas* canvas = gc->canvas();
    extraParams.scrollbarTrack.isBack = (partType == BackTrackPart);
    extraParams.scrollbarTrack.trackX = alignRect.x();
    extraParams.scrollbarTrack.trackY = alignRect.y();
    extraParams.scrollbarTrack.trackWidth = alignRect.width();
    extraParams.scrollbarTrack.trackHeight = alignRect.height();
    blink::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? blink::WebThemeEngine::PartScrollbarHorizontalTrack : blink::WebThemeEngine::PartScrollbarVerticalTrack, state, blink::WebRect(rect), &extraParams);
}

void ScrollbarThemeGtkOrAura::paintButton(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
{
    blink::WebThemeEngine::Part paintPart;
    blink::WebThemeEngine::State state = blink::WebThemeEngine::StateNormal;
    blink::WebCanvas* canvas = gc->canvas();
    bool checkMin = false;
    bool checkMax = false;

    if (scrollbar->orientation() == HorizontalScrollbar) {
        if (part == BackButtonStartPart) {
            paintPart = blink::WebThemeEngine::PartScrollbarLeftArrow;
            checkMin = true;
        } else if (useMockTheme() && part != ForwardButtonEndPart) {
            return;
        } else {
            paintPart = blink::WebThemeEngine::PartScrollbarRightArrow;
            checkMax = true;
        }
    } else {
        if (part == BackButtonStartPart) {
            paintPart = blink::WebThemeEngine::PartScrollbarUpArrow;
            checkMin = true;
        } else if (useMockTheme() && part != ForwardButtonEndPart) {
            return;
        } else {
            paintPart = blink::WebThemeEngine::PartScrollbarDownArrow;
            checkMax = true;
        }
    }
    if (useMockTheme() && !scrollbar->enabled()) {
        state = blink::WebThemeEngine::StateDisabled;
    } else if (!useMockTheme() && ((checkMin && (scrollbar->currentPos() <= 0))
        || (checkMax && scrollbar->currentPos() == scrollbar->maximum()))) {
        state = blink::WebThemeEngine::StateDisabled;
    } else {
        if (part == scrollbar->pressedPart())
            state = blink::WebThemeEngine::StatePressed;
        else if (part == scrollbar->hoveredPart())
            state = blink::WebThemeEngine::StateHover;
    }
    blink::Platform::current()->themeEngine()->paint(canvas, paintPart, state, blink::WebRect(rect), 0);
}

void ScrollbarThemeGtkOrAura::paintThumb(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect)
{
    blink::WebThemeEngine::State state;
    blink::WebCanvas* canvas = gc->canvas();
    if (scrollbar->pressedPart() == ThumbPart)
        state = blink::WebThemeEngine::StatePressed;
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = blink::WebThemeEngine::StateHover;
    else
        state = blink::WebThemeEngine::StateNormal;
    blink::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? blink::WebThemeEngine::PartScrollbarHorizontalThumb : blink::WebThemeEngine::PartScrollbarVerticalThumb, state, blink::WebRect(rect), 0);
}

bool ScrollbarThemeGtkOrAura::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
{
    return (evt.shiftKey() && evt.button() == LeftButton) || (evt.button() == MiddleButton);
}

IntSize ScrollbarThemeGtkOrAura::buttonSize(ScrollbarThemeClient* scrollbar)
{
    if (scrollbar->orientation() == VerticalScrollbar) {
        IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarUpArrow);
        return IntSize(size.width(), scrollbar->height() < 2 * size.height() ? scrollbar->height() / 2 : size.height());
    }

    // HorizontalScrollbar
    IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarLeftArrow);
    return IntSize(scrollbar->width() < 2 * size.width() ? scrollbar->width() / 2 : size.width(), size.height());
}

int ScrollbarThemeGtkOrAura::minimumThumbLength(ScrollbarThemeClient* scrollbar)
{
    if (scrollbar->orientation() == VerticalScrollbar) {
        IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarVerticalThumb);
        return size.height();
    }

    IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarHorizontalThumb);
    return size.width();
}

} // namespace WebCore
<commit_msg>Hard codes ScrollbarThemeGtkOrAura::scrollbarThickness to 15 in layout test mode<commit_after>/*
 * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT{
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,{
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "platform/scroll/ScrollbarThemeGtkOrAura.h"

#include "RuntimeEnabledFeatures.h"
#include "platform/LayoutTestSupport.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/scroll/ScrollbarThemeClient.h"
#include "platform/scroll/ScrollbarThemeOverlay.h"
#include "public/platform/Platform.h"
#include "public/platform/WebRect.h"
#include "public/platform/default/WebThemeEngine.h"

namespace WebCore {

static bool useMockTheme()
{
    return isRunningLayoutTest();
}

ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
    if (RuntimeEnabledFeatures::overlayScrollbarsEnabled()) {
        DEFINE_STATIC_LOCAL(ScrollbarThemeOverlay, theme, (10, 0, ScrollbarThemeOverlay::AllowHitTest, Color(128, 128, 128, 192)));
        return &theme;
    }

    DEFINE_STATIC_LOCAL(ScrollbarThemeGtkOrAura, theme, ());
    return &theme;
}

int ScrollbarThemeGtkOrAura::scrollbarThickness(ScrollbarControlSize controlSize)
{
    // Horiz and Vert scrollbars are the same thickness.
    // In unit tests we don't have the mock theme engine (because of layering violations), so we hard code the size (see bug 327470).
    if (useMockTheme())
        return 15;
    IntSize scrollbarSize = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarVerticalTrack);
    return scrollbarSize.width();
}

void ScrollbarThemeGtkOrAura::paintTrackPiece(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
    blink::WebThemeEngine::State state = scrollbar->hoveredPart() == partType ? blink::WebThemeEngine::StateHover : blink::WebThemeEngine::StateNormal;

    if (useMockTheme() && !scrollbar->enabled())
        state = blink::WebThemeEngine::StateDisabled;

    IntRect alignRect = trackRect(scrollbar, false);
    blink::WebThemeEngine::ExtraParams extraParams;
    blink::WebCanvas* canvas = gc->canvas();
    extraParams.scrollbarTrack.isBack = (partType == BackTrackPart);
    extraParams.scrollbarTrack.trackX = alignRect.x();
    extraParams.scrollbarTrack.trackY = alignRect.y();
    extraParams.scrollbarTrack.trackWidth = alignRect.width();
    extraParams.scrollbarTrack.trackHeight = alignRect.height();
    blink::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? blink::WebThemeEngine::PartScrollbarHorizontalTrack : blink::WebThemeEngine::PartScrollbarVerticalTrack, state, blink::WebRect(rect), &extraParams);
}

void ScrollbarThemeGtkOrAura::paintButton(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
{
    blink::WebThemeEngine::Part paintPart;
    blink::WebThemeEngine::State state = blink::WebThemeEngine::StateNormal;
    blink::WebCanvas* canvas = gc->canvas();
    bool checkMin = false;
    bool checkMax = false;

    if (scrollbar->orientation() == HorizontalScrollbar) {
        if (part == BackButtonStartPart) {
            paintPart = blink::WebThemeEngine::PartScrollbarLeftArrow;
            checkMin = true;
        } else if (useMockTheme() && part != ForwardButtonEndPart) {
            return;
        } else {
            paintPart = blink::WebThemeEngine::PartScrollbarRightArrow;
            checkMax = true;
        }
    } else {
        if (part == BackButtonStartPart) {
            paintPart = blink::WebThemeEngine::PartScrollbarUpArrow;
            checkMin = true;
        } else if (useMockTheme() && part != ForwardButtonEndPart) {
            return;
        } else {
            paintPart = blink::WebThemeEngine::PartScrollbarDownArrow;
            checkMax = true;
        }
    }
    if (useMockTheme() && !scrollbar->enabled()) {
        state = blink::WebThemeEngine::StateDisabled;
    } else if (!useMockTheme() && ((checkMin && (scrollbar->currentPos() <= 0))
        || (checkMax && scrollbar->currentPos() == scrollbar->maximum()))) {
        state = blink::WebThemeEngine::StateDisabled;
    } else {
        if (part == scrollbar->pressedPart())
            state = blink::WebThemeEngine::StatePressed;
        else if (part == scrollbar->hoveredPart())
            state = blink::WebThemeEngine::StateHover;
    }
    blink::Platform::current()->themeEngine()->paint(canvas, paintPart, state, blink::WebRect(rect), 0);
}

void ScrollbarThemeGtkOrAura::paintThumb(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect)
{
    blink::WebThemeEngine::State state;
    blink::WebCanvas* canvas = gc->canvas();
    if (scrollbar->pressedPart() == ThumbPart)
        state = blink::WebThemeEngine::StatePressed;
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = blink::WebThemeEngine::StateHover;
    else
        state = blink::WebThemeEngine::StateNormal;
    blink::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? blink::WebThemeEngine::PartScrollbarHorizontalThumb : blink::WebThemeEngine::PartScrollbarVerticalThumb, state, blink::WebRect(rect), 0);
}

bool ScrollbarThemeGtkOrAura::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
{
    return (evt.shiftKey() && evt.button() == LeftButton) || (evt.button() == MiddleButton);
}

IntSize ScrollbarThemeGtkOrAura::buttonSize(ScrollbarThemeClient* scrollbar)
{
    if (scrollbar->orientation() == VerticalScrollbar) {
        IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarUpArrow);
        return IntSize(size.width(), scrollbar->height() < 2 * size.height() ? scrollbar->height() / 2 : size.height());
    }

    // HorizontalScrollbar
    IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarLeftArrow);
    return IntSize(scrollbar->width() < 2 * size.width() ? scrollbar->width() / 2 : size.width(), size.height());
}

int ScrollbarThemeGtkOrAura::minimumThumbLength(ScrollbarThemeClient* scrollbar)
{
    if (scrollbar->orientation() == VerticalScrollbar) {
        IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarVerticalThumb);
        return size.height();
    }

    IntSize size = blink::Platform::current()->themeEngine()->getSize(blink::WebThemeEngine::PartScrollbarHorizontalThumb);
    return size.width();
}

} // namespace WebCore
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_FUN_SQUARE_HPP
#define STAN_MATH_PRIM_FUN_SQUARE_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/functor/apply_scalar_unary.hpp>
#include <stan/math/prim/functor/apply_vector_unary.hpp>
#include <cmath>

namespace stan {
namespace math {

/**
 * Return the square of the specified argument.
 *
 *
\f$\mbox{square}(x) = x^2\f$.
 *
 *
The implementation of square(x) is just
 * x * x.  Given this, this method is mainly useful
 * in cases where x is not a simple primitive type,
 * particularly when it is an autodiff type.
 *
 * @param x Input to square.
 * @return Square of input.
 */
inline double square(double x) { return std::pow(x, 2); }

/**
 * Structure to wrap square() so that it can be vectorized.
 *
 * @tparam T type of variable
 * @param x variable
 * @return x squared.
 */
struct square_fun {
  template <typename T>
  static inline T fun(const T& x) {
    return square(x);
  }
};

/**
 * Vectorized version of square().
 *
 * @tparam Container type of container
 * @param x container
 * @return Each value in x squared.
 */
template <
    typename Container,
    require_not_stan_scalar_t<Container>* = nullptr,
    require_not_var_matrix_t<Container>* = nullptr,
    require_not_nonscalar_prim_or_rev_kernel_expression_t<Container>* = nullptr>
inline auto square(const Container& x) {
  return apply_scalar_unary<square_fun, Container>::apply(x);
}

/**
 * Version of square() that accepts std::vectors, Eigen Matrix/Array objects
 *  or expressions, and containers of these.
 *
 * @tparam Container Type of x
 * @param x Container
 * @return Each value in x squared.
 */
template <typename Container,
          require_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto square(const Container& x) {
  return apply_vector_unary<Container>::apply(
      x, [](const auto& v) { return v.array().square(); });
}

}  // namespace math
}  // namespace stan

#endif
<commit_msg>fix template for square<commit_after>#ifndef STAN_MATH_PRIM_FUN_SQUARE_HPP
#define STAN_MATH_PRIM_FUN_SQUARE_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/functor/apply_scalar_unary.hpp>
#include <stan/math/prim/functor/apply_vector_unary.hpp>
#include <cmath>

namespace stan {
namespace math {

/**
 * Return the square of the specified argument.
 *
 *
\f$\mbox{square}(x) = x^2\f$.
 *
 *
The implementation of square(x) is just
 * x * x.  Given this, this method is mainly useful
 * in cases where x is not a simple primitive type,
 * particularly when it is an autodiff type.
 *
 * @param x Input to square.
 * @return Square of input.
 */
inline double square(double x) { return std::pow(x, 2); }

/**
 * Structure to wrap square() so that it can be vectorized.
 *
 * @tparam T type of variable
 * @param x variable
 * @return x squared.
 */
struct square_fun {
  template <typename T>
  static inline T fun(const T& x) {
    return square(x);
  }
};

/**
 * Vectorized version of square().
 *
 * @tparam Container type of container
 * @param x container
 * @return Each value in x squared.
 */
template <
    typename Container,
    require_not_stan_scalar_t<Container>* = nullptr,
    require_not_container_st<std::is_arithmetic, Container>* = nullptr,
    require_not_var_matrix_t<Container>* = nullptr,
    require_not_nonscalar_prim_or_rev_kernel_expression_t<Container>* = nullptr>
inline auto square(const Container& x) {
  return apply_scalar_unary<square_fun, Container>::apply(x);
}

/**
 * Version of square() that accepts std::vectors, Eigen Matrix/Array objects
 *  or expressions, and containers of these.
 *
 * @tparam Container Type of x
 * @param x Container
 * @return Each value in x squared.
 */
template <typename Container,
          require_container_st<std::is_arithmetic, Container>* = nullptr>
inline auto square(const Container& x) {
  return apply_vector_unary<Container>::apply(
      x, [](const auto& v) { return v.array().square(); });
}

}  // namespace math
}  // namespace stan

#endif
<|endoftext|>


<commit_before>
#include "Assert.h"

#ifdef PLATFORM_WINDOWS

#include <cstdlib>
#include <memory>
#include <sstream>
#include <vector>
#include <stdio.h>

#include "Core/Debug/Debug.h"

// IDs
constexpr uint16 ID_BREAK = 110;
constexpr uint16 ID_IGNORE = 111;
constexpr uint16 ID_TERMINATE = 112;
constexpr uint16 ID_EDITABLE_TEXT = 113;
constexpr uint16 ID_DONT_CARE = 500;

// Styles
constexpr uint32 STYLE_ITEM = WS_CHILD | WS_VISIBLE;
constexpr uint32 STYLE_BUTTON = STYLE_ITEM | BS_PUSHBUTTON | BS_TEXT;
constexpr uint32 STYLE_DEFAULT_BUTTON = STYLE_ITEM | BS_DEFPUSHBUTTON | BS_TEXT;
constexpr uint32 STYLE_EDITABLE_TEXT = STYLE_ITEM | ES_LEFT | ES_READONLY | ES_MULTILINE | WS_VSCROLL | WS_BORDER;
constexpr uint32 STYLE_STATIC_TEXT = STYLE_ITEM;
constexpr uint32 STYLE_WHITE_RECT = STYLE_ITEM | SS_WHITERECT;
constexpr uint32 STYLE_ICON = STYLE_ITEM | SS_ICON;

// Class ordinal values
constexpr uint16 CLASS_BUTTON = 0x0080;
constexpr uint16 CLASS_EDIT = 0x0081;
constexpr uint16 CLASS_STATIC = 0x0082;

static void addButtonToDialog(void** buffer, size_t& space, int16 x, int16 y, WORD id, DWORD style, const wchar_t* text, uint32 textLength);
static void addEditableTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength);
static void addStaticTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength);
static void addWhiteRectToDialog(void** buffer, size_t& space, int16 x, int16 y);
static void addIconToDialog(void** buffer, size_t& space, int16 x, int16 y);

INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg)
	{
	case WM_CTLCOLORSTATIC: {
		if (GetDlgCtrlID((HWND)lParam) != ID_EDITABLE_TEXT) {
			HGDIOBJ whiteBrush = GetStockObject(WHITE_BRUSH);
			return (INT_PTR)whiteBrush;
		}
		break;
	}
	case WM_INITDIALOG: {
		MessageBeep(MB_ICONWARNING);
		break;
	}
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case ID_TERMINATE:
			[[fallthrough]];
		case ID_IGNORE:
			[[fallthrough]];
		case ID_BREAK:
			EndDialog(hwndDlg, wParam);
			return TRUE;
		}
		break;
	case WM_CLOSE:
		EndDialog(hwndDlg, ID_IGNORE);
		return TRUE;
	}
	return FALSE;
}

bool showAssertDialogWindows(const std::wstring& msg) {
	const static size_t BUFF_SIZE = 1024 * 5;

	// Init buffer
	HGLOBAL globalHandle = GlobalAlloc(GMEM_ZEROINIT, BUFF_SIZE);
	if (globalHandle == NULL) {
		return false;
	}

	void* buffer = nullptr;

	buffer = GlobalLock(globalHandle);

	if (buffer == nullptr) {
		return false;
	}

	// Define the dialogue box
	LPDLGTEMPLATE templatePtr = reinterpret_cast<LPDLGTEMPLATE>(buffer);
	templatePtr->style = WS_POPUP | WS_BORDER | DS_MODALFRAME | WS_CAPTION | DS_CENTER | WS_SYSMENU | DS_MODALFRAME | DS_SHELLFONT;
	templatePtr->cdit = 7;         // Number of controls
	templatePtr->x = 0;
	templatePtr->y = 0;
	templatePtr->cx = 350;
	templatePtr->cy = 250;
	templatePtr++;

	LPWORD wordPtr = reinterpret_cast<LPWORD>(templatePtr);
	*wordPtr++ = 0; // No menu
	*wordPtr++ = 0; // Predefined dialog box class (by default)

	LPWSTR wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
	memcpy(wideStringPtr, L"Open Game Framework", 20 * sizeof(wchar_t));
	wideStringPtr += 20;

	// Font
	wordPtr = reinterpret_cast<LPWORD>(wideStringPtr);
	*wordPtr++ = 8;

	wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
	memcpy(wideStringPtr, L"MS Shell Dlg", 13 * sizeof(wchar_t));
	wideStringPtr += 13;

	buffer = reinterpret_cast<void*>(wideStringPtr);

	// Calculate space left
	size_t space = BUFF_SIZE - sizeof(LPDLGTEMPLATE) - (20 * sizeof(wchar_t)) - (3 * sizeof(WORD));

	// Add buttons
	addButtonToDialog(&buffer, space, 5, 230, ID_IGNORE, STYLE_BUTTON, L"Ignore", 6);
	addButtonToDialog(&buffer, space, 60, 230, ID_BREAK, STYLE_BUTTON | (Debug::isDebuggerAttached() ? 0 : WS_DISABLED), L"Break", 5);
	addButtonToDialog(&buffer, space, 115, 230, ID_TERMINATE, STYLE_BUTTON, L"Terminate", 9);

	addWhiteRectToDialog(&buffer, space, 0, 0);
	addEditableTextToDialog(&buffer, space, 5, 45, msg.c_str(), msg.length());
	addIconToDialog(&buffer, space, 10, 10);
	addStaticTextToDialog(&buffer, space, 38, 18, L"Assertion Failed!", 17);

	// Display dialogue
	GlobalUnlock(globalHandle);

	INT_PTR retVal = DialogBoxIndirect(NULL, reinterpret_cast<LPDLGTEMPLATE>(globalHandle), NULL, (DLGPROC)DialogProc);

	// Cleanup
	GlobalFree(globalHandle);

	if (retVal == ID_TERMINATE) {
		std::exit(1);
	}

	return (retVal == ID_BREAK);
}

static void addDialogItem(void** buffer, size_t& space, int16 x, int16 y, int16 width, int16 height, WORD id, DWORD style, WORD classOrdinalValue, const wchar_t* title, uint32 titleLength) {
	const size_t itemSize = sizeof(DLGITEMTEMPLATE) + ((titleLength + 1) * sizeof(wchar_t)) + (sizeof(WORD) * 3);

	if (std::align(alignof(DWORD), itemSize, *buffer, space)) {
		LPDLGITEMTEMPLATE itemTemplatePtr = reinterpret_cast<LPDLGITEMTEMPLATE>(*buffer);
		itemTemplatePtr->x = x;
		itemTemplatePtr->y = y;
		itemTemplatePtr->cx = width;
		itemTemplatePtr->cy = height;
		itemTemplatePtr->id = id;
		itemTemplatePtr->style = style;
		itemTemplatePtr++;

		LPWORD wordPtr = reinterpret_cast<LPWORD>(itemTemplatePtr);
		*wordPtr++ = 0xFFFF;
		*wordPtr++ = classOrdinalValue;

		LPWSTR wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
		memcpy(wideStringPtr, title, (titleLength + 1) * sizeof(wchar_t));
		wideStringPtr += titleLength + 1;

		wordPtr = reinterpret_cast<LPWORD>(wideStringPtr);
		*wordPtr++ = 0;             // No creation data

		*buffer = reinterpret_cast<void*>(wordPtr);
	}
}

static void addButtonToDialog(void** buffer, size_t& space, int16 x, int16 y, WORD id, DWORD style, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 50, 14, id, style, CLASS_BUTTON, text, textLength);
}

static void addEditableTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 340, 165, ID_EDITABLE_TEXT, STYLE_EDITABLE_TEXT, CLASS_EDIT, text, textLength);
}

static void addStaticTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 100, 20, ID_DONT_CARE, STYLE_STATIC_TEXT, CLASS_STATIC, text, textLength);
}

static void addWhiteRectToDialog(void** buffer, size_t& space, int16 x, int16 y) {
	addDialogItem(buffer, space, x, y, 500, 220, ID_DONT_CARE, STYLE_WHITE_RECT, CLASS_STATIC, L"\0", 1);
}

static void addIconToDialog(void** buffer, size_t& space, int16 x, int16 y) {
	wchar_t iconStr[2] = { 0xFFFF, (WORD)IDI_WARNING };
	addDialogItem(buffer, space, x, y, SM_CXICON, SM_CYICON, ID_DONT_CARE, STYLE_ICON, CLASS_STATIC, iconStr, 1);
}

std::wstring formatAssertMessage(const char* fileName, uint32 lineNumber, const std::vector<string>& stackTrace, const char* msg, ...) {
	va_list args;
	va_start(args, msg);

	int32 bufferSize = _vscprintf(msg, args);
	if (bufferSize < 0)
	{
		// Error
		va_end(args);
		return std::wstring();
	}

	bufferSize++; // For terminating null character
	char* buffer = new char[bufferSize];
	int32 charsWritten = vsprintf_s(buffer, bufferSize, msg, args);
	if (charsWritten < 0)
	{
		// Error
		va_end(args);
		delete[] buffer;
		return std::wstring();
	}

	va_end(args);

	std::wstringstream sstream;
	sstream << L"File: " << fileName << "\r\n" << "Line: " << lineNumber << "\r\n\r\n" << buffer << "\r\n\r\n";
	for (const std::string& str : stackTrace) {
		sstream << str.c_str() << "\r\n";
	}

	delete[] buffer;
	return sstream.str();

}
#endif<commit_msg>Make ignore button default for assert dialog<commit_after>
#include "Assert.h"

#ifdef PLATFORM_WINDOWS

#include <cstdlib>
#include <memory>
#include <sstream>
#include <vector>
#include <stdio.h>

#include "Core/Debug/Debug.h"

// IDs
constexpr uint16 ID_BREAK = 110;
constexpr uint16 ID_IGNORE = 111;
constexpr uint16 ID_TERMINATE = 112;
constexpr uint16 ID_EDITABLE_TEXT = 113;
constexpr uint16 ID_DONT_CARE = 500;

// Styles
constexpr uint32 STYLE_ITEM = WS_CHILD | WS_VISIBLE;
constexpr uint32 STYLE_BUTTON = STYLE_ITEM | BS_PUSHBUTTON | BS_TEXT;
constexpr uint32 STYLE_DEFAULT_BUTTON = STYLE_ITEM | BS_DEFPUSHBUTTON | BS_TEXT;
constexpr uint32 STYLE_EDITABLE_TEXT = STYLE_ITEM | ES_LEFT | ES_READONLY | ES_MULTILINE | WS_VSCROLL | WS_BORDER;
constexpr uint32 STYLE_STATIC_TEXT = STYLE_ITEM;
constexpr uint32 STYLE_WHITE_RECT = STYLE_ITEM | SS_WHITERECT;
constexpr uint32 STYLE_ICON = STYLE_ITEM | SS_ICON;

// Class ordinal values
constexpr uint16 CLASS_BUTTON = 0x0080;
constexpr uint16 CLASS_EDIT = 0x0081;
constexpr uint16 CLASS_STATIC = 0x0082;

static void addButtonToDialog(void** buffer, size_t& space, int16 x, int16 y, WORD id, DWORD style, const wchar_t* text, uint32 textLength);
static void addEditableTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength);
static void addStaticTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength);
static void addWhiteRectToDialog(void** buffer, size_t& space, int16 x, int16 y);
static void addIconToDialog(void** buffer, size_t& space, int16 x, int16 y);

INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg)
	{
	case WM_CTLCOLORSTATIC: {
		if (GetDlgCtrlID((HWND)lParam) != ID_EDITABLE_TEXT) {
			HGDIOBJ whiteBrush = GetStockObject(WHITE_BRUSH);
			return (INT_PTR)whiteBrush;
		}
		break;
	}
	case WM_INITDIALOG: {
		MessageBeep(MB_ICONWARNING);
		break;
	}
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case ID_TERMINATE:
			[[fallthrough]];
		case ID_IGNORE:
			[[fallthrough]];
		case ID_BREAK:
			EndDialog(hwndDlg, wParam);
			return TRUE;
		}
		break;
	case WM_CLOSE:
		EndDialog(hwndDlg, ID_IGNORE);
		return TRUE;
	}
	return FALSE;
}

bool showAssertDialogWindows(const std::wstring& msg) {
	const static size_t BUFF_SIZE = 1024 * 5;

	// Init buffer
	HGLOBAL globalHandle = GlobalAlloc(GMEM_ZEROINIT, BUFF_SIZE);
	if (globalHandle == NULL) {
		return false;
	}

	void* buffer = nullptr;

	buffer = GlobalLock(globalHandle);

	if (buffer == nullptr) {
		return false;
	}

	// Define the dialogue box
	LPDLGTEMPLATE templatePtr = reinterpret_cast<LPDLGTEMPLATE>(buffer);
	templatePtr->style = WS_POPUP | WS_BORDER | DS_MODALFRAME | WS_CAPTION | DS_CENTER | WS_SYSMENU | DS_MODALFRAME | DS_SHELLFONT;
	templatePtr->cdit = 7;         // Number of controls
	templatePtr->x = 0;
	templatePtr->y = 0;
	templatePtr->cx = 350;
	templatePtr->cy = 250;
	templatePtr++;

	LPWORD wordPtr = reinterpret_cast<LPWORD>(templatePtr);
	*wordPtr++ = 0; // No menu
	*wordPtr++ = 0; // Predefined dialog box class (by default)

	LPWSTR wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
	memcpy(wideStringPtr, L"Open Game Framework", 20 * sizeof(wchar_t));
	wideStringPtr += 20;

	// Font
	wordPtr = reinterpret_cast<LPWORD>(wideStringPtr);
	*wordPtr++ = 8;

	wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
	memcpy(wideStringPtr, L"MS Shell Dlg", 13 * sizeof(wchar_t));
	wideStringPtr += 13;

	buffer = reinterpret_cast<void*>(wideStringPtr);

	// Calculate space left
	size_t space = BUFF_SIZE - sizeof(LPDLGTEMPLATE) - (20 * sizeof(wchar_t)) - (3 * sizeof(WORD));

	// Add buttons
	addButtonToDialog(&buffer, space, 5, 230, ID_IGNORE, STYLE_DEFAULT_BUTTON, L"Ignore", 6);
	addButtonToDialog(&buffer, space, 60, 230, ID_BREAK, STYLE_BUTTON | (Debug::isDebuggerAttached() ? 0 : WS_DISABLED), L"Break", 5);
	addButtonToDialog(&buffer, space, 115, 230, ID_TERMINATE, STYLE_BUTTON, L"Terminate", 9);

	addWhiteRectToDialog(&buffer, space, 0, 0);
	addEditableTextToDialog(&buffer, space, 5, 45, msg.c_str(), msg.length());
	addIconToDialog(&buffer, space, 10, 10);
	addStaticTextToDialog(&buffer, space, 38, 18, L"Assertion Failed!", 17);

	// Display dialogue
	GlobalUnlock(globalHandle);

	INT_PTR retVal = DialogBoxIndirect(NULL, reinterpret_cast<LPDLGTEMPLATE>(globalHandle), NULL, (DLGPROC)DialogProc);

	// Cleanup
	GlobalFree(globalHandle);

	if (retVal == ID_TERMINATE) {
		std::exit(1);
	}

	return (retVal == ID_BREAK);
}

static void addDialogItem(void** buffer, size_t& space, int16 x, int16 y, int16 width, int16 height, WORD id, DWORD style, WORD classOrdinalValue, const wchar_t* title, uint32 titleLength) {
	const size_t itemSize = sizeof(DLGITEMTEMPLATE) + ((titleLength + 1) * sizeof(wchar_t)) + (sizeof(WORD) * 3);

	if (std::align(alignof(DWORD), itemSize, *buffer, space)) {
		LPDLGITEMTEMPLATE itemTemplatePtr = reinterpret_cast<LPDLGITEMTEMPLATE>(*buffer);
		itemTemplatePtr->x = x;
		itemTemplatePtr->y = y;
		itemTemplatePtr->cx = width;
		itemTemplatePtr->cy = height;
		itemTemplatePtr->id = id;
		itemTemplatePtr->style = style;
		itemTemplatePtr++;

		LPWORD wordPtr = reinterpret_cast<LPWORD>(itemTemplatePtr);
		*wordPtr++ = 0xFFFF;
		*wordPtr++ = classOrdinalValue;

		LPWSTR wideStringPtr = reinterpret_cast<LPWSTR>(wordPtr);
		memcpy(wideStringPtr, title, (titleLength + 1) * sizeof(wchar_t));
		wideStringPtr += titleLength + 1;

		wordPtr = reinterpret_cast<LPWORD>(wideStringPtr);
		*wordPtr++ = 0;             // No creation data

		*buffer = reinterpret_cast<void*>(wordPtr);
	}
}

static void addButtonToDialog(void** buffer, size_t& space, int16 x, int16 y, WORD id, DWORD style, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 50, 14, id, style, CLASS_BUTTON, text, textLength);
}

static void addEditableTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 340, 165, ID_EDITABLE_TEXT, STYLE_EDITABLE_TEXT, CLASS_EDIT, text, textLength);
}

static void addStaticTextToDialog(void** buffer, size_t& space, int16 x, int16 y, const wchar_t* text, uint32 textLength) {
	addDialogItem(buffer, space, x, y, 100, 20, ID_DONT_CARE, STYLE_STATIC_TEXT, CLASS_STATIC, text, textLength);
}

static void addWhiteRectToDialog(void** buffer, size_t& space, int16 x, int16 y) {
	addDialogItem(buffer, space, x, y, 500, 220, ID_DONT_CARE, STYLE_WHITE_RECT, CLASS_STATIC, L"\0", 1);
}

static void addIconToDialog(void** buffer, size_t& space, int16 x, int16 y) {
	wchar_t iconStr[2] = { 0xFFFF, (WORD)IDI_WARNING };
	addDialogItem(buffer, space, x, y, SM_CXICON, SM_CYICON, ID_DONT_CARE, STYLE_ICON, CLASS_STATIC, iconStr, 1);
}

std::wstring formatAssertMessage(const char* fileName, uint32 lineNumber, const std::vector<string>& stackTrace, const char* msg, ...) {
	va_list args;
	va_start(args, msg);

	int32 bufferSize = _vscprintf(msg, args);
	if (bufferSize < 0)
	{
		// Error
		va_end(args);
		return std::wstring();
	}

	bufferSize++; // For terminating null character
	char* buffer = new char[bufferSize];
	int32 charsWritten = vsprintf_s(buffer, bufferSize, msg, args);
	if (charsWritten < 0)
	{
		// Error
		va_end(args);
		delete[] buffer;
		return std::wstring();
	}

	va_end(args);

	std::wstringstream sstream;
	sstream << L"File: " << fileName << "\r\n" << "Line: " << lineNumber << "\r\n\r\n" << buffer << "\r\n\r\n";
	for (const std::string& str : stackTrace) {
		sstream << str.c_str() << "\r\n";
	}

	delete[] buffer;
	return sstream.str();

}
#endif<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageAlgorithm.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  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 notice for more information.

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

#include "vtkObjectFactory.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkCxxRevisionMacro(vtkImageAlgorithm, "1.25");

//----------------------------------------------------------------------------
vtkImageAlgorithm::vtkImageAlgorithm()
{
  this->SetNumberOfInputPorts(1);
  this->SetNumberOfOutputPorts(1);

  // by default process active point scalars
  this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::SCALARS);
}

//----------------------------------------------------------------------------
vtkImageAlgorithm::~vtkImageAlgorithm()
{
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

//----------------------------------------------------------------------------
// This is the superclasses style of Execute method.  Convert it into
// an imaging style Execute method.
int vtkImageAlgorithm::RequestData(
  vtkInformation* request,
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector* outputVector)
{
  // the default implimentation is to do what the old pipeline did find what
  // output is requesting the data, and pass that into ExecuteData

  // which output port did the request come from
  int outputPort =
    request->Get(vtkDemandDrivenPipeline::FROM_OUTPUT_PORT());

  // if output port is negative then that means this filter is calling the
  // update directly, in that case just assume port 0
  if (outputPort == -1)
      {
      outputPort = 0;
      }

  // get the data object
  vtkInformation *outInfo =
    outputVector->GetInformationObject(outputPort);
  // call ExecuteData
  if (outInfo)
    {
    this->ExecuteData( outInfo->Get(vtkDataObject::DATA_OBJECT()) );
    }
  else
    {
    this->ExecuteData(NULL);
    }
  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::ProcessRequest(vtkInformation* request,
                                      vtkInformationVector** inputVector,
                                      vtkInformationVector* outputVector)
{
  // generate the data
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
    {
    this->RequestData(request, inputVector, outputVector);
    return 1;
    }

  // execute information
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
    {
    this->RequestInformation(request, inputVector, outputVector);
    return 1;
    }

  // propagate update extent
  if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
    {
    this->RequestUpdateExtent(request, inputVector, outputVector);
    return 1;
    }

  return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}

//----------------------------------------------------------------------------
// Assume that any source that implements ExecuteData
// can handle an empty extent.
void vtkImageAlgorithm::ExecuteData(vtkDataObject *)
{
  this->Execute();
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::Execute()
{
  vtkErrorMacro(<< "Definition of Execute() method should be in subclass and you should really use the ExecuteData(vtkInformation *request,...) signature instead");
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::CopyInputArrayAttributesToOutput
(vtkInformation* vtkNotUsed( request ),
 vtkInformationVector** inputVector,
 vtkInformationVector* outputVector)
{
  // for image data to image data
  if (this->GetNumberOfInputPorts() && this->GetNumberOfOutputPorts())
    {
    vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
    // if the input is image data
    if (vtkImageData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())))
      {
      vtkInformation *info =
        this->GetInputArrayFieldInformation(0, inputVector);
      if (info)
        {
        int scalarType = info->Get( vtkDataObject::FIELD_ARRAY_TYPE());
        int numComp = info->Get( vtkDataObject::FIELD_NUMBER_OF_COMPONENTS());
        for(int i=0; i < this->GetNumberOfOutputPorts(); ++i)
          {
          vtkInformation* outInfo = outputVector->GetInformationObject(i);
          // if the output is image data
          if (vtkImageData::SafeDownCast
              (outInfo->Get(vtkDataObject::DATA_OBJECT())))
            {
            // copy scalar type and scalar number of components
            vtkDataObject::SetPointDataActiveScalarInfo(outInfo,
                                                        scalarType, numComp);
            }
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::RequestInformation(
  vtkInformation* request,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  // do nothing except copy scalar type info
  this->CopyInputArrayAttributesToOutput(request,inputVector,outputVector);
  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::RequestUpdateExtent(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* vtkNotUsed(outputVector))
{
  // do nothing let subclasses handle it
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AllocateOutputData(vtkImageData *output,
                                           int *uExtent)
{
  // set the extent to be the update extent
  output->SetExtent(uExtent);
  output->AllocateScalars();
}

//----------------------------------------------------------------------------
vtkImageData *vtkImageAlgorithm::AllocateOutputData(vtkDataObject *output)
{
  // set the extent to be the update extent
  vtkImageData *out = vtkImageData::SafeDownCast(output);
  if (out)
    {
    // this needs to be fixed -Ken
    vtkStreamingDemandDrivenPipeline *sddp =
      vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
    if (sddp)
      {
      int extent[6];
      sddp->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),extent);
      out->SetExtent(extent);
      }
    out->AllocateScalars();
    }
  return out;
}

//----------------------------------------------------------------------------
// by default copy the attr from the first input to the first output
void vtkImageAlgorithm::CopyAttributeData(vtkImageData *input,
                                          vtkImageData *output,
                                          vtkInformationVector **inputVector)
{
  if (!input || !output)
    {
    return;
    }

  int inExt[6];
  int outExt[6];
  vtkDataArray *inArray;
  vtkDataArray *outArray;

  input->GetExtent(inExt);
  output->GetExtent(outExt);

  // Do not copy the array we will be generating.
  inArray = this->GetInputArrayToProcess(0,inputVector);

  // Conditionally copy point and cell data.  Only copy if corresponding
  // indexes refer to identical points.
  double *oIn = input->GetOrigin();
  double *sIn = input->GetSpacing();
  double *oOut = output->GetOrigin();
  double *sOut = output->GetSpacing();
  if (oIn[0] == oOut[0] && oIn[1] == oOut[1] && oIn[2] == oOut[2] &&
      sIn[0] == sOut[0] && sIn[1] == sOut[1] && sIn[2] == sOut[2])
    {
    output->GetPointData()->CopyAllOn();
    output->GetCellData()->CopyAllOn();
    output->GetPointData()->CopyScalarsOff();

    // If the extents are the same, then pass the attribute data for
    // efficiency.
    if (inExt[0] == outExt[0] && inExt[1] == outExt[1] &&
        inExt[2] == outExt[2] && inExt[3] == outExt[3] &&
        inExt[4] == outExt[4] && inExt[5] == outExt[5])
      {// Pass
      // set the name of the output to match the input name
      outArray = output->GetPointData()->GetScalars();
      if (inArray)
        {
        outArray->SetName(inArray->GetName());
        }
      output->GetPointData()->PassData(input->GetPointData());
      output->GetCellData()->PassData(input->GetCellData());
      }
    else
      {// Copy
       // Since this can be expensive to copy all of these values,
       // lets make sure there are arrays to copy (other than the scalars)
      if (input->GetPointData()->GetNumberOfArrays() > 1)
        {
        // Copy the point data.
        // CopyAllocate frees all arrays.
        // Keep the old scalar array (not being copied).
        // This is a hack, but avoids reallocation ...
        vtkDataArray *tmp = NULL;
        if ( ! output->GetPointData()->GetCopyScalars() )
          {
          tmp = output->GetPointData()->GetScalars();
          // set the name of the output to match the input name
          if (inArray)
            {
            tmp->SetName(inArray->GetName());
            }
          }
        output->GetPointData()->CopyAllocate(input->GetPointData(),
                                             output->GetNumberOfPoints());
        if (tmp)
          { // Restore the array.
          output->GetPointData()->SetScalars(tmp);
          }
        // Now Copy The point data, but only if output is a subextent of the
        // input.
        if (outExt[0] >= inExt[0] && outExt[1] <= inExt[1] &&
            outExt[2] >= inExt[2] && outExt[3] <= inExt[3] &&
            outExt[4] >= inExt[4] && outExt[5] <= inExt[5])
          {
          output->GetPointData()->CopyStructuredData(input->GetPointData(),
                                                     inExt, outExt);
          }
        }

      if (input->GetCellData()->GetNumberOfArrays() > 0)
        {
        output->GetCellData()->CopyAllocate(input->GetCellData(),
                                            output->GetNumberOfCells());
        // Cell extent is one less than point extent.
        // Conditional to handle a colapsed axis (lower dimensional cells).
        if (inExt[0] < inExt[1]) {--inExt[1];}
        if (inExt[2] < inExt[3]) {--inExt[3];}
        if (inExt[4] < inExt[5]) {--inExt[5];}
        // Cell extent is one less than point extent.
        if (outExt[0] < outExt[1]) {--outExt[1];}
        if (outExt[2] < outExt[3]) {--outExt[3];}
        if (outExt[4] < outExt[5]) {--outExt[5];}
        // Now Copy The cell data, but only if output is a subextent of the input.
        if (outExt[0] >= inExt[0] && outExt[1] <= inExt[1] &&
            outExt[2] >= inExt[2] && outExt[3] <= inExt[3] &&
            outExt[4] >= inExt[4] && outExt[5] <= inExt[5])
          {
          output->GetCellData()->CopyStructuredData(input->GetCellData(),
                                                    inExt, outExt);
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetOutput()
{
  return this->GetOutput(0);
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetOutput(int port)
{
  return vtkImageData::SafeDownCast(this->GetOutputDataObject(port));
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetOutput(vtkDataObject* d)
{
  this->GetExecutive()->SetOutputData(0, d);
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::FillOutputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  // now add our info
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");

  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::FillInputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetInput(vtkDataObject* input)
{
  this->SetInput(0, input);
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetInput(int index, vtkDataObject* input)
{
  if(input)
    {
    this->SetInputConnection(index, input->GetProducerPort());
    }
  else
    {
    // Setting a NULL input removes the connection.
    this->SetInputConnection(index, 0);
    }
}

//----------------------------------------------------------------------------
vtkDataObject* vtkImageAlgorithm::GetInput(int port)
{
  return this->GetExecutive()->GetInputData(port, 0);
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetImageDataInput(int port)
{
  return vtkImageData::SafeDownCast(this->GetInput(port));
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AddInput(vtkDataObject* input)
{
  this->AddInput(0, input);
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AddInput(int index, vtkDataObject* input)
{
  if(input)
    {
    this->AddInputConnection(index, input->GetProducerPort());
    }
}
<commit_msg>ENH: Merge changes from main tree into VTK-5-0 branch. (cvs -q up -j1.25 -j1.26 Filtering/vtkImageAlgorithm.cxx)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageAlgorithm.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  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 notice for more information.

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

#include "vtkObjectFactory.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkCxxRevisionMacro(vtkImageAlgorithm, "1.25.4.1");

//----------------------------------------------------------------------------
vtkImageAlgorithm::vtkImageAlgorithm()
{
  this->SetNumberOfInputPorts(1);
  this->SetNumberOfOutputPorts(1);

  // by default process active point scalars
  this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::SCALARS);
}

//----------------------------------------------------------------------------
vtkImageAlgorithm::~vtkImageAlgorithm()
{
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

//----------------------------------------------------------------------------
// This is the superclasses style of Execute method.  Convert it into
// an imaging style Execute method.
int vtkImageAlgorithm::RequestData(
  vtkInformation* request,
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector* outputVector)
{
  // the default implimentation is to do what the old pipeline did find what
  // output is requesting the data, and pass that into ExecuteData

  // which output port did the request come from
  int outputPort =
    request->Get(vtkDemandDrivenPipeline::FROM_OUTPUT_PORT());

  // if output port is negative then that means this filter is calling the
  // update directly, in that case just assume port 0
  if (outputPort == -1)
      {
      outputPort = 0;
      }

  // get the data object
  vtkInformation *outInfo =
    outputVector->GetInformationObject(outputPort);
  // call ExecuteData
  if (outInfo)
    {
    this->ExecuteData( outInfo->Get(vtkDataObject::DATA_OBJECT()) );
    }
  else
    {
    this->ExecuteData(NULL);
    }
  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::ProcessRequest(vtkInformation* request,
                                      vtkInformationVector** inputVector,
                                      vtkInformationVector* outputVector)
{
  // generate the data
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
    {
    return this->RequestData(request, inputVector, outputVector);
    }

  // execute information
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
    {
    return this->RequestInformation(request, inputVector, outputVector);
    }

  // propagate update extent
  if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
    {
    return this->RequestUpdateExtent(request, inputVector, outputVector);
    }

  return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}

//----------------------------------------------------------------------------
// Assume that any source that implements ExecuteData
// can handle an empty extent.
void vtkImageAlgorithm::ExecuteData(vtkDataObject *)
{
  this->Execute();
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::Execute()
{
  vtkErrorMacro(<< "Definition of Execute() method should be in subclass and you should really use the ExecuteData(vtkInformation *request,...) signature instead");
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::CopyInputArrayAttributesToOutput
(vtkInformation* vtkNotUsed( request ),
 vtkInformationVector** inputVector,
 vtkInformationVector* outputVector)
{
  // for image data to image data
  if (this->GetNumberOfInputPorts() && this->GetNumberOfOutputPorts())
    {
    vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
    // if the input is image data
    if (vtkImageData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())))
      {
      vtkInformation *info =
        this->GetInputArrayFieldInformation(0, inputVector);
      if (info)
        {
        int scalarType = info->Get( vtkDataObject::FIELD_ARRAY_TYPE());
        int numComp = info->Get( vtkDataObject::FIELD_NUMBER_OF_COMPONENTS());
        for(int i=0; i < this->GetNumberOfOutputPorts(); ++i)
          {
          vtkInformation* outInfo = outputVector->GetInformationObject(i);
          // if the output is image data
          if (vtkImageData::SafeDownCast
              (outInfo->Get(vtkDataObject::DATA_OBJECT())))
            {
            // copy scalar type and scalar number of components
            vtkDataObject::SetPointDataActiveScalarInfo(outInfo,
                                                        scalarType, numComp);
            }
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::RequestInformation(
  vtkInformation* request,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  // do nothing except copy scalar type info
  this->CopyInputArrayAttributesToOutput(request,inputVector,outputVector);
  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::RequestUpdateExtent(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* vtkNotUsed(outputVector))
{
  // do nothing let subclasses handle it
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AllocateOutputData(vtkImageData *output,
                                           int *uExtent)
{
  // set the extent to be the update extent
  output->SetExtent(uExtent);
  output->AllocateScalars();
}

//----------------------------------------------------------------------------
vtkImageData *vtkImageAlgorithm::AllocateOutputData(vtkDataObject *output)
{
  // set the extent to be the update extent
  vtkImageData *out = vtkImageData::SafeDownCast(output);
  if (out)
    {
    // this needs to be fixed -Ken
    vtkStreamingDemandDrivenPipeline *sddp =
      vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
    if (sddp)
      {
      int extent[6];
      sddp->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),extent);
      out->SetExtent(extent);
      }
    out->AllocateScalars();
    }
  return out;
}

//----------------------------------------------------------------------------
// by default copy the attr from the first input to the first output
void vtkImageAlgorithm::CopyAttributeData(vtkImageData *input,
                                          vtkImageData *output,
                                          vtkInformationVector **inputVector)
{
  if (!input || !output)
    {
    return;
    }

  int inExt[6];
  int outExt[6];
  vtkDataArray *inArray;
  vtkDataArray *outArray;

  input->GetExtent(inExt);
  output->GetExtent(outExt);

  // Do not copy the array we will be generating.
  inArray = this->GetInputArrayToProcess(0,inputVector);

  // Conditionally copy point and cell data.  Only copy if corresponding
  // indexes refer to identical points.
  double *oIn = input->GetOrigin();
  double *sIn = input->GetSpacing();
  double *oOut = output->GetOrigin();
  double *sOut = output->GetSpacing();
  if (oIn[0] == oOut[0] && oIn[1] == oOut[1] && oIn[2] == oOut[2] &&
      sIn[0] == sOut[0] && sIn[1] == sOut[1] && sIn[2] == sOut[2])
    {
    output->GetPointData()->CopyAllOn();
    output->GetCellData()->CopyAllOn();
    output->GetPointData()->CopyScalarsOff();

    // If the extents are the same, then pass the attribute data for
    // efficiency.
    if (inExt[0] == outExt[0] && inExt[1] == outExt[1] &&
        inExt[2] == outExt[2] && inExt[3] == outExt[3] &&
        inExt[4] == outExt[4] && inExt[5] == outExt[5])
      {// Pass
      // set the name of the output to match the input name
      outArray = output->GetPointData()->GetScalars();
      if (inArray)
        {
        outArray->SetName(inArray->GetName());
        }
      output->GetPointData()->PassData(input->GetPointData());
      output->GetCellData()->PassData(input->GetCellData());
      }
    else
      {// Copy
       // Since this can be expensive to copy all of these values,
       // lets make sure there are arrays to copy (other than the scalars)
      if (input->GetPointData()->GetNumberOfArrays() > 1)
        {
        // Copy the point data.
        // CopyAllocate frees all arrays.
        // Keep the old scalar array (not being copied).
        // This is a hack, but avoids reallocation ...
        vtkDataArray *tmp = NULL;
        if ( ! output->GetPointData()->GetCopyScalars() )
          {
          tmp = output->GetPointData()->GetScalars();
          // set the name of the output to match the input name
          if (inArray)
            {
            tmp->SetName(inArray->GetName());
            }
          }
        output->GetPointData()->CopyAllocate(input->GetPointData(),
                                             output->GetNumberOfPoints());
        if (tmp)
          { // Restore the array.
          output->GetPointData()->SetScalars(tmp);
          }
        // Now Copy The point data, but only if output is a subextent of the
        // input.
        if (outExt[0] >= inExt[0] && outExt[1] <= inExt[1] &&
            outExt[2] >= inExt[2] && outExt[3] <= inExt[3] &&
            outExt[4] >= inExt[4] && outExt[5] <= inExt[5])
          {
          output->GetPointData()->CopyStructuredData(input->GetPointData(),
                                                     inExt, outExt);
          }
        }

      if (input->GetCellData()->GetNumberOfArrays() > 0)
        {
        output->GetCellData()->CopyAllocate(input->GetCellData(),
                                            output->GetNumberOfCells());
        // Cell extent is one less than point extent.
        // Conditional to handle a colapsed axis (lower dimensional cells).
        if (inExt[0] < inExt[1]) {--inExt[1];}
        if (inExt[2] < inExt[3]) {--inExt[3];}
        if (inExt[4] < inExt[5]) {--inExt[5];}
        // Cell extent is one less than point extent.
        if (outExt[0] < outExt[1]) {--outExt[1];}
        if (outExt[2] < outExt[3]) {--outExt[3];}
        if (outExt[4] < outExt[5]) {--outExt[5];}
        // Now Copy The cell data, but only if output is a subextent of the input.
        if (outExt[0] >= inExt[0] && outExt[1] <= inExt[1] &&
            outExt[2] >= inExt[2] && outExt[3] <= inExt[3] &&
            outExt[4] >= inExt[4] && outExt[5] <= inExt[5])
          {
          output->GetCellData()->CopyStructuredData(input->GetCellData(),
                                                    inExt, outExt);
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetOutput()
{
  return this->GetOutput(0);
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetOutput(int port)
{
  return vtkImageData::SafeDownCast(this->GetOutputDataObject(port));
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetOutput(vtkDataObject* d)
{
  this->GetExecutive()->SetOutputData(0, d);
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::FillOutputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  // now add our info
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");

  return 1;
}

//----------------------------------------------------------------------------
int vtkImageAlgorithm::FillInputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
  return 1;
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetInput(vtkDataObject* input)
{
  this->SetInput(0, input);
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::SetInput(int index, vtkDataObject* input)
{
  if(input)
    {
    this->SetInputConnection(index, input->GetProducerPort());
    }
  else
    {
    // Setting a NULL input removes the connection.
    this->SetInputConnection(index, 0);
    }
}

//----------------------------------------------------------------------------
vtkDataObject* vtkImageAlgorithm::GetInput(int port)
{
  return this->GetExecutive()->GetInputData(port, 0);
}

//----------------------------------------------------------------------------
vtkImageData* vtkImageAlgorithm::GetImageDataInput(int port)
{
  return vtkImageData::SafeDownCast(this->GetInput(port));
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AddInput(vtkDataObject* input)
{
  this->AddInput(0, input);
}

//----------------------------------------------------------------------------
void vtkImageAlgorithm::AddInput(int index, vtkDataObject* input)
{
  if(input)
    {
    this->AddInputConnection(index, input->GetProducerPort());
    }
}
<|endoftext|>