Files
video-v1/vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml.cpp

253 lines
9.7 KiB
C++

#include "pch.h"
#include "MainWindow.xaml.h"
#include "MainVideoPage.xaml.h"
#include "MultiVideoPage.xaml.h"
// Temporarily excluded - old VideoPlayerControl
// #include "LayeredVideoPage.xaml.h"
#include "SettingsPage.xaml.h"
#include "src/Logger/LogManager.h"
#include <microsoft.ui.xaml.window.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif
using namespace winrt;
using namespace winrt::Microsoft::UI::Xaml;
using namespace winrt::Microsoft::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Interop;
namespace winrt::Vav2Player::implementation
{
MainWindow::MainWindow()
{
InitializeComponent();
// Apply dark mode to title bar using DWM API
try {
auto windowNative = this->try_as<::IWindowNative>();
if (windowNative) {
HWND hWnd = nullptr;
windowNative->get_WindowHandle(&hWnd);
if (hWnd) {
BOOL isDarkMode = TRUE;
::DwmSetWindowAttribute(
hWnd,
DWMWA_USE_IMMERSIVE_DARK_MODE,
&isDarkMode,
sizeof(isDarkMode)
);
}
}
} catch (...) {
// Ignore title bar dark mode errors - non-critical
}
// Initialize LogManager with default outputs (Console + Debug) FIRST
::Vav2Player::LogManager::GetInstance().InitializeDefaultOutputs();
::Vav2Player::LogManager::GetInstance().SetLogLevel(::Vav2Player::LogLevel::Info);
// Initialize log panel after LogManager is ready
m_logPanel = LogPanel();
// Set LogMessagePage as global instance for backward compatibility
// This enables Observer pattern - LogMessagePage will automatically receive updates from LogManager
auto logPageImpl = winrt::get_self<winrt::Vav2Player::implementation::LogMessagePage>(m_logPanel);
winrt::Vav2Player::implementation::LogMessagePage::SetInstance(std::shared_ptr<winrt::Vav2Player::implementation::LogMessagePage>(logPageImpl, [](auto*) {}));
// Initially show log panel
ShowLogToggle().IsChecked(true);
// Load Main Video as default page (start screen)
TypeName pageTypeName;
pageTypeName.Name = winrt::name_of<Vav2Player::MainVideoPage>();
pageTypeName.Kind = TypeKind::Metadata;
ContentFrame().Navigate(pageTypeName);
// Add welcome message to log - this will now be received by LogMessagePage via Observer pattern
::Vav2Player::LogManager::GetInstance().LogInfo(L"Vav2Player started successfully", L"MainWindow");
}
// Navigation event handlers
void MainWindow::SwitchToMainView_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
TypeName pageTypeName;
pageTypeName.Name = winrt::name_of<Vav2Player::MainVideoPage>();
pageTypeName.Kind = TypeKind::Metadata;
ContentFrame().Navigate(pageTypeName);
}
void MainWindow::SwitchToMultiVideoView_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
TypeName pageTypeName;
pageTypeName.Name = winrt::name_of<Vav2Player::MultiVideoPage>();
pageTypeName.Kind = TypeKind::Metadata;
ContentFrame().Navigate(pageTypeName);
}
void MainWindow::SwitchToLayeredVideoView_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
// Temporarily disabled - old VideoPlayerControl
// TODO: Update LayeredVideoPage to use VideoPlayerControl2
return;
/*
TypeName pageTypeName;
pageTypeName.Name = winrt::name_of<Vav2Player::LayeredVideoPage>();
pageTypeName.Kind = TypeKind::Metadata;
ContentFrame().Navigate(pageTypeName);
*/
}
void MainWindow::Exit_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
this->Close();
}
void MainWindow::Settings_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
TypeName pageTypeName;
pageTypeName.Name = winrt::name_of<Vav2Player::SettingsPage>();
pageTypeName.Kind = TypeKind::Metadata;
ContentFrame().Navigate(pageTypeName);
}
void MainWindow::About_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
// Could implement About dialog
// For now, just log the request
::Vav2Player::LogManager::GetInstance().LogInfo(L"About dialog requested", L"MainWindow");
}
void MainWindow::ShowLogToggle_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
if (auto toggleButton = sender.try_as<Controls::AppBarToggleButton>())
{
bool isChecked = toggleButton.IsChecked().GetBoolean();
if (isChecked)
{
// Show log panel with default width
LogPanelColumn().Width(GridLength(400));
LogPanelBorder().Visibility(Visibility::Visible);
}
else
{
// Hide log panel
LogPanelColumn().Width(GridLength(0));
LogPanelBorder().Visibility(Visibility::Collapsed);
}
// Log panel visibility toggled - no need to log this
}
}
// Drag-based splitter implementation
void MainWindow::Splitter_PointerPressed(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
// Capture pointer first to ensure we receive subsequent events
if (auto border = SplitterBorder())
{
border.CapturePointer(e.Pointer());
border.Background(Microsoft::UI::Xaml::Media::SolidColorBrush(Microsoft::UI::Colors::CornflowerBlue()));
}
// Set drag state after capturing pointer
m_isDraggingSplitter = true;
// Store initial panel width
m_initialPanelWidth = LogPanelColumn().Width().Value;
// Store initial screen mouse position using Windows API
POINT screenPoint;
GetCursorPos(&screenPoint);
m_lastMouseX = static_cast<double>(screenPoint.x);
// Mark event as handled to prevent bubbling
e.Handled(true);
// Splitter drag started - no need to log drag events
}
void MainWindow::Splitter_PointerMoved(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
if (!m_isDraggingSplitter)
return;
// Get current screen mouse position using Windows API
POINT currentScreenPoint;
GetCursorPos(&currentScreenPoint);
double currentMouseX = static_cast<double>(currentScreenPoint.x);
// Calculate relative mouse movement delta
double deltaX = currentMouseX - m_lastMouseX;
m_lastMouseX = currentMouseX;
// Get current panel width and apply delta
auto currentWidth = LogPanelColumn().Width().Value;
double newWidth = currentWidth + deltaX;
// Set only minimum limit (no maximum limit)
const double MIN_WIDTH = 200.0;
newWidth = std::max(MIN_WIDTH, newWidth);
// Update panel width immediately for natural dragging
LogPanelColumn().Width(GridLength(newWidth));
// Mark event as handled
e.Handled(true);
}
void MainWindow::Splitter_PointerReleased(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
if (m_isDraggingSplitter)
{
m_isDraggingSplitter = false;
// Release pointer capture
if (auto border = SplitterBorder())
{
border.ReleasePointerCapture(e.Pointer());
border.Background(Microsoft::UI::Xaml::Media::SolidColorBrush(
Microsoft::UI::ColorHelper::FromArgb(255, 102, 102, 102))); // Dark gray for splitter
}
// Splitter drag completed - no need to log resize events
// Mark event as handled
e.Handled(true);
}
}
void MainWindow::Splitter_PointerEntered(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const&)
{
// Highlight on hover
if (auto border = SplitterBorder())
{
border.Background(Microsoft::UI::Xaml::Media::SolidColorBrush(Microsoft::UI::Colors::LightGray()));
}
}
void MainWindow::Splitter_PointerExited(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const&)
{
// Reset to default color
if (auto border = SplitterBorder())
{
border.Background(Microsoft::UI::Xaml::Media::SolidColorBrush(
Microsoft::UI::ColorHelper::FromArgb(255, 80, 80, 80))); // Darker gray for default splitter
}
}
// Helper methods moved to MainVideoPage
void MainWindow::ConvertYUVToBGRA(const VavCoreVideoFrame& yuv_frame, uint8_t* bgra_buffer, uint32_t width, uint32_t height)
{
// Implementation moved to MainVideoPage
}
void MainWindow::RenderFrameToScreen(const VavCoreVideoFrame& frame, winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap& bitmap, std::vector<uint8_t>& bgra_buffer)
{
// Implementation moved to MainVideoPage
}
}