Gered
c5cdddbeaa
current versions of all of my basic framework sources, build configurations/scripts, and supporting assets
331 lines
7.2 KiB
C++
331 lines
7.2 KiB
C++
/*
|
|
GWEN
|
|
Copyright (c) 2010 Facepunch Studios
|
|
See license in Gwen.h
|
|
*/
|
|
|
|
|
|
#include "../gwen.h"
|
|
#include "gwen_windowcanvas.h"
|
|
#include "../gwen_skin.h"
|
|
#include "gwen_menu.h"
|
|
#include "../gwen_draganddrop.h"
|
|
#include "../gwen_tooltip.h"
|
|
|
|
#ifndef GWEN_NO_ANIMATION
|
|
#include "../gwen_anim.h"
|
|
#endif
|
|
|
|
using namespace Gwen;
|
|
using namespace Gwen::Controls;
|
|
|
|
WindowCanvas::WindowCanvas( int x, int y, int w, int h, Gwen::Skin::Base* pSkin, const Gwen::String& strWindowTitle ) : BaseClass( NULL )
|
|
{
|
|
m_bQuit = false;
|
|
m_bCanMaximize = true;
|
|
m_bIsMaximized = false;
|
|
|
|
SetPadding( Padding( 1, 0, 1, 1 ) );
|
|
|
|
// Centering the window on the desktop
|
|
{
|
|
int dw, dh;
|
|
Gwen::Platform::GetDesktopSize( dw, dh );
|
|
|
|
if ( x < 0 ) x = (dw - w) * 0.5;
|
|
if ( y < 0 ) y = (dh - h) * 0.5;
|
|
}
|
|
|
|
m_pOSWindow = Gwen::Platform::CreatePlatformWindow( x, y, w, h, strWindowTitle );
|
|
m_WindowPos = Gwen::Point( x, y );
|
|
|
|
pSkin->GetRender()->InitializeContext( this );
|
|
pSkin->GetRender()->Init();
|
|
m_pSkinChange = pSkin;
|
|
|
|
SetSize( w, h );
|
|
|
|
m_TitleBar = new Gwen::ControlsInternal::Dragger( this );
|
|
m_TitleBar->SetHeight( 24 );
|
|
m_TitleBar->SetPadding( Padding( 0, 0, 0, 0 ) );
|
|
m_TitleBar->SetMargin( Margin( 0, 0, 0, 0 ) );
|
|
m_TitleBar->Dock( Pos::Top );
|
|
m_TitleBar->SetDoMove( false );
|
|
m_TitleBar->onDragged.Add( this, &ThisClass::Dragger_Moved );
|
|
m_TitleBar->onDragStart.Add( this, &ThisClass::Dragger_Start );
|
|
m_TitleBar->onDoubleClickLeft.Add( this, &ThisClass::OnTitleDoubleClicked );
|
|
|
|
m_Title = new Gwen::Controls::Label( m_TitleBar );
|
|
m_Title->SetAlignment( Pos::Left | Pos::CenterV );
|
|
m_Title->SetText( strWindowTitle );
|
|
m_Title->Dock( Pos::Fill );
|
|
m_Title->SetPadding( Padding( 8, 0, 0, 0 ) );
|
|
m_Title->SetTextColor( GetSkin()->Colors.Window.TitleInactive );
|
|
|
|
// CLOSE
|
|
{
|
|
m_pClose = new Gwen::Controls::WindowCloseButton( m_TitleBar, "Close" );
|
|
m_pClose->Dock( Pos::Right );
|
|
m_pClose->SetMargin( Margin( 0, 0, 4, 0 ) );
|
|
m_pClose->onPress.Add( this, &WindowCanvas::CloseButtonPressed );
|
|
m_pClose->SetTabable( false );
|
|
m_pClose->SetWindow( this );
|
|
}
|
|
|
|
// MAXIMIZE
|
|
{
|
|
m_pMaximize = new Gwen::Controls::WindowMaximizeButton( m_TitleBar, "Maximize" );
|
|
m_pMaximize->Dock( Pos::Right );
|
|
m_pMaximize->onPress.Add( this, &WindowCanvas::MaximizeButtonPressed );
|
|
m_pMaximize->SetTabable( false );
|
|
m_pMaximize->SetWindow( this );
|
|
}
|
|
|
|
// MINIMiZE
|
|
{
|
|
m_pMinimize = new Gwen::Controls::WindowMinimizeButton( m_TitleBar, "Minimize" );
|
|
m_pMinimize->Dock( Pos::Right );
|
|
m_pMinimize->onPress.Add( this, &WindowCanvas::MinimizeButtonPressed );
|
|
m_pMinimize->SetTabable( false );
|
|
m_pMinimize->SetWindow( this );
|
|
}
|
|
|
|
// Bottom Right Corner Sizer
|
|
{
|
|
m_Sizer = new Gwen::ControlsInternal::Dragger( this );
|
|
m_Sizer->SetSize( 16, 16 );
|
|
m_Sizer->SetDoMove( false );
|
|
m_Sizer->onDragged.Add( this, &WindowCanvas::Sizer_Moved );
|
|
m_Sizer->onDragStart.Add( this, &WindowCanvas::Dragger_Start );
|
|
m_Sizer->SetCursor( Gwen::CursorType::SizeNWSE );
|
|
}
|
|
}
|
|
|
|
WindowCanvas::~WindowCanvas()
|
|
{
|
|
DestroyWindow();
|
|
}
|
|
|
|
void* WindowCanvas::GetWindow()
|
|
{
|
|
return m_pOSWindow;
|
|
}
|
|
|
|
void WindowCanvas::Layout( Skin::Base* skin )
|
|
{
|
|
m_Sizer->BringToFront();
|
|
m_Sizer->Position( Pos::Right | Pos::Bottom );
|
|
|
|
BaseClass::Layout( skin );
|
|
}
|
|
|
|
void WindowCanvas::DoThink()
|
|
{
|
|
Platform::MessagePump( m_pOSWindow, this );
|
|
BaseClass::DoThink();
|
|
RenderCanvas();
|
|
}
|
|
|
|
void WindowCanvas::RenderCanvas()
|
|
{
|
|
//
|
|
// If there isn't anything going on we sleep the thread for a few ms
|
|
// This gives some cpu time back to the os. If you're using a rendering
|
|
// method that needs continual updates, just call canvas->redraw every frame.
|
|
//
|
|
if ( !NeedsRedraw() )
|
|
{
|
|
Platform::Sleep( 10 );
|
|
return;
|
|
}
|
|
|
|
m_bNeedsRedraw = false;
|
|
|
|
Gwen::Renderer::Base* render = m_Skin->GetRender();
|
|
|
|
if ( render->BeginContext( this ) )
|
|
{
|
|
render->Begin();
|
|
|
|
RecurseLayout( m_Skin );
|
|
|
|
render->SetClipRegion( GetRenderBounds() );
|
|
render->SetRenderOffset( Gwen::Point( X() * -1, Y() * -1 ) );
|
|
render->SetScale( Scale() );
|
|
|
|
if ( m_bDrawBackground )
|
|
{
|
|
render->SetDrawColor( m_BackgroundColor );
|
|
render->DrawFilledRect( GetRenderBounds() );
|
|
}
|
|
|
|
DoRender( m_Skin );
|
|
|
|
DragAndDrop::RenderOverlay( this, m_Skin );
|
|
|
|
ToolTip::RenderToolTip( m_Skin );
|
|
|
|
render->End();
|
|
}
|
|
|
|
render->EndContext( this );
|
|
|
|
render->PresentContext( this );
|
|
}
|
|
|
|
void WindowCanvas::Render( Skin::Base* skin )
|
|
{
|
|
bool bHasFocus = IsOnTop();
|
|
|
|
if ( bHasFocus )
|
|
m_Title->SetTextColor( GetSkin()->Colors.Window.TitleActive );
|
|
else
|
|
m_Title->SetTextColor( GetSkin()->Colors.Window.TitleInactive );
|
|
|
|
skin->DrawWindow( this, m_TitleBar->Bottom(), bHasFocus );
|
|
}
|
|
|
|
|
|
void WindowCanvas::DestroyWindow()
|
|
{
|
|
if ( m_pOSWindow )
|
|
{
|
|
GetSkin()->GetRender()->ShutdownContext( this );
|
|
Gwen::Platform::DestroyPlatformWindow( m_pOSWindow );
|
|
m_pOSWindow = NULL;
|
|
}
|
|
}
|
|
|
|
bool WindowCanvas::InputQuit()
|
|
{
|
|
m_bQuit = true;
|
|
return true;
|
|
}
|
|
|
|
Skin::Base* WindowCanvas::GetSkin( void )
|
|
{
|
|
if ( m_pSkinChange )
|
|
{
|
|
SetSkin( m_pSkinChange );
|
|
m_pSkinChange = NULL;
|
|
}
|
|
|
|
return BaseClass::GetSkin();
|
|
}
|
|
|
|
|
|
void WindowCanvas::Dragger_Start()
|
|
{
|
|
Gwen::Platform::GetCursorPos( m_HoldPos );
|
|
|
|
m_HoldPos.x -= m_WindowPos.x;
|
|
m_HoldPos.y -= m_WindowPos.y;
|
|
}
|
|
|
|
void WindowCanvas::Dragger_Moved()
|
|
{
|
|
Gwen::Point p;
|
|
Gwen::Platform::GetCursorPos( p );
|
|
|
|
//
|
|
// Dragged out of maximized
|
|
//
|
|
if ( m_bIsMaximized )
|
|
{
|
|
float fOldWidth = Width();
|
|
|
|
SetMaximize( false );
|
|
|
|
// Change the hold pos to be the same distance across the titlebar of the resized window
|
|
m_HoldPos.x = ((float)m_HoldPos.x) * ( (float)Width() / fOldWidth );
|
|
m_HoldPos.y = 10;
|
|
}
|
|
|
|
SetPos( p.x - m_HoldPos.x, p.y - m_HoldPos.y );
|
|
}
|
|
|
|
void WindowCanvas::SetPos( int x, int y )
|
|
{
|
|
int w, h;
|
|
Gwen::Platform::GetDesktopSize( w, h );
|
|
y = Gwen::Clamp( y, 0, h );
|
|
|
|
m_WindowPos.x = x;
|
|
m_WindowPos.y = y;
|
|
|
|
Gwen::Platform::SetBoundsPlatformWindow( m_pOSWindow, x, y, Width(), Height() );
|
|
}
|
|
|
|
void WindowCanvas::CloseButtonPressed()
|
|
{
|
|
InputQuit();
|
|
}
|
|
|
|
bool WindowCanvas::IsOnTop()
|
|
{
|
|
return Gwen::Platform::HasFocusPlatformWindow( m_pOSWindow );
|
|
}
|
|
|
|
|
|
void WindowCanvas::Sizer_Moved()
|
|
{
|
|
Gwen::Point p;
|
|
Gwen::Platform::GetCursorPos( p );
|
|
|
|
int w = (p.x) - m_WindowPos.x;
|
|
int h = (p.y) - m_WindowPos.y;
|
|
|
|
w = Clamp( w, 100, 9999 );
|
|
h = Clamp( h, 100, 9999 );
|
|
|
|
Gwen::Platform::SetBoundsPlatformWindow( m_pOSWindow, m_WindowPos.x, m_WindowPos.y, w, h );
|
|
GetSkin()->GetRender()->ResizedContext( this, w, h );
|
|
this->SetSize( w, h );
|
|
|
|
BaseClass::DoThink();
|
|
RenderCanvas();
|
|
}
|
|
|
|
void WindowCanvas::OnTitleDoubleClicked()
|
|
{
|
|
if ( !CanMaximize() ) return;
|
|
|
|
SetMaximize( !m_bIsMaximized );
|
|
}
|
|
|
|
void WindowCanvas::SetMaximize( bool b )
|
|
{
|
|
m_bIsMaximized = b;
|
|
m_pMaximize->SetMaximized( m_bIsMaximized );
|
|
|
|
Gwen::Point pSize, pPos;
|
|
|
|
Gwen::Platform::SetWindowMaximized( m_pOSWindow, m_bIsMaximized, pPos, pSize );
|
|
SetSize( pSize.x, pSize.y );
|
|
m_WindowPos = pPos;
|
|
|
|
GetSkin()->GetRender()->ResizedContext( this, pSize.x, pSize.y );
|
|
|
|
BaseClass::DoThink();
|
|
RenderCanvas();
|
|
}
|
|
|
|
void WindowCanvas::MaximizeButtonPressed()
|
|
{
|
|
if ( !CanMaximize() ) return;
|
|
|
|
SetMaximize( !m_bIsMaximized );
|
|
}
|
|
|
|
void WindowCanvas::MinimizeButtonPressed()
|
|
{
|
|
Gwen::Platform::SetWindowMinimized( m_pOSWindow, true );
|
|
}
|
|
|
|
void WindowCanvas::SetCanMaximize( bool b )
|
|
{
|
|
if ( m_bCanMaximize == b ) return;
|
|
|
|
m_bCanMaximize = b;
|
|
m_pMaximize->SetDisabled( !b );
|
|
} |