commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

174
include/engine/ui/ui.cpp Normal file
View File

@ -0,0 +1,174 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui.h"
#include "ui/ui_camera.h"
#include "ui/ui_sprite.h"
#include "ui/ui_ace_manager.h"
#include "ui/ui_scene_script_event.h"
#include "ui/ui_scene_scripted_object.h"
#include "ui/ui_item_script_event.h"
#include "ui/ui_item_scripted_object.h"
#include "script/script_engine_types.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Scene::SetClock(Core::Clock *c)
{ clock = c ? c : new Core::Clock; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::SetCurrentCamera(Camera *camera)
{ current_camera = camera ? camera : default_camera.c_ptr(); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Item *Scene::ItemFromName(const char *name, Item *parent) const
{
if (parent)
{
ListForeachPtr(Item *, i, parent->GetChildren())
if (i->name == name)
return i;
}
else
{
ListForeachPtr(Item *, i, item_list)
if (i->name == name)
return i;
}
return NULL;
}
Item *Scene::ItemFromUid(uint uid) const
{
ListForeachPtr(Item *, i, item_list)
if (i->GetUid() == uid)
return i;
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
float Scene::GetGlobalFadeEffect() const
{ return global_fade_color.w; }
void Scene::SetGlobalFadeEffect(float o)
{ global_fade_color.w = Types::Clamp(o); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::SetupItemComponents(Item *i)
{
i->scripted_object = new ItemScriptedObject(i, vm);
if (vm)
i->item_event = new ItemScriptEvent;
}
void Scene::AddItem(Item *i, bool setup_components)
{
i->uid = current_item_uid++;
if (setup_components)
SetupItemComponents(i);
g_ui_messenger.BroadcastMessage(UIMsg_AddingItem, this, (void *)i);
item_list.Add(i);
g_ui_messenger.BroadcastMessage(UIMsg_ItemAdded, this, (void *)i);
}
bool Scene::RemoveItem(Item *i)
{
g_ui_messenger.BroadcastMessage(UIMsg_DeletingItem, this, (void *)i);
if (lock == i)
lock = NULL;
item_list.Remove(i);
g_ui_messenger.BroadcastMessage(UIMsg_ItemDeleted, this, (void *)i);
return true;
}
void Scene::DeleteAllItems()
{
while (List <Item *> ::Item *i = item_list.GetRoot())
RemoveItem(i->Object());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Scene::ExecCommand(ACE::Command *cmd, float dt)
{
float k = dt / cmd->duration_left;
switch (cmd->code)
{
case ACE_globalfade:
global_fade_color.w = Types::Clamp(global_fade_color.w + (cmd->parm[0] - global_fade_color.w) * k);
return true;
}
return ACE::Unit::ExecCommand(cmd, dt);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::RenderSetup(Core::ResourceFactories *f)
{
ListForeachPtr(Item *, item, item_list)
item->RenderSetup(f);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::Setup()
{
scene_event->OnSetup(this);
// Setup items.
ListForeachPtr(Item *, i, item_list)
i->Setup();
}
void Scene::Reset()
{
scene_event->OnReset(this);
}
void Scene::Clear()
{
scene_event->OnDelete(this);
window_skin = NULL;
global_fade_color.Set(0, 0, 0, 0);
item_list.Clear();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Scene::Scene(Script::IVM *script_vm)
{
vm = script_vm;
lock = NULL;
current_item_uid = 0;
clock = new Core::Clock;
default_camera = new Camera;
default_camera->resolution.Set(1280, 960);
current_camera = default_camera;
scene_event = vm ? new SceneScriptEvent : new ISceneEvent;
scripted_object = new SceneScriptedObject(vm, this);
global_fade_color.Set(0, 0, 0, 0);
}
Scene::~Scene()
{
Clear();
if (vm)
vm->InvalidateNativeReference((void *)this);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_ace_manager.h"
#include "core/ace.h"
#include "memory/nauto_ptr.h"
//------------------------------------------------------------------------------
GS::ACE::Manager *GS::S2D::ACEManager::Get()
{
static AutoPtr <GS::ACE::Manager> ui_manager;
if (!ui_manager)
{
ui_manager = new GS::ACE::Manager;
ui_manager->DefineACECommand("toalpha", ACE_toalpha, 1);
ui_manager->DefineACECommand("toposition", ACE_toposition, 2);
ui_manager->DefineACECommand("toscale", ACE_toscale, 2);
ui_manager->DefineACECommand("toangle", ACE_toangle, 1);
ui_manager->DefineACECommand("show", ACE_show, 0);
ui_manager->DefineACECommand("hide", ACE_hide, 0);
ui_manager->DefineACECommand("globalfade", ACE_globalfade, 1);
}
return ui_manager;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,9 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_camera.h"
using namespace GS::S2D;

View File

@ -0,0 +1,301 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include <float.h>
#include "ui/ui_cursor.h"
#include "ui/ui.h"
#include "ui/ui_window.h"
#include "script/script_engine_types.h"
#include "script/script_variant.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool Scene::CallEventHandler(Cursor *cursor, EventCode event_code, EventTable *event_table)
{
EventHandler *handler = event_table ? event_table->GetHandler(event_code) : NULL;
if (!handler)
return false;
if (vm->SetupFunctionCall(NULL, handler->GetHandler(), handler->GetContext()))
{
AutoPtr <Script::Object> table_object(vm->CreateTable());
table_object->Set("sprite", Script::Variant(cursor->current_state.item, Script::typetag_Window));
table_object->Set("window", Script::Variant(cursor->current_state.item, Script::typetag_Window));
table_object->Set("widget", Script::Variant(cursor->current_state.widget, Script::typetag_Widget));
if (cursor->current_state.widget)
table_object->Set("id", Script::Variant(cursor->current_state.widget->GetId()));
table_object->Set("cursor_id", cursor->id);
table_object->Set("x", cursor->current_state.x);
table_object->Set("y", cursor->current_state.y);
table_object->Set("dx", cursor->current_state.x - cursor->previous_state.x);
table_object->Set("dy", cursor->current_state.y - cursor->previous_state.y);
table_object->Set("down", cursor->current_state.down);
// Cursor position in sprite.
if (cursor->current_state.item)
{
Vector2 c_pos = cursor->current_state.item->ScreenToLocal(Vector2(cursor->current_state.x, cursor->current_state.y));
table_object->Set("local_x", c_pos.x);
table_object->Set("local_y", c_pos.y);
if (cursor->previous_state.item == cursor->current_state.item)
{
Vector2 p_pos = cursor->previous_state.item->ScreenToLocal(Vector2(cursor->previous_state.x, cursor->previous_state.y));
table_object->Set("local_dx", c_pos.x - p_pos.x);
table_object->Set("local_dy", c_pos.y - p_pos.y);
}
else
{
table_object->Set("local_dx", 0);
table_object->Set("local_dy", 0);
}
}
vm->PushArgument(event_code);
vm->PushArgument(table_object.c_ptr());
if (!vm->DoFunctionCall())
__ERR__(__LOG_E__ << "Event handler (" << event_code << ") call failed. The handler parameters should be (event, table).\n", false)
return true;
}
return false;
}
void Scene::CallEventHandler(Cursor *cursor, Widget *widget, EventCode event_code, bool can_propagate)
{
for (Widget *base = widget; base; base = base->GetParent())
{
if (CallEventHandler(cursor, event_code, base->GetEventTable()))
return;
if (!can_propagate)
break;
}
// Try the sprite event handler.
if (can_propagate && cursor->current_state.item.IsValid())
CallEventHandler(cursor, event_code, cursor->current_state.item->GetEventTable());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Widget *Scene::RecurseWidgetBelowCursor(Window *window, Widget *widget, int mx, int my)
{
if (!window || !widget)
return NULL;
ListForeachPtr(Widget *, c, widget->GetChildren())
{
Rect <int> rect(c->GetRect());
if (!c->IsHidden() && window->LocalToScreen(rect).Inside(mx, my))
{
Widget *sub_w = RecurseWidgetBelowCursor(window, c, mx, my);
return sub_w ? sub_w : c;
}
}
return widget;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::ProcessCursorEnterLeaveWidget(Cursor *cursor, Window *window, Widget *widget)
{
if (widget && !widget->IsHidden())
{
// Process on widget.
iRect screen_rect = window->LocalToScreen(widget->GetRect());
if (screen_rect.Inside((int)cursor->current_state.x, (int)cursor->current_state.y))
{
if (!screen_rect.Inside((int)cursor->previous_state.x, (int)cursor->previous_state.y))
CallEventHandler(cursor, widget, Event_CursorEnter, false);
}
else
if (screen_rect.Inside((int)cursor->previous_state.x, (int)cursor->previous_state.y))
CallEventHandler(cursor, widget, Event_CursorLeave, false);
// Process on widget children.
ListForeachPtr(Widget *, c, widget->GetChildren())
ProcessCursorEnterLeaveWidget(cursor, window, c);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::UpdateCursor(Cursor *cursor)
{
Cursor::State &p_state = cursor->previous_state,
&c_state = cursor->current_state,
&down_state = cursor->down_state;
// Assert lock sprite validity.
if (lock && !item_list.Find(lock))
lock = NULL;
// Move cursor position in system reference.
Vector4 c_ui = screen_to_ui * Vector4(c_state.x, c_state.y, 1);
// __LOG__ << "x: " << c_ui.x << ", y: " << c_ui.y << "\n";
c_state.x = c_ui.x;
c_state.y = c_ui.y;
// Determine the current sprite under the cursor.
if (lock)
c_state.item = lock;
else
{
float min_z_order = FLT_MAX;
c_state.item = NULL;
for (List <Item *> ::Item *e = item_list.GetLast(); e; e = e->Previous())
{
Item *i = e->Object();
switch (i->GetItemType())
{
case Item::Type_Sprite:
case Item::Type_Window:
{
Sprite *s = (Sprite *)i;
if (s->opacity == 0.0)
break;
if (s->sprite_flags.IsSet(Sprite::FlagNonSensitive))
break;
Rect <int> wrect(s->GetRect());
if (s->LocalToScreen(wrect).Inside((int)c_state.x, (int)c_state.y) && (min_z_order > s->GetZOrder()))
{
min_z_order = s->GetZOrder();
c_state.item = s;
}
}
break;
}
}
}
// Determine the current widget under the cursor.
c_state.widget = NULL;
if (c_state.item && (c_state.item->GetItemType() == Item::Type_Window))
{
Window *w = (Window *)c_state.item.c_ptr();
c_state.widget = RecurseWidgetBelowCursor(w, w->GetBaseWidget(), (int)c_state.x, (int)c_state.y);
}
// State must be complete from here on.
// Store down state.
if (c_state.down && !p_state.down)
down_state = c_state;
// Handle cursor up event (done here so that the down_state widget/sprite will always catch the event).
if (p_state.down && !c_state.down)
{
if (down_state.widget)
CallEventHandler(cursor, down_state.widget, Event_CursorUp);
else if (down_state.item)
CallEventHandler(cursor, Event_CursorUp, down_state.item->GetEventTable());
}
// Handle hit/down/move cursor events.
if (c_state.widget)
{
if (p_state.down && !c_state.down)
{
if (c_state.widget == down_state.widget)
CallEventHandler(cursor, c_state.widget, Event_CursorHit);
}
if (!p_state.down && c_state.down)
CallEventHandler(cursor, c_state.widget, Event_CursorDown);
if ((c_state.widget == p_state.widget) && ((c_state.x != p_state.x) || (c_state.y != p_state.y)))
CallEventHandler(cursor, c_state.widget, Event_CursorMove);
}
else
if (c_state.item)
{
if (p_state.down && !c_state.down)
{
if (c_state.item == down_state.item)
CallEventHandler(cursor, Event_CursorHit, c_state.item->GetEventTable());
}
if (!p_state.down && c_state.down)
CallEventHandler(cursor, Event_CursorDown, c_state.item->GetEventTable());
if ((c_state.item == p_state.item) && ((c_state.x != p_state.x) || (c_state.y != p_state.y)))
CallEventHandler(cursor, Event_CursorMove, c_state.item->GetEventTable());
}
// Handle enter/leave cursor events.
if (c_state.item)
{
if (c_state.item->GetItemType() == Item::Type_Window)
{
Window *w = (Window *)c_state.item.c_ptr();
ProcessCursorEnterLeaveWidget(cursor, w, w->GetBaseWidget());
}
if (c_state.item != p_state.item)
CallEventHandler(cursor, Event_CursorEnter, c_state.item->GetEventTable());
}
if (p_state.item)
{
if (p_state.item->GetItemType() == Item::Type_Window)
{
Window *w = (Window *)p_state.item.c_ptr();
ProcessCursorEnterLeaveWidget(cursor, w, w->GetBaseWidget());
}
if (p_state.item != c_state.item)
CallEventHandler(cursor, Event_CursorLeave, p_state.item->GetEventTable());
}
#if 0
if ((c_state.x != p_state.x) || (c_state.y != p_state.y))
{
__LOG__ << "CURSOR ID = " << cursor->id << "\n";
__LOG__ << "\n";
__LOG__ << "X = " << c_state.x << ", Y = " << c_state.y << "\n";
if (c_state.item)
__LOG__ << "PX = " << c_state.item->GetPosition().x << ", PY = " << c_state.item->GetPosition().y << "\n";
if (Sprite *sprite = (Sprite *)c_state.item)
{
__LOG__ << "SPRITE = ";
if (sprite)
__LOG__ << (int)sprite;
else
__LOG__ << "None";
}
__LOG__ << ", WIDGET = ";
if (c_state.widget)
{
__LOG__ << (int)c_state.widget << " (Id = " << c_state.widget->GetId() << "), type = " << c_state.widget->GetType() << "\n";
nRect <int> rect = c_state.widget->GetRect();
__LOG__ << "SX = " << rect.sx << ", SY = " << rect.sy << ", W = " << rect.GetWidth() << ", EY = " << rect.GetHeight() << "\n";
}
else
__LOG__ << "None";
__LOG__ << "\n";
}
#endif
p_state = c_state;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,48 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_event_handler.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
EventHandler *EventTable::GetHandler(EventCode code) const
{
ListForeachPtr(EventHandler *, h, handler_list)
if (h->GetCode() == code)
return h;
return NULL;
}
EventHandler *EventTable::SetHandler(EventCode code, GS::Script::Object *h, GS::Script::Object *c)
{
EventHandler *handler = GetHandler(code);
if (!handler)
{
handler = new EventHandler(code);
handler_list.Add(handler);
}
handler->handler = h;
handler->context = c;
return handler;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void EventTable::DeleteHandler(EventCode code)
{
handler_list.Remove(GetHandler(code));
}
bool EventTable::HasHandlerContext(EventCode code) const
{
EventHandler *handler = GetHandler(code);
if (!handler)
return false;
return asbool(handler);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,20 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_group.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool Group::IsMember(const Item *item) const
{
ListForeachPtr(Item *, i, item_list)
if (i == item)
return true;
return false;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,162 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item.h"
#include "ui/ui_item_automated_property_provider.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Item::SetParent(Item *item)
{
if (parent)
parent->GetChildren().Remove(this);
if ((parent = item) != NULL)
parent->GetChildren().Add(this);
}
bool Item::Inherits(const Item *item) const
{
if (this == item)
return true;
for (Item *p = GetParent(); p; p = p->GetParent())
if (p == item)
return true;
return false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Item::SnapshotTransformation(const Matrix3 &matrix)
{
Vector4 p = matrix.GetRow(2);
SetPosition(p.x, p.y);
Vector2 u(matrix.m[0][0], matrix.m[1][0]),
v(matrix.m[0][1], matrix.m[1][1]);
SetScale(u.Len(), v.Len());
u.Normalize();
float a = Math::ACos(u.x);
if (u.y < 0.f)
a = 2.f * Math::Pi - a;
SetRotation(a);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Item::ComputeMatrix()
{
local_matrix = Matrix3::RotationMatrixZAxis(angle);
local_matrix.m[0][2] = position.x;
local_matrix.m[1][2] = position.y;
local_matrix = local_matrix * Matrix3(scale.x, 0, 0, 0, scale.y, 0, -pivot.x * scale.x, -pivot.y * scale.y, 1);
if (GetParent())
{
GetParent()->ComputeMatrix();
matrix = GetParent()->GetMatrix() * local_matrix;
}
else
matrix = local_matrix;
matrix.Inverse(imatrix);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
iRect Item::GetRect() const
{ return iRect(0, 0, (int)size.x, (int)size.y); }
iRect Item::GetScreenRect() const
{
Vector4 _v[4], _o[4];
_v[0].Set(0, 0, 1);
_v[1].Set(size.x, 0, 1);
_v[2].Set(size.x, size.y, 1);
_v[3].Set(0, size.y, 1);
matrix.Apply(_o, _v, 4);
Vector4 mn = _o[0], mx = _o[0];
for (int n = 1; n < 4; ++n)
{
mn = Vector4::Minimum(mn, _o[n]);
mx = Vector4::Maximum(mx, _o[n]);
}
return iRect((int)mn.x, (int)mn.y, (int)mx.x, (int)mx.y);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
iRect Item::LocalToScreen(const iRect &r) const
{
Vector4 sxy((float)r.sx, (float)r.sy, 1, 1), exy((float)r.ex, (float)r.ey, 1, 1);
Vector4 tsxy = sxy * matrix, texy = exy * matrix;
return iRect((int)tsxy.x, (int)tsxy.y, (int)texy.x, (int)texy.y);
}
iRect Item::ScreenToLocal(const iRect &r) const
{
Vector4 sxy((float)r.sx, (float)r.sy, 1, 1), exy((float)r.ex, (float)r.ey, 1, 1);
Vector4 tsxy = sxy * imatrix, texy = exy * imatrix;
return iRect((int)tsxy.x, (int)tsxy.y, (int)texy.x, (int)texy.y);
}
Vector2 Item::LocalToScreen(const Vector2 &v) const
{
Vector4 o = Vector4(v.x, v.y, 1) * matrix;
return Vector2(o.x, o.y);
}
Vector2 Item::ScreenToLocal(const Vector2 &v) const
{
Vector4 o = Vector4(v.x, v.y, 1) * imatrix;
return Vector2(o.x, o.y);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Item::Setup()
{
item_event->OnSetup(this);
item_event->OnSetupDone(this);
}
void Item::Reset()
{
SetPivot(0, 0);
SetScale(1, 1);
SetZOrder(0.5);
SetRotation(0);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Item::Item()
{
uid = uint(~0);
item_flags.Raise(Flag_ItemActive);
type = Type_None;
parent = 0;
Reset();
item_event = new IItemEvent;
automation_player = new GS::Automation::Player;
automation_player->property_provider = new Automation::ItemPropertyProvider(this);
}
Item::~Item()
{
SetParent(NULL);
ListForeachPtr(Item *, c, children)
c->SetParent(NULL);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,50 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item_automated_property_provider.h"
#include "ui/ui_item.h"
using GS::Quaternion;
using namespace GS::Core;
using namespace GS::S2D::Automation;
//------------------------------------------------------------------------------
bool ItemPropertyProvider::GetProperty(MotionChannel::Type type, float &v)
{
switch (type)
{
case MotionChannel::XPos: v = item->GetPosition().x; return true;
case MotionChannel::YPos: v = item->GetPosition().y; return true;
case MotionChannel::ZRot: v = item->GetRotation(); return true;
case MotionChannel::XScl: v = item->GetScale().x; return true;
case MotionChannel::YScl: v = item->GetScale().y; return true;
}
return false;
}
bool ItemPropertyProvider::SetProperty(MotionChannel::Type type, float v)
{
Vector2 t;
switch (type)
{
case MotionChannel::XPos: t = item->GetPosition(); item->SetPosition(v, t.y); return true;
case MotionChannel::YPos: t = item->GetPosition(); item->SetPosition(t.x, v); return true;
case MotionChannel::ZRot: item->SetRotation(v); return true;
case MotionChannel::XScl: t = item->GetScale(); item->SetScale(v, t.y); return true;
case MotionChannel::YScl: t = item->GetScale(); item->SetScale(t.x, v); return true;
}
return false;
}
Quaternion ItemPropertyProvider::GetRotation() const
{
return Quaternion::FromEuler(0, 0, item->GetRotation());
}
bool ItemPropertyProvider::SetRotation(const Quaternion &q)
{
item->SetRotation(q.AsMatrix3().AsEuler().z);
return true;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,93 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item.h"
#include "math/vector_nml.h"
#include "log/log.h"
using namespace GS::S2D;
using GS::NML::Tag;
//------------------------------------------------------------------------------
bool Item::FromMetaTag(Tag &tag)
{
if (tag.name != "Item")
__ERR__(__LOG_E__ << "Could not parse sprite, incorrect root tag (" << tag.name << ").\n", false)
Reset();
NMLTagForeach(pt, tag)
{
if (pt->name == "Uid")
uid = pt->GetUnsigned();
else if (pt->name == "Name")
name = pt->GetString();
else if (pt->name == "Active")
item_flags |= Flag_ItemActive;
else if (pt->name == "Position")
tVectorFromMetaTag(position, *pt);
else if (pt->name == "Size")
{
Vector2 v;
tVectorFromMetaTag(v, *pt);
SetSize(v.x, v.y);
}
else if (pt->name == "Pivot")
tVectorFromMetaTag(pivot, *pt);
else if (pt->name == "Scale")
tVectorFromMetaTag(scale, *pt);
else if (pt->name == "Angle")
angle = pt->GetReal();
else if (pt->name == "ZOrder")
zorder = pt->GetReal();
else if (pt->name == "ScriptedObject")
{
if (scripted_object)
scripted_object->FromMetaTag(*pt);
}
else __LOG_W__ << "Unknown tag '" << pt->name << "' in <Item2d>.\n";
}
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Tag *Item::AsMetaTag() const
{
Tag *root = new Tag("Item");
if (!root)
__ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL)
root->AddChild("Name", name.toUtf8());
root->AddChild("Uid", GetUid());
if (item_flags.IsSet(Flag_ItemActive))
root->AddChild("Active");
root->AddChild(tVectorAsMetaTag(position, "Position"));
root->AddChild(tVectorAsMetaTag(size, "Size"));
if ((pivot.x != 0) || (pivot.y != 0))
root->AddChild(tVectorAsMetaTag(pivot, "Pivot"));
if ((scale.x != 1) || (scale.y != 1))
root->AddChild(tVectorAsMetaTag(scale, "Scale"));
if (GetZOrder() != 0.5)
root->AddChild("ZOrder", GetZOrder());
if (GetRotation() != 0)
root->AddChild("Angle", angle);
// Components.
if (scripted_object.IsValid())
root->AddChild(scripted_object->AsMetaTag());
return root;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,81 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item_script_event.h"
#include "ui/ui_item_scripted_object.h"
#include "ui/ui_item_script_unit.h"
#include "ui/ui_item.h"
#include "physic/physic_world.h"
#include "script/script_engine_types.h"
#include "script/script_variant.h"
using namespace GS::Script;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void ItemScriptEvent::OnSetup(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnSetup"))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnSetupDone(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnSetupDone"))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnReset(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnReset"))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnActivate(Item *item, bool activate)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (((ItemScriptUnit *)unit)->activation_callback && unit->SetupFunctionCall("OnActivate", ((ItemScriptUnit *)unit)->activation_callback))
{
unit->PushFunctionCallArgument(activate);
unit->DoFunctionCall();
}
}
void ItemScriptEvent::OnUpdate(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (((ItemScriptUnit *)unit)->update_callback && unit->SetupFunctionCall("OnUpdate", ((ItemScriptUnit *)unit)->update_callback))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnPhysicStep(Item *item, bool step_taken)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (((ItemScriptUnit *)unit)->physic_callback && unit->SetupFunctionCall("OnPhysicStep", ((ItemScriptUnit *)unit)->physic_callback))
{
unit->PushFunctionCallArgument(step_taken);
unit->DoFunctionCall();
}
}
void ItemScriptEvent::OnRenderDone(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnRenderDone"))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnRenderUser(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (((ItemScriptUnit *)unit)->render_user_callback && unit->SetupFunctionCall("OnRenderUser", ((ItemScriptUnit *)unit)->render_user_callback))
unit->DoFunctionCall();
}
void ItemScriptEvent::OnDelete(Item *item)
{
ListForeachPtr(Unit *, unit, item->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnDelete"))
unit->DoFunctionCall();
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,45 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item_script_unit.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool ItemScriptUnit::Open()
{
if (!Script::Unit::Open())
return false;
update_callback = vm->GetObjectFromName("OnUpdate", self);
trigger_callback = vm->GetObjectFromName("OnTrigger", self);
activation_callback = vm->GetObjectFromName("OnActivate", self);
physic_callback = vm->GetObjectFromName("OnPhysicStep", self);
collision_callback = vm->GetObjectFromName("OnCollision", self);
collisionex_callback = vm->GetObjectFromName("OnCollisionEx", self);
render_user_callback = vm->GetObjectFromName("OnRenderUser", self);
return true;
}
void ItemScriptUnit::Close()
{
update_callback = NULL;
trigger_callback = NULL;
activation_callback = NULL;
physic_callback = NULL;
physic_sleep_callback = NULL;
collision_callback = NULL;
collisionex_callback = NULL;
render_user_callback = NULL;
Script::Unit::Close();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
ItemScriptUnit::ItemScriptUnit(GS::Script::IVM *vm) : Unit(vm) {}
ItemScriptUnit::~ItemScriptUnit() { Close(); }
//------------------------------------------------------------------------------

View File

@ -0,0 +1,27 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_item_scripted_object.h"
#include "ui/ui_item_script_unit.h"
#include "ui/ui_item.h"
#include "script/script_engine_types.h"
#include "log/log.h"
using namespace GS::Script;
using namespace GS::S2D;
//------------------------------------------------------------------------------
Unit *ItemScriptedObject::NewUnit() const
{
Unit *unit = new ItemScriptUnit(vm);
if (!unit)
__ERR__(__LOG_E__ << "Failed to allocate new item script unit.", NULL);
unit->SetInterfaceObject(item, Script::typetag_UIItem);
return unit;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,11 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_message.h"
using namespace GS::S2D;
GS::Messaging::Broadcaster <Message, Listener, Scene *> GS::S2D::g_ui_messenger;

View File

@ -0,0 +1,216 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui.h"
#include "ui/ui_window.h"
#include "ui/ui_group.h"
#include "core/tool_mode.h"
#include "script/scripted_object.h"
#include "script/script_unit.h"
#include "timing/benchmark.h"
#include "metafile/nml.h"
#include "log/log.h"
using namespace GS::NML;
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool Scene::FromMetaFileStoreGroup(const char *path, Group **group, uint flag, GS::ToolMode tool_mode, int load_level)
{
NML::File file;
if (!NML::Parser::Load(path, file))
return false;
if (Tag *scene_tag = file.GetTag("Scene2D"))
{
if (FromMetaTagStoreGroup(*scene_tag, group, flag, tool_mode, load_level))
name = path;
}
else
__ERR__(__LOG_E__ << "No <Scene2D> tag in '" << path << "'.\n", false)
if (group && group[0])
group[0]->name = path;
return true;
}
static bool ShouldLoadItem(GS::ToolMode mode, Tag *pt, uint flag, int load_level)
{
if (pt->GetTag("Item:ToolSpecific;") || pt->GetTag("Item:Helper;"))
{
if (!(flag & SceneIOHelper))
return false;
// Do not load tool specific items in no tool or project preview modes.
if ((mode == GS::NoTool) || (mode == GS::ToolProjectPreview))
return false;
// Do not load tool specific items in no tool mode above the first load level.
if (load_level > 0)
return false;
}
return true;
}
template <class T> static T *LoadItemDerived(Scene *scene, T *i, GS::Map <uint, uint> &uid_map, Tag *t, uint type_flag, const uint load_flag, int load_level, GS::ToolMode tool_mode)
{
if (!(load_flag & type_flag) || !ShouldLoadItem(tool_mode, t, load_flag, load_level))
{
delete i;
return NULL;
}
scene->SetupItemComponents(i);
if (i->FromMetaTag(*t))
{
uint olduid = i->GetUid(); // uid from source scene
scene->AddItem(i, false); // add to live scene
uid_map.Add(olduid, i->GetUid()); // store map from source to live scene
}
return i;
}
bool Scene::FromMetaTagStoreGroup(const Tag &tag, Group **group, uint load_flag, GS::ToolMode tool_mode, int load_level)
{
if (tag.name != "Scene2D")
__ERR__(__LOG_E__ << "Could not parse UI scene, incorrect root tag (" << tag.name << ").\n", false)
Benchmark bench(true);
// Read items and setup uid remap array.
Map <uint, uint> uid_map;
if (Tag *itag = tag.GetTag("Items"))
{
// Item count in scene.
uint item_to_load = 0;
NMLTagForeach(pt, *itag)
if (Tag *item_tag = pt->GetTag("Item;"))
item_to_load++;
NMLTagForeach(pt, *itag)
{
Item *citem = NULL;
if (pt->name == "Sprite")
citem = LoadItemDerived(this, new Sprite, uid_map, pt, SceneIOSprite, load_flag, load_level, tool_mode);
else if (pt->name == "Window")
citem = LoadItemDerived(this, new Window, uid_map, pt, SceneIOWindow, load_flag, load_level, tool_mode);
else
__LOG_W__ << "Unexpected <" << pt->name << "> sub-tag in <Items>.\n";
if (citem)
{
// Add item to the scene group.
if (group && group[0])
group[0]->item_list.Add(citem);
}
}
}
// Script unit.
if (load_flag & SceneIOScript)
{
if (Tag *stag = tag.GetTag("ScriptedObject"))
scripted_object->FromMetaTag(*stag);
#if 1 // Compatibility
else
if (Tag *stag = tag.GetTag("ScriptUnit"))
if (Script::Unit *unit = scripted_object->AddUnit(scripted_object->NewUnit()))
unit->FromMetaTag(*stag);
#endif
}
// Motion sets.
if (load_flag & SceneIOMotion)
if (Tag *ctag = tag.GetTag("SceneMotionContainer"))
motion.FromMetaTag(*ctag, &uid_map);
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Scene::IsItemToBeSaved(Item *i, const Group *group, uint flag) const
{
if (!i)
return false;
// Filter out irrelevant items.
if (group && !group->IsMember(i))
return false;
switch (i->GetItemType())
{
case Item::Type_Sprite: if (!(flag & SceneIOSprite)) return false; break;
case Item::Type_Window: if (!(flag & SceneIOWindow)) return false; break;
}
return true;
}
Tag *Scene::LinkInfoAsMetaTag(Item *i, const Group *group, uint flag) const
{
if (!IsItemToBeSaved(i, group, flag))
return NULL;
Item *l = i->GetParent();
if (!l)
return NULL;
if (!IsItemToBeSaved(l, group, flag))
return NULL;
// Save link information.
Tag *tag = new Tag("Link");
if (tag)
{
tag->AddChild("Item", i->GetUid());
tag->AddChild("Link", l->GetUid());
}
return tag;
}
Tag *Scene::AsMetaTag(const Group *group, uint save_flag, GS::ToolMode tool_mode) const
{
Tag *root = new Tag("Scene2D");
if (!root)
__ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL)
// Write script object.
if (scripted_object.IsValid() && !group)
root->AddChild(scripted_object->AsMetaTag());
// Write motion sets.
if (save_flag & SceneIOMotion)
root->AddChild(motion.AsMetaTag());
// Write managed items.
if (Tag *itag = root->AddChild("Items"))
ListForeachPtr(Item *, i, item_list)
{
if (group && !group->item_list.Find(i))
continue;
switch (i->GetItemType())
{
case Item::Type_Sprite: if (!(save_flag & SceneIOSprite)) continue; break;
case Item::Type_Window: if (!(save_flag & SceneIOWindow)) continue; break;
}
itag->AddChild(i->AsMetaTag());
}
else
__ERR__(__LOG_E__ << "Failed to allocate <Items> root tag.\n", NULL);
// Write link informations.
if (Tag *ltag = root->AddChild("Links"))
ListForeachPtr(Item *, i, item_list)
ltag->AddChild(LinkInfoAsMetaTag(i, group, save_flag));
else
__ERR__(__LOG_E__ << "Failed to allocate <Links> root tag.\n", NULL)
return root;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,24 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui.h"
#include "core/core_profiler.h"
#include "core/raster_font.h"
#include "core/renderer.h"
using namespace GS;
//------------------------------------------------------------------------------
void S2D::Scene::DrawProfilerText(Renderer &r, Render::RasterFont *font[2], float &x, float &y)
{
Color title_color(0.75, 0.5, 1);
Renderer::WriterConfig config(false);
r.Write(*font[1], "Scene 2D:\n\n", x, y, config, 1, &title_color);
r.Write(*font[0], String::Format("Window count = %d\n\n", item_list.GetCount()), x, y, config, 1, &Color::Yellow);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,89 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui.h"
#include "ui/ui_camera.h"
#include "ui/ui_sprite.h"
#include "core/renderer.h"
#include "gpu/gpu_triangle_batch.h"
using namespace GS;
using namespace S2D;
//------------------------------------------------------------------------------
static float ItemCompareDrawOrder(const S2D::Item *c, const S2D::Item *n)
{ return -(c->GetZOrder() - n->GetZOrder()); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::SetRenderMatrices(Renderer &renderer)
{
const Vector2 &resolution = current_camera->resolution;
float k_ar = (renderer.GetOutputAspectRatio() * renderer.GetGlobalAspectRatio()) / (resolution.y / resolution.x);
// UI to normalized screen and back.
ui_to_screen = Matrix3::TranslationMatrix(Vector2(0.5f, 0.5f)) *
(
(offset_matrix * Matrix3::ScaleMatrix(Vector2(k_ar / resolution.x, 1.f / resolution.y))) *
(Matrix3::TranslationMatrix(Vector2(-resolution.x * 0.5f, -resolution.y * 0.5f)) * current_camera->GetInverseMatrix())
);
ui_to_screen.Inverse(screen_to_ui);
// Render matrices.
Matrix4 identity(Matrix4::IdentityMatrix());
renderer.SetViewMatrix(identity, &identity);
renderer.SetWorldMatrix(identity, &identity);
Matrix3 projection(2.f * k_ar / resolution.x, 0, 0, 0, -2.f / resolution.y, 0, -1.f * k_ar, 1.f, 0.0f); // z = 0.0f
projection = offset_matrix * (projection * current_camera->GetInverseMatrix());
renderer.SetProjectionMatrix(Matrix4::FromMatrix3(projection));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::Render(Renderer &renderer, GPU::TriangleBatch *batch)
{
// Enforce window positioning.
item_list.MergeSort(ItemCompareDrawOrder);
// Render items.
SetRenderMatrices(renderer);
ListForeachPtr(Item *, i, item_list)
if (i->item_flags.IsSet(Item::Flag_ItemActive))
switch (i->GetItemType())
{
case Item::Type_Sprite:
case Item::Type_Window:
((Sprite *)i)->Render(renderer, batch);
break;
}
if (batch)
batch->Flush();
}
void Scene::RenderGlobalFade(Renderer &renderer)
{
if (global_fade_color.w < 0.01f)
return;
renderer.SetProjectionMatrix(Matrix4::IdentityMatrix());
// Setup attributes.
Vector4 vtx_attr[4];
vtx_attr[0].Set(-1, -1, 1);
vtx_attr[1].Set(1, -1, 1);
vtx_attr[2].Set(1, 1, 1);
vtx_attr[3].Set(-1, 1, 1);
Color color_attr[4];
for (uint n = 0; n < 4; ++n)
color_attr[n] = global_fade_color;
ushort idx[6] = { 2, 1, 0, 3, 2, 0 };
renderer.DrawTriangle(2, vtx_attr, idx, color_attr, NULL, NULL, Core::Material::Blend_Alpha, Core::Material::Render_NoZTest);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,40 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_scene_script_event.h"
#include "ui/ui_script_unit.h"
#include "ui/ui.h"
#include "script/scripted_object.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
void SceneScriptEvent::OnSetup(Scene *scene)
{
ListForeachPtr(Script::Unit *, unit, scene->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnSetup"))
unit->DoFunctionCall(0);
}
void SceneScriptEvent::OnReset(Scene *scene)
{
ListForeachPtr(Script::Unit *, unit, scene->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnReset"))
unit->DoFunctionCall(0);
}
void SceneScriptEvent::OnUpdate(Scene *scene)
{
ListForeachPtr(Script::Unit *, unit, scene->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnUpdate", ((SceneUnit *)unit)->frame_callback))
unit->DoFunctionCall(0);
}
void SceneScriptEvent::OnDelete(Scene *scene)
{
ListForeachPtr(Script::Unit *, unit, scene->scripted_object->GetUnitList())
if (unit->SetupFunctionCall("OnDelete"))
unit->DoFunctionCall(0);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,25 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_scene_scripted_object.h"
#include "ui/ui_script_unit.h"
#include "script/script_engine_types.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
Script::Unit *SceneScriptedObject::NewUnit() const
{
Script::Unit *unit = new SceneUnit(vm);
if (!unit)
__ERR__(__LOG_E__ << "Failed to allocate new UI scene script unit.", NULL);
unit->SetInterfaceObject(scene, Script::typetag_Scene2d);
return unit;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,32 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_script_unit.h"
using namespace GS::Script;
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool SceneUnit::Open()
{
if (!Unit::Open())
return false;
frame_callback = vm->GetObjectFromName("OnUpdate", self);
return true;
}
void SceneUnit::Close()
{
frame_callback = NULL;
Unit::Close();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SceneUnit::SceneUnit(IVM *vm) : Unit(vm) {}
SceneUnit::~SceneUnit() { Close(); }
//------------------------------------------------------------------------------

View File

@ -0,0 +1,67 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_sprite.h"
#include "ui/ui_ace_manager.h"
#include "core/render_resource_factory.h"
#include "core/camera.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Sprite::RenderSetup(Core::ResourceFactories *f)
{
if ((render_data = new RenderData))
if (f && f->render)
if (!texture.IsEmpty())
render_data->texture = f->render->LoadTexture(texture);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Sprite::ExecCommand(ACE::Command *cmd, float dt)
{
float k = dt / cmd->duration_left;
switch (cmd->code)
{
case ACE_toalpha:
opacity = Types::Clamp(opacity + (cmd->parm[0] - opacity) * k);
return true;
case ACE_toposition:
position.x += (cmd->parm[0] - position.x) * k;
position.y += (cmd->parm[1] - position.y) * k;
SetPosition(position.x, position.y);
return true;
case ACE_toscale:
scale.x += (cmd->parm[0] - scale.x) * k;
scale.y += (cmd->parm[1] - scale.y) * k;
return true;
case ACE_toangle:
angle += (Units::Deg(cmd->parm[0]) - angle) * k;
SetRotation(angle);
return true;
}
return ACE::Unit::ExecCommand(cmd, dt);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Sprite::Sprite()
{
opacity = 1;
uv_origin.Set(0, 0);
type = Type_Sprite;
event_table = new EventTable;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,95 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_sprite.h"
#include "ui/ui.h"
#include "metafile/nml.h"
#include "log/log.h"
using namespace GS::S2D;
using GS::NML::Tag;
//------------------------------------------------------------------------------
bool Sprite::FromMetaTag(Tag &tag)
{
if (tag.name != "Sprite")
__ERR__(__LOG_E__ << "Could not parse sprite, incorrect root tag (" << tag.name << ").\n", false)
opacity = 1.f;
// Parse root tags.
NMLTagForeach(pt, tag)
{
if (pt->name == "Item")
Item::FromMetaTag(*pt);
else if (pt->name == "Opacity")
opacity = pt->GetReal();
else if (pt->name == "Flag")
{
NMLTagForeach(st, *pt)
{
if (st->name == "FlipU")
sprite_flags.Raise(FlagFlipU, true);
else if (st->name == "FlipV")
sprite_flags.Raise(FlagFlipV, true);
else if (st->name == "Opaque")
sprite_flags |= FlagBlendOpaque;
else if (st->name == "Additive")
sprite_flags |= FlagBlendAdditive;
else if (st->name == "NonSensitive")
sprite_flags |= FlagNonSensitive;
else if (st->name == "ResolutionInvariant")
sprite_flags |= FlagResolutionInvariant;
else if (st->name == "TransformUV")
sprite_flags |= FlagTransformUV;
}
}
else if (pt->name == "Texture")
texture = pt->GetString();
else __LOG_W__ << "Unknown tag '" << pt->name << "' in <Sprite2d>.\n";
}
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Tag *Sprite::AsMetaTag() const
{
Tag *root = new Tag("Sprite");
if (!root)
__ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL)
root->AddChild(Item::AsMetaTag());
if (opacity != 1.f)
root->AddChild("Opacity", opacity);
if ((type == Type_Sprite) && !texture.IsEmpty())
root->AddChild("Texture", texture.c_str());
if (Tag *flag_tag = root->AddChild("Flag"))
{
if (sprite_flags.IsSet(FlagFlipU))
flag_tag->AddChild("FlipU");
if (sprite_flags.IsSet(FlagFlipV))
flag_tag->AddChild("FlipV");
if (sprite_flags.IsSet(FlagNonSensitive))
flag_tag->AddChild("NonSensitive");
if (sprite_flags.IsSet(FlagBlendAdditive))
flag_tag->AddChild("Additive");
if (sprite_flags.IsSet(FlagResolutionInvariant))
flag_tag->AddChild("ResolutionInvariant");
if (sprite_flags.IsSet(FlagTransformUV))
flag_tag->AddChild("TransformUV");
}
return root;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,113 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_sprite.h"
#include "gpu/gpu_triangle_batch.h"
#include "core/renderer.h"
using namespace GS::Render;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Sprite::Render(Renderer &render, GS::GPU::TriangleBatch *batch)
{
if (render_data.IsNull())
return;
if (opacity < 0.003f)
return;
ComputeMatrix();
// Test visibility.
bool should_show = true;
float final_opacity = opacity;
for (Item *p = GetParent(); p; p = p->GetParent())
if (Sprite *sp = (Sprite *)p)
final_opacity *= sp->opacity;
if (final_opacity < 0.003f)
should_show = false;
// Compute hierarchy matrix, opacity and visibility.
if (sprite_flags.IsSet(FlagSnapToPixel))
{
matrix.m[0][2] = Math::Floor(matrix.m[0][2]);
matrix.m[1][2] = Math::Floor(matrix.m[1][2]);
}
if (!should_show) // [EJ] do not move before matrix is updated
return;
Texture *t = render_data->texture;
if (t && t->format != Texture::FormatInvalid)
{
Vector4 vtx[4];
vtx[0].Set(0, 0, 1);
vtx[1].Set(size.x, 0, 1);
vtx[2].Set(size.x, size.y, 1);
vtx[3].Set(0, size.y, 1);
Vector4 vtx_attr[4];
matrix.Apply(vtx_attr, vtx, 4); // transform on the CPU for the batch system
Color color_attr[4];
for (uint n = 0; n < 4; ++n)
color_attr[n].Set(1, 1, 1, final_opacity);
Vector2 uv_attr[4];
float su = uv_origin.x / float(t->GetWidth()),
sv = uv_origin.y / float(t->GetHeight()),
eu = (uv_origin.x + size.x) / float(t->GetWidth()),
ev = (uv_origin.y + size.y) / float(t->GetHeight());
if (sprite_flags.IsSet(FlagFlipU)) Types::swap(su, eu);
if (sprite_flags.IsSet(FlagFlipV)) Types::swap(sv, ev);
if (sprite_flags.IsSet(FlagTransformUV))
{
Vector4 s_uv[4], o_uv[4];
s_uv[0].Set(su, sv, 1);
s_uv[1].Set(eu, sv, 1);
s_uv[2].Set(eu, ev, 1);
s_uv[3].Set(su, ev, 1);
uv_matrix.Apply(o_uv, s_uv, 4);
for (int n = 0; n < 4; ++n)
uv_attr[n].Set(o_uv[n].x, o_uv[n].y);
}
else
{
uv_attr[0].Set(su, sv);
uv_attr[1].Set(eu, sv);
uv_attr[2].Set(eu, ev);
uv_attr[3].Set(su, ev);
}
// Blend mode.
using Core::Material;
Material::BlendOperator blend_op;
if (sprite_flags.IsSet(FlagBlendOpaque))
blend_op = final_opacity < 1.f ? Material::Blend_Alpha : Material::Blend_None;
else blend_op = sprite_flags.IsSet(FlagBlendAdditive) ? Material::Blend_Add : Material::Blend_Alpha;
Material::RenderWord render_word = Material::RenderWord(Material::Render_NoZWrite | Material::Render_NoZTest);
// Draw.
ushort idx[6] = { 0, 1, 2, 0, 2, 3 };
if (batch)
batch->DrawTriangle(2, 4, vtx_attr, idx, color_attr, uv_attr, render_data->texture, blend_op, render_word);
else
render.DrawTriangle(2, vtx_attr, idx, color_attr, uv_attr, render_data->texture, blend_op, render_word);
}
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,70 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui.h"
#include "ui/ui_camera.h"
#include "ui/ui_sprite.h"
#include "ui/ui_ace_manager.h"
#include "ui/ui_scene_script_event.h"
#include "ui/ui_scene_scripted_object.h"
#include "ui/ui_item_script_event.h"
#include "ui/ui_item_scripted_object.h"
#include "script/script_engine_types.h"
#include "script/script_variant.h"
#include "log/log.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Scene::SetAsScriptGlobalScene(GS::Script::IVM *_vm)
{
if (!_vm)
_vm = vm;
if (!_vm || !_vm->IsOpen())
return;
_vm->Set("g_scene", GS::Script::Variant(this, GS::Script::typetag_Scene2d));
_vm->Set("g_clock_fq", GS::Platform::Get().GetClockFrequency());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Scene::Update()
{
if (clock->GetRefCount() == 1)
clock->Update();
float dt = clock->GetDeltaf();
// ACE update.
ACEManager::Get()->UpdateACEUnit(this, dt);
ListForeachPtr(Item *, i, item_list)
{
i->automation_player->Evaluate(Time::fromSec(dt));
switch (i->GetItemType())
{
case Item::Type_Sprite:
case Item::Type_Window:
{
Sprite *s = (Sprite *)i;
ACEManager::Get()->UpdateACEUnit(s, dt);
}
break;
}
}
//
// Script events.
// if (eval_flag & SceneUpdateEvent)
{
scene_event->OnUpdate(this);
ListForeachPtr(Item *, i, item_list)
i->item_event->OnUpdate(i);
}
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,365 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_window.h"
#include "ui/widget_text.h"
#include "core/renderer_toolbox.h"
#include "core/render_resource_factory.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
iRect Window::GetRect() const
{
if (!window_flags.IsSet(Window::FlagNoDecoration))
if (skin.IsValid())
return iRect(0, 0, (int)size.x, (int)skin->top->GetHeight());
return iRect(0, 0, (int)size.x, (int)size.y);
}
iRect Window::GetClientRect() const
{
if (!window_flags.IsSet(Window::FlagNoDecoration))
if (skin.IsValid())
return iRect(skin->left->GetWidth(), skin->top_left->GetHeight(), int(size.x - skin->right->GetWidth()), int(size.y - skin->bottom_right->GetHeight()));
return iRect(0, 0, (int)size.x, (int)size.y);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::SetSize(float _w, float _h)
{
uint w = (uint)_w, h = (uint)_h;
if (cache.IsValid())
{
if (w > cache->GetWidth() || h > cache->GetHeight() || w < (cache->GetWidth() / 2) || h < (cache->GetHeight() / 2))
{
cache->AllocAs(w, h);
if (render_data && render_data->texture)
render_data->texture->Resize(w, h);
}
}
Invalidate();
Sprite::SetSize(_w, _h);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Widget *Window::GetTitleWidget() const
{ return title_widget; }
void Window::SetTitleWidget(Widget *w)
{
title_widget = w;
Invalidate();
}
Widget *Window::GetBaseWidget() const
{ return base_widget; }
void Window::SetBaseWidget(Widget *w)
{
base_widget = w;
Invalidate();
}
Widget *Window::GetWidget(uint id)
{ return base_widget ? base_widget->GetChild(id) : NULL; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::ComposeSkin()
{
if (skin.IsNull())
return;
cache->Fill(0, 0, 0, 0);
// Fill main area.
Rect <int> rect(GetRect());
rect.sx = skin->top_left->GetWidth();
rect.sy = skin->top_left->GetHeight();
rect.ex -= skin->bottom_right->GetWidth();
rect.ey -= skin->bottom_right->GetHeight();
Color _skin_color(skin->color);
cache->Fill(_skin_color.x, _skin_color.y, _skin_color.z, _skin_color.w, &rect);
// Blit corners.
Picture::Blit(*skin->top_left, *cache);
rect = GetRect();
rect.sx = rect.ex - skin->top_right->GetWidth();
Picture::Blit(*skin->top_right, *cache, NULL, &rect);
rect = GetRect();
rect.sy = rect.ey - skin->bottom_left->GetHeight();
Picture::Blit(*skin->bottom_left, *cache, NULL, &rect);
rect = GetRect();
rect.sx = rect.ex - skin->bottom_right->GetWidth();
rect.sy = rect.ey - skin->bottom_right->GetHeight();
Picture::Blit(*skin->bottom_right, *cache, NULL, &rect);
// Window left side.
{
int height = GetRect().GetHeight() - skin->top_left->GetHeight() - skin->bottom_left->GetHeight();
int *dst = (int *)cache->GetData();
dst += skin->top_left->GetHeight() * cache->GetWidth();
int *src = 0;
for (int s = 0, _s = 0; s < height; ++s)
{
if (!src || (++_s == (int)skin->left->GetHeight()))
{
src = (int *)skin->left->GetData();
_s = 0;
}
for (uint x = 0; x < skin->left->GetWidth(); ++x)
dst[x] = src[x];
src += skin->left->GetWidth();
dst += cache->GetWidth();
}
}
// Window right side.
{
int height = GetRect().GetHeight() - skin->top_right->GetHeight() - skin->bottom_right->GetHeight();
int *dst = (int *)cache->GetData();
dst += skin->top_right->GetHeight() * cache->GetWidth() + GetRect().ex - skin->right->GetWidth();
int *src = 0;
for (int s = 0, _s = 0; s < height; ++s)
{
if (!src || (++_s == (int)skin->right->GetHeight()))
{
src = (int *)skin->right->GetData();
_s = 0;
}
for (uint x = 0; x < skin->right->GetWidth(); ++x)
dst[x] = src[x];
src += skin->right->GetWidth();
dst += cache->GetWidth();
}
}
// Window top side.
{
int block_width = skin->top->GetWidth();
int width = GetRect().GetWidth() - skin->top_left->GetWidth() - skin->top_right->GetWidth(), height = skin->top->GetHeight();
int *src = (int *)skin->top->GetData(), *dst = (int *)cache->GetData();
dst += skin->top_left->GetWidth();
for (int y = 0; y < height; ++y)
{
for (int x = 0, _x = 0; x < width; ++x)
{
dst[x] = src[_x++];
if (_x == block_width)
_x = 0;
}
src += skin->top->GetWidth();
dst += cache->GetWidth();
}
}
// Window bottom side.
{
int block_width = skin->bottom->GetWidth();
int width = GetRect().GetWidth() - skin->bottom_left->GetWidth() - skin->bottom_right->GetWidth(), height = skin->bottom->GetHeight();
int *src = (int *)skin->bottom->GetData(), *dst = (int *)cache->GetData();
dst += skin->bottom_left->GetWidth() + (GetRect().ey - height) * cache->GetWidth();
for (int y = 0; y < height; ++y)
{
for (int x = 0, _x = 0; x < width; ++x)
{
dst[x] = src[_x++];
if (_x == block_width)
_x = 0;
}
src += skin->bottom->GetWidth();
dst += cache->GetWidth();
}
}
//
{
int height = GetRect().ey - skin->bottom_right->GetHeight() - skin->top_left->GetHeight(), width = GetRect().GetWidth();
//
uint *dst = (uint *)cache->GetData();
dst += cache->GetWidth() * skin->top_left->GetHeight();// + system.skin_left->GetWidth();
float alpha = 1.f;
int segment_height = (height * 70) / 100;
float alpha_step = (0.85f - alpha) / (float)segment_height;
for (int y = 0; y < segment_height; ++y)
{
uint int_alpha = (uint(alpha * 255.f)) & 0xff;
// uint scan_color = nColor::ARGBtoRGBA((system.skin_color & 0xffffff00) + int_alpha);
for (int x = 0; x < width; ++x)
dst[x] = (((((dst[x] >> 24) & 0xff) * int_alpha) >> 8) << 24) + (dst[x] & 0x00ffffff);//scan_color;
dst += cache->GetWidth();
alpha += alpha_step;
}
segment_height = height - segment_height;
alpha_step = (1.f - alpha) / (float)segment_height;
for (int y = 0; y < segment_height; ++y)
{
uint int_alpha = (uint(alpha * 255.f)) & 0xff;
// uint scan_color = nColor::ARGBtoRGBA((system.skin_color & 0xffffff00) + int_alpha);
for (int x = 0; x < width; ++x)
dst[x] = (((((dst[x] >> 24) & 0xff) * int_alpha) >> 8) << 24) + (dst[x] & 0x00ffffff);//scan_color;
dst += cache->GetWidth();
alpha += alpha_step;
}
}
}
void Window::Compose()
{
if (cache.IsNull())
return;
if (background_picture)
{
cache->Fill(0, 0, 0, 0);
Picture::Blit(*background_picture, *cache);
}
else
{
bool skinned = false;
if (!window_flags.IsSet(Window::FlagNoDecoration))
if (skin.IsValid())
skinned = true;
if (skinned)
ComposeSkin();
cache->Fill(background_color.x, background_color.y, background_color.z, background_color.w);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::Invalidate()
{
if (base_widget)
base_widget->Invalidate();
if (title_widget)
title_widget->Invalidate();
window_flags.Raise(FlagCacheDirty | FlagRenderDirty);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::RenderSetup(Core::ResourceFactories *f)
{
if ((render_data = new Sprite::RenderData))
if (f && f->render)
{
render_data->texture = f->render->NewTexture();
render_data->texture->Create(NULL, (int)size.x, (int)size.y, Render::Texture::FormatRGBA8, Render::Texture::NoAA, Render::Texture::Usage(Render::Texture::IsRenderTarget | Render::Texture::IsShaderResource));
window_flags.Raise(FlagRenderDirty);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::Render(Renderer &renderer, GPU::TriangleBatch *batch)
{
// Compose.
bool has_title = !(window_flags.IsSet(Window::FlagNoTitleBar) || background_picture);
if (base_widget)
{
base_widget->Refresh();
if (base_widget->IsDirty())
{
Invalidate();
// Compose window skin.
Compose();
// Compose window content.
Rect <int> compose_rect(GetRect());
if (has_title && skin)
{
compose_rect.sx = skin->top_left->GetWidth();
compose_rect.sy = skin->title_bottom + 4;
compose_rect.ex -= skin->bottom_right->GetWidth();
compose_rect.ey -= skin->bottom_right->GetHeight();
}
if (cache.IsValid())
base_widget->Compose(*cache, compose_rect);
}
}
else
if (window_flags.IsSet(FlagCacheDirty))
Compose();
// Compose the window title.
if (has_title && skin)
{
iRect title_rect(skin->top_left->GetWidth(), skin->title_top, GetRect().GetWidth() - skin->top_right->GetWidth(), skin->title_bottom);
if (cache.IsValid())
title_widget->Compose(*cache, title_rect);
}
if (window_flags.IsSet(FlagRenderDirty))
if (render_data.IsValid() && render_data->texture.IsValid())
{
render_data->texture->Blit((const char *)cache->GetData(), cache->GetWidth(), cache->GetHeight());
window_flags.Remove(FlagRenderDirty);
}
Sprite::Render(renderer, batch);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Window::SetSkin(WindowSkin *s)
{
if ((skin = s))
if (title_widget->GetType() == WidgetTypeText)
if (TextWidget *t = (TextWidget *)title_widget.c_ptr())
{
Color skin_color(skin->title_color);
t->SetFont(s->title_font);
t->SetFontColor(skin_color.x, skin_color.y, skin_color.z);
t->SetFontSize(s->title_size);
t->SetTextAlignment(TextState::Center);
}
Invalidate();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Window::Window()
{
window_flags.Set(FlagCacheDirty);
type = Type_Window;
cache = new Picture;
background_color.Set(0.f, 0.f, 0.f, 0.f);
title_widget = new TextWidget(-1, "Window Title");
SetSize(320, 200);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/ui_window.h"
#include "metafile/nml.h"
#include "log/log.h"
using namespace GS::NML;
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool Window::FromMetaTag(Tag &tag)
{
if (tag.name != "Window")
__ERR__(__LOG_E__ << "Could not parse window, incorrect root tag (" << tag.name << ").\n", false)
// Parse root tags.
NMLTagForeach(pt, tag)
{
if (pt->name == "Sprite")
Sprite::FromMetaTag(*pt);
else if (pt->name == "Flag")
{
NMLTagForeach(st, *pt)
{
if (st->name == "NoDecoration")
window_flags |= FlagNoDecoration;
else if (st->name == "NoTitle")
window_flags |= FlagNoTitleBar;
}
}
else
__LOG_W__ << "Unknown tag '" << pt->name << "' in <Window>.\n";
}
return true;
}
Tag *Window::AsMetaTag() const
{
Tag *root = new Tag("Window");
if (!root)
__ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL)
root->AddChild(Sprite::AsMetaTag());
if (Tag *style_tag = new Tag("Flag"))
{
if (window_flags.IsSet(FlagNoDecoration))
style_tag->AddChild("NoDecoration");
if (window_flags.IsSet(FlagNoTitleBar))
style_tag->AddChild("NoTitle");
}
return root;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,7 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/
#include "ui/ui_window_skin.h"

View File

@ -0,0 +1,169 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/widget.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void Widget::SetParent(Widget *w)
{
if (w != parent)
{
if (parent)
parent->children.Remove(this);
parent = w;
if (parent)
parent->children.Add(this);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Widget::SetHidden(bool h)
{
if (h != hidden)
{
hidden = h;
dirty = true;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Widget *Widget::GetChild(int id)
{
if (GetId() == id)
return this;
ListForeachPtr(Widget *, w, GetChildren())
if (Widget *match = w->GetChild(id))
return match;
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Widget::Invalidate()
{ dirty = true; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
iRect Widget::GetRect() const
{ return iRect(rect.sx, rect.sy, rect.ex, rect.ey); }
void Widget::SetBorderSize(float t, float b, float l, float r)
{
border_size.Set(t, b, l, r);
Invalidate();
}
void Widget::SetHAlign(Align a)
{
h_align = a;
Invalidate();
}
void Widget::SetVAlign(Align a)
{
v_align = a;
Invalidate();
}
void Widget::SetFormattingSize(const Vector2 &s)
{
format = s;
Invalidate();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Vector2 Widget::GetFormat() const
{
switch (GetType())
{
case WidgetTypeHSizer:
case WidgetTypeVSizer:
break;
default:
return format;
}
// Combine all child formats.
Vector2 total_format(0, 0);
ListForeachPtr(Widget *, w, GetChildren())
{
Vector2 child_format = w->GetFormat();
switch (GetType())
{
case WidgetTypeHSizer:
total_format.x += child_format.x;
total_format.y = total_format.y > child_format.y ? total_format.y : child_format.y;
break;
case WidgetTypeVSizer:
total_format.x = total_format.x > child_format.x ? total_format.x : child_format.x;
total_format.y += child_format.y;
break;
}
}
return total_format * format;
}
//------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
iRect Widget::FormatOutputRect(const iRect &rect, const iRect &clip_rect)
//--------------------------------------------------------------------------------------
{
iRect out_rect(clip_rect.sx, clip_rect.sy, clip_rect.sx + rect.GetWidth(), clip_rect.sy + rect.GetHeight());
switch (h_align)
{
case AlignLeft: break;
case AlignMiddle: out_rect = out_rect.Offset((clip_rect.GetWidth() - rect.GetWidth()) / 2, 0); break;
case AlignRight: out_rect = out_rect.Offset(clip_rect.GetWidth() - rect.GetWidth(), 0); break;
case AlignGrow: out_rect.ex = clip_rect.ex; break;
}
switch (v_align)
{
case AlignTop: break;
case AlignMiddle: out_rect = out_rect.Offset(0, (clip_rect.GetHeight() - rect.GetHeight()) / 2); break;
case AlignBottom: out_rect = out_rect.Offset(0, clip_rect.GetHeight() - rect.GetHeight()); break;
case AlignGrow: out_rect.ey = clip_rect.ey; break;
}
return out_rect;
}
//------------------------------------------------------------------------------
Widget::Widget(int id)
{
object_id = id;
parent = NULL;
format.Set(1, 1);
SetBorderSize();
h_align = AlignMiddle;
v_align = AlignMiddle;
dirty = true;
hidden = false;
type = WidgetTypeBase;
event_table = new EventTable;
}
Widget::~Widget()
{
SetParent(NULL);
ListForeachPtr(Widget *, c, children)
c->SetParent(NULL);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "widget_bitmap.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
void BitmapWidget::SetPicture(GS::Picture *p)
{
if (picture != p)
{
picture = p;
Invalidate();
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BitmapWidget::BitmapWidget(int id, GS::Picture *p) : DrawableWidget(id)
{
SetPicture(p);
type = WidgetTypeBitmap;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,29 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/widget_canvas.h"
using namespace GS::S2D;
//------------------------------------------------------------------------------
bool CanvasWidget::Allocate(uint width, uint height)
{
if (!picture->AllocAs(width, height, GS::PixelFormat::RGBA8))
return false;
dirty = true;
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
CanvasWidget::CanvasWidget(int id, uint width, uint height) : DrawableWidget(id)
{
type = WidgetTypeCanvas;
picture = new GS::Picture(width, height);
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,58 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/
#include "ui/widget_check.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void CheckWidget::SetState(bool b_state)
{
state = b_state;
// check_bitmap.SetPicture(state ? "scene2d/ui_check_true.tga" : "scene2d/ui_check_false.tga");
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void CheckWidget::Refresh()
{
check_bitmap.Refresh();
label.Refresh();
dirty = check_bitmap.IsDirty() || label.IsDirty();
}
void CheckWidget::Invalidate()
{
check_bitmap.Invalidate();
label.Invalidate();
Widget::Invalidate();
}
void CheckWidget::Compose(Picture &output, const iRect &out_rect)
{
if (hidden || !dirty)
return;
rect = out_rect;
rect.sy += (int)border_size.x;
rect.ey -= (int)border_size.y;
rect.sx += (int)border_size.z;
rect.ex -= (int)border_size.w;
// Compose check box and label.
Rect <int> check_rect(rect), label_rect(rect);
if (check_bitmap.GetPicture())
{
check_rect.ex = check_rect.sx + (check_bitmap.GetPicture()->GetWidth() * 3) / 2;
label_rect.sx = check_rect.ex;
}
check_bitmap.Compose(output, check_rect);
label.Compose(output, label_rect);
dirty = false;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,66 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "widget_drawable.h"
#include "picture/pict.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void DrawableWidget::Compose(Picture &output, const iRect &clip_rect)
{
if (hidden || !dirty || !picture)
return;
if (picture)
rect.Set(0, 0, picture->GetWidth(), picture->GetHeight());
else rect.Set(0, 0, 0, 0);
iRect out_rect = Widget::FormatOutputRect(rect, clip_rect),
blit_rect = out_rect.Intersection(clip_rect);
if (blit_rect.GetWidth() > rect.GetWidth())
blit_rect.ex = blit_rect.sx + rect.GetWidth();
if (blit_rect.GetHeight() > rect.GetHeight())
blit_rect.ey = blit_rect.sy + rect.GetHeight();
int src_offsetx = blit_rect.sx - out_rect.sx,
src_offsety = blit_rect.sy - out_rect.sy;
uchar *ptr = picture->GetData() + (src_offsety * picture->GetWidth() + src_offsetx) * 4,
*pds = output.GetData() + (blit_rect.sy * output.GetWidth() + blit_rect.sx) * 4;
for (int y = 0; y < blit_rect.GetHeight(); ++y)
{
uchar *psc = ptr, *spt = pds;
for (int x = 0; x < blit_rect.GetWidth(); ++x)
{
uchar alpha = psc[3];
uchar a_blend = Picture::AlphaCompositeAlpha(spt[3], alpha);
spt[0] = Picture::AlphaCompositeColor(spt[0], psc[0], spt[3], alpha, a_blend);
spt[1] = Picture::AlphaCompositeColor(spt[1], psc[1], spt[3], alpha, a_blend);
spt[2] = Picture::AlphaCompositeColor(spt[2], psc[2], spt[3], alpha, a_blend);
spt[3] = a_blend;
spt += 4;
psc += 4;
}
ptr += picture->GetWidth() * 4;
pds += output.GetWidth() * 4;
}
rect = out_rect;
dirty = false;
}
DrawableWidget::DrawableWidget(int id) : Widget(id)
{
type = WidgetTypeDrawable;
picture = NULL;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,114 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "widget_sizer.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
Widget *SizerWidget::Add(Widget *widget)
{
if (widget)
widget->SetParent(this);
return widget;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void SizerWidget::Invalidate()
{
ListForeachPtr(Widget *, c, children)
c->Invalidate();
Widget::Invalidate();
}
void HSizerWidget::Refresh()
{
ListForeachPtr(Widget *, c, children)
{
c->Refresh();
if (c->IsDirty())
dirty = true;
}
}
void HSizerWidget::Compose(Picture &output, const iRect &out_rect)
{
if (hidden || !dirty || !children.GetCount())
return;
rect = out_rect;
rect.sy += (int)border_size.x;
rect.ey -= (int)border_size.y;
rect.sx += (int)border_size.z;
rect.ex -= (int)border_size.w;
iRect wid_rect(rect);
float tsz = 0.f;
ListForeachPtr(Widget *, c, children)
if (!c->IsHidden())
tsz += c->GetFormat().x;
float stx = (float)out_rect.GetWidth() / tsz;
ListForeachPtr(Widget *, c, children)
if (!c->IsHidden())
{
float cell_size = stx * c->GetFormat().x;
wid_rect.ex = wid_rect.sx + (int)cell_size;
c->Compose(output, wid_rect);
wid_rect.sx += (int)cell_size;
}
else
c->Validate();
dirty = false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void VSizerWidget::Refresh()
{
ListForeachPtr(Widget *, c, children)
{
c->Refresh();
if (c->IsDirty())
dirty = true;
}
}
void VSizerWidget::Compose(Picture &output, const iRect &out_rect)
{
if (hidden || !dirty || !children.GetCount())
return;
rect = out_rect;
rect.sy += (int)border_size.x;
rect.ey -= (int)border_size.y;
rect.sx += (int)border_size.z;
rect.ex -= (int)border_size.w;
iRect wid_rect(rect);
float tsy = 0.f;
ListForeachPtr(Widget *, c, children)
if (!c->IsHidden())
tsy += c->GetFormat().y;
float sty = (float)out_rect.GetHeight() / tsy;
ListForeachPtr(Widget *, c, children)
if (!c->IsHidden())
{
float cell_size = sty * c->GetFormat().y;
wid_rect.ey = wid_rect.sy + (int)cell_size;
c->Compose(output, wid_rect);
wid_rect.sy += (int)cell_size;
}
else
c->Validate();
dirty = false;
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,102 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/widget_staticcontainer.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S2D;
//-------------------------------------------------------------------------
ContainerCell *ContainerWidget::GetCell(const Widget *widget) const
//-------------------------------------------------------------------------
{
ListForeachPtr(ContainerCell *, cell, cell_list)
if (cell->widget == widget)
return cell;
return NULL;
}
//------------------------------------------------------------------------------
Widget *ContainerWidget::Add(Widget *widget, const iRect &cell_rect)
{
if (!widget)
__ERR__(__LOG_E__ << "Cannot create a cell for a NULL widget.\n", NULL)
ContainerCell *cell = new ContainerCell;
if (!cell)
__ERR__(__LOG_E__ << "Failed to allocate new container cell.\n", NULL)
widget->SetParent(this);
cell->cell_rect = cell_rect;
cell->widget = widget;
cell_list.Add(cell, true, false);
children.Add(widget);
return widget;
}
bool ContainerWidget::Remove(Widget *widget)
{
ContainerCell *e = GetCell(widget);
if (!e)
return false;
cell_list.Remove(e);
_safe_delete(e);
children.Remove(widget);
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------
void ContainerWidget::Invalidate()
//------------------------------------------------
{
ListForeachPtr(ContainerCell *, cell, cell_list)
cell->widget->Invalidate();
Widget::Invalidate();
}
//---------------------------------------------
void ContainerWidget::Refresh()
//---------------------------------------------
{
ListForeachPtr(ContainerCell *, cell, cell_list)
{
cell->widget->Refresh();
if (cell->widget->IsDirty())
dirty = true;
}
}
//------------------------------------------------------------------------------
void ContainerWidget::Compose(Picture &output, const iRect &out_rect)
{
if (hidden || !dirty || !cell_list.GetCount())
return;
rect = out_rect;
ListForeachPtr(ContainerCell *, cell, cell_list)
if (!cell->widget->IsHidden())
cell->widget->Compose(output, cell->cell_rect.Offset(rect.sx, rect.sy));
else
cell->widget->Validate();
dirty = false;
}
ContainerWidget::~ContainerWidget()
{
/*
Only cells are deleted here since children are handled by the base
Widget class destructor.
*/
ListDeleteAllPtr(ContainerCell *, cell_list)
}
//------------------------------------------------------------------------------

View File

@ -0,0 +1,92 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "ui/widget_text.h"
using namespace GS;
using namespace GS::S2D;
//------------------------------------------------------------------------------
void TextWidget::SetTextState(const TextState &_state)
{
// Avoid useless invalidation.
if (Memory::Compare(&state, &_state, sizeof(TextState)))
{
state = _state;
Invalidate();
}
}
void TextWidget::GetTextState(TextState &_state) const
{ _state = state; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void TextWidget::SetText(const char *t)
{
text = t;
Invalidate();
}
void TextWidget::SetFont(FontEx *f)
{
if (state.font != f)
{
state.font = f;
Invalidate();
}
}
void TextWidget::SetFontSize(int s)
{
state.SetSize(s);
if (state.font.IsValid())
state.font->SetPixelSize(s);
Invalidate();
}
void TextWidget::SetFontColor(float red, float green, float blue, float alpha)
{
state.color.Set(red * 255.f, green * 255.f, blue * 255.f, alpha * 255.f);
Invalidate();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void TextWidget::Refresh()
{
if (!state.font || !dirty)
return;
rect = state.font->GetTextBoundRect(text);
}
void TextWidget::Compose(Picture &output, const iRect &clip_rect)
{
iRect text_rect = FontRenderer::Format(text.c_str(), state, clip_rect),
out_rect = Widget::FormatOutputRect(text_rect, clip_rect);
rect = FontRenderer::Compose(output, text.c_str(), state, out_rect, clip_rect);
dirty = false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
TextWidget::TextWidget(int id, const char *t, FontEx *font, int s) : Widget(id)
{
type = WidgetTypeText;
state.format = TextState::Line;
state.alignment = TextState::Left;
h_align = AlignGrow;
SetText(t);
SetFont(font);
SetFontSize(s);
SetFontColor(1, 1, 1);
SetColumnWidth(80);
state.SetTracking(FontRenderer::default_text_tracking);
state.SetLeading(FontRenderer::default_text_heading);
}
//------------------------------------------------------------------------------