commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
174
include/engine/ui/ui.cpp
Normal file
174
include/engine/ui/ui.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
30
include/engine/ui/ui_ace_manager.cpp
Normal file
30
include/engine/ui/ui_ace_manager.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
9
include/engine/ui/ui_camera.cpp
Normal file
9
include/engine/ui/ui_camera.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "ui/ui_camera.h"
|
||||
|
||||
using namespace GS::S2D;
|
||||
301
include/engine/ui/ui_cursor.cpp
Normal file
301
include/engine/ui/ui_cursor.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
48
include/engine/ui/ui_event_handler.cpp
Normal file
48
include/engine/ui/ui_event_handler.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
20
include/engine/ui/ui_group.cpp
Normal file
20
include/engine/ui/ui_group.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
162
include/engine/ui/ui_item.cpp
Normal file
162
include/engine/ui/ui_item.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
50
include/engine/ui/ui_item_automated_property_provider.cpp
Normal file
50
include/engine/ui/ui_item_automated_property_provider.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
93
include/engine/ui/ui_item_nml.cpp
Normal file
93
include/engine/ui/ui_item_nml.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
81
include/engine/ui/ui_item_script_event.cpp
Normal file
81
include/engine/ui/ui_item_script_event.cpp
Normal 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();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
45
include/engine/ui/ui_item_script_unit.cpp
Normal file
45
include/engine/ui/ui_item_script_unit.cpp
Normal 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(); }
|
||||
//------------------------------------------------------------------------------
|
||||
27
include/engine/ui/ui_item_scripted_object.cpp
Normal file
27
include/engine/ui/ui_item_scripted_object.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
11
include/engine/ui/ui_message.cpp
Normal file
11
include/engine/ui/ui_message.cpp
Normal 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;
|
||||
216
include/engine/ui/ui_nml.cpp
Normal file
216
include/engine/ui/ui_nml.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
24
include/engine/ui/ui_profiler.cpp
Normal file
24
include/engine/ui/ui_profiler.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
89
include/engine/ui/ui_render.cpp
Normal file
89
include/engine/ui/ui_render.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
40
include/engine/ui/ui_scene_script_event.cpp
Normal file
40
include/engine/ui/ui_scene_script_event.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
25
include/engine/ui/ui_scene_scripted_object.cpp
Normal file
25
include/engine/ui/ui_scene_scripted_object.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
32
include/engine/ui/ui_script_unit.cpp
Normal file
32
include/engine/ui/ui_script_unit.cpp
Normal 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(); }
|
||||
//------------------------------------------------------------------------------
|
||||
67
include/engine/ui/ui_sprite.cpp
Normal file
67
include/engine/ui/ui_sprite.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
95
include/engine/ui/ui_sprite_nml.cpp
Normal file
95
include/engine/ui/ui_sprite_nml.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
113
include/engine/ui/ui_sprite_render.cpp
Normal file
113
include/engine/ui/ui_sprite_render.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
70
include/engine/ui/ui_update.cpp
Normal file
70
include/engine/ui/ui_update.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
365
include/engine/ui/ui_window.cpp
Normal file
365
include/engine/ui/ui_window.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
59
include/engine/ui/ui_window_nml.cpp
Normal file
59
include/engine/ui/ui_window_nml.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
7
include/engine/ui/ui_window_skin.cpp
Normal file
7
include/engine/ui/ui_window_skin.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ui/ui_window_skin.h"
|
||||
169
include/engine/ui/widget.cpp
Normal file
169
include/engine/ui/widget.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
29
include/engine/ui/widget_bitmap.cpp
Normal file
29
include/engine/ui/widget_bitmap.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
29
include/engine/ui/widget_canvas.cpp
Normal file
29
include/engine/ui/widget_canvas.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
58
include/engine/ui/widget_check.cpp
Normal file
58
include/engine/ui/widget_check.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
66
include/engine/ui/widget_drawable.cpp
Normal file
66
include/engine/ui/widget_drawable.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
114
include/engine/ui/widget_sizer.cpp
Normal file
114
include/engine/ui/widget_sizer.cpp
Normal 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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
102
include/engine/ui/widget_staticcontainer.cpp
Normal file
102
include/engine/ui/widget_staticcontainer.cpp
Normal 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)
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
92
include/engine/ui/widget_text.cpp
Normal file
92
include/engine/ui/widget_text.cpp
Normal 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);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user