253 lines
9.7 KiB
C++
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(¤tScreenPoint);
|
|
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
|
|
}
|
|
} |