This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
MyGameFramework/lib/gwen/controls/gwen_windowcanvas.cpp
Gered c5cdddbeaa initial commit
current versions of all of my basic framework sources, build configurations/scripts, and supporting assets
2013-01-31 12:53:05 -05:00

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 );
}