1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-01-28 07:03:11 +08:00
guix/guix_studio/sprite_service_provider.cpp

460 lines
14 KiB
C++

#include "studiox_includes.h"
#include "gx_win32_studio_display_driver.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_SPRITE_FRAMES 256
static void studio_sprite_draw(GX_SPRITE* sprite)
{
GX_SPRITE_FRAME* frame;
GX_PIXELMAP* map;
GX_VALUE xpos;
GX_VALUE ypos;
int theme_index;
res_info* info;
studiox_project* project = GetOpenProject();
GX_WIN32_DISPLAY_DRIVER_DATA* data = gx_win32_get_data_instance_by_thread_id(GetCurrentThreadId());
if ((!data) || (!project))
{
return;
}
/* Draw sprite background. */
gx_widget_background_draw((GX_WIDGET*)sprite);
if (sprite->gx_sprite_frame_list)
{
frame = &sprite->gx_sprite_frame_list[sprite->gx_sprite_current_frame];
theme_index = project->mDisplays[data->win32_display_index].active_theme;
info = project->FindResource(data->win32_display_index, theme_index, RES_TYPE_PIXELMAP, frame->gx_sprite_frame_pixelmap);
if (!info)
{
return;
}
if (sprite->gx_sprite_current_frame < sprite->gx_sprite_frame_count)
{
map = info->GetPixelmap(sprite->gx_sprite_current_frame);
if (map)
{
xpos = (GX_VALUE)(sprite->gx_widget_size.gx_rectangle_left + frame->gx_sprite_frame_x_offset);
ypos = (GX_VALUE)(sprite->gx_widget_size.gx_rectangle_top + frame->gx_sprite_frame_y_offset);
if (frame->gx_sprite_frame_alpha != GX_ALPHA_VALUE_OPAQUE)
{
gx_canvas_pixelmap_blend(xpos, ypos, map, frame->gx_sprite_frame_alpha);
}
else
{
gx_canvas_pixelmap_draw(xpos, ypos, map);
}
}
}
}
/* Draw children widgets of sprite widget. */
gx_widget_children_draw((GX_WIDGET*)sprite);
}
sprite_service_provider::sprite_service_provider()
{
}
CString sprite_service_provider::GetVarDeclaration()
{
return CString("GX_SPRITE_MEMBERS_DECLARE");
}
CString sprite_service_provider::DeclarePropertiesStruct()
{
CString out(""
"typedef struct\n"
"{\n"
" GX_SPRITE_FRAME *frame_list;\n"
" USHORT frame_count;\n"
"} GX_SPRITE_PROPERTIES;\n\n");
return out;
}
TCHAR *sprite_background_string[] = {
_T("GX_SPRITE_BACKGROUND_NO_ACTION"),
_T("GX_SPRITE_BACKGROUND_SOLID_FILL"),
_T("GX_SPRITE_BACKGROUND_RESTORE")
};
CString sprite_service_provider::WriteExtendedProperties(screen_generator *gen, CString &prefix, widget_info *info)
{
int index;
int back_op;
CString temp;
CString list;
GX_SPRITE_FRAME *frame;
CString propname = prefix + info->app_name;
if (info->ewi.sprite.frame_count > 0)
{
list.Format(_T("GX_SPRITE_FRAME %s_frame_list[%d] =\n{\n"),
propname, info->ewi.sprite.frame_count);
frame = info->ewi.sprite.framelist;
int frame_id;
for (index = 0; index < info->ewi.sprite.frame_count; index++)
{
if (info->pixelmap_id[NORMAL_PIXELMAP_INDEX])
{
frame_id = index;
}
else
{
frame_id = 0;
}
back_op = frame->gx_sprite_frame_background_operation;
if (back_op >= 3)
{
back_op = 0;
}
temp.Format(_T(" {\n")
_T(" %s, /* pixelmap id */\n")
_T(" %d, /* x offset */\n")
_T(" %d, /* y offset */\n")
_T(" %d, /* frame delay */\n")
_T(" %s, /* background operation */\n")
_T(" %d /* alpha value*/\n")
_T(" }"),
gen->GetPixelmapIdName(frame->gx_sprite_frame_pixelmap, frame_id),
frame->gx_sprite_frame_x_offset,
frame->gx_sprite_frame_y_offset,
frame->gx_sprite_frame_delay,
sprite_background_string[back_op],
frame->gx_sprite_frame_alpha);
if (index == info->ewi.sprite.frame_count - 1)
{
temp += "\n";
}
else
{
temp += ",\n";
}
list += temp;
frame++;
}
list += "};\n\n";
temp.Format(_T("GX_SPRITE_PROPERTIES %s_properties =\n")
_T("{\n")
_T(" %s_frame_list, /* address of frame list */\n")
_T(" %d, /* frame count */\n")
_T("};\n"),
propname, propname, info->ewi.sprite.frame_count);
list += temp;
}
else
{
list.Format(_T("GX_SPRITE_PROPERTIES %s_properties =\n")
_T("{\n")
_T(" GX_NULL, /* address of frame list */\n")
_T(" 0, /* frame count */\n")
_T("};\n"),
propname);
}
return list;
}
CString sprite_service_provider::GetCreateFromDefFunctionName()
{
return CString("gx_studio_sprite_create");
}
CString sprite_service_provider::GetCreateFromDefFunction(int version)
{
CString out;
MakeCreatePreamble("sprite", version, out);
out += "{\n"
" UINT status;\n"
" GX_SPRITE *sprite = (GX_SPRITE *) control_block;\n"
" GX_SPRITE_PROPERTIES *props = (GX_SPRITE_PROPERTIES *) info->properties;\n"
" status = gx_sprite_create(sprite, info->widget_name, parent,\n"
" props->frame_list, props->frame_count,\n"
" info->style, info->widget_id, &info->size);\n"
" return status;\n"
"}\n";
return out;
}
widget_info *sprite_service_provider::CreateNewInstance(GX_WIDGET *parent)
{
GX_RECTANGLE size;
gx_utility_rectangle_define(&size, 0, 0, 63, 63);
gx_utility_rectangle_center(&size, &parent->gx_widget_size);
GX_SPRITE *sprite = new GX_SPRITE;
gx_sprite_create(sprite, "sprite", parent,
GX_NULL, 0, GX_STYLE_ENABLED, 0, &size);
widget_info *info = InitWidgetInfo((GX_WIDGET *) sprite);
info->ewi.sprite.framelist = NULL;
info->ewi.sprite.frame_count = 0;
info->ewi.sprite.apply_to_all_frames = FALSE;
return info;
}
GX_WIDGET *sprite_service_provider::GenerateFromInfo(GX_WIDGET *parent, widget_info *info)
{
GX_SPRITE *sprite = new GX_SPRITE;
ULONG style = info->style;
gx_sprite_create(sprite,
(CHAR *) info->app_name.GetString(),
parent,
info->ewi.sprite.framelist, info->ewi.sprite.frame_count,
style, 0, &info->size);
if (info->pixelmap_id[NORMAL_PIXELMAP_INDEX])
{
gx_widget_draw_set(sprite, studio_sprite_draw);
}
gx_widget_fill_color_set((GX_WIDGET *) sprite,
info->color_id[NORMAL_FILL_COLOR_INDEX], info->color_id[SELECTED_FILL_COLOR_INDEX], info->color_id[DISABLED_FILL_COLOR_INDEX]);
return ((GX_WIDGET *) sprite);
}
void sprite_service_provider::SaveToProject(xml_writer &writer, studiox_project *project, int display, widget_info *info)
{
int index;
GX_SPRITE_FRAME *frame;
widget_service_provider::SaveToProject(writer, project, display, info);
WritePixelmapId(writer, project, display, "pixelmap_id", info->pixelmap_id[NORMAL_PIXELMAP_INDEX]);
writer.WriteInt("framecount", info->ewi.sprite.frame_count);
writer.WriteBool("apply_to_all_frames", info->ewi.sprite.apply_to_all_frames);
writer.OpenTag("framelist");
frame = info->ewi.sprite.framelist;
for (index = 0; index < info->ewi.sprite.frame_count; index++)
{
writer.OpenTag("sprite_frame");
WritePixelmapId(writer, project, display, "pixelmap", frame->gx_sprite_frame_pixelmap);
writer.WriteInt("x_offset", frame->gx_sprite_frame_x_offset);
writer.WriteInt("y_offset", frame->gx_sprite_frame_y_offset);
writer.WriteInt("delay", frame->gx_sprite_frame_delay);
writer.WriteInt("background", frame->gx_sprite_frame_background_operation);
writer.WriteUnsigned("alpha", frame->gx_sprite_frame_alpha);
writer.CloseTag("sprite_frame");
frame++;
}
writer.CloseTag("framelist");
}
void sprite_service_provider::ReadFromProject(xml_reader &reader, studiox_project *project, int display, widget_info *info, ULONG valid_styles)
{
int framecount;
int index;
int val;
unsigned long uval;
GX_SPRITE_FRAME *frame;
valid_styles |= GX_STYLE_SPRITE_AUTO|GX_STYLE_SPRITE_LOOP;
widget_service_provider::ReadFromProject(reader, project, display, info, valid_styles);
info->pixelmap_id[NORMAL_PIXELMAP_INDEX] = ReadPixelmapId(reader, project, display, "pixelmap_id");
reader.ReadInt("framecount", framecount);
info->ewi.sprite.frame_count = framecount;
reader.ReadBool("apply_to_all_frames", info->ewi.sprite.apply_to_all_frames);
if (framecount)
{
info->ewi.sprite.framelist = new GX_SPRITE_FRAME[framecount];
memset(info->ewi.sprite.framelist, 0, sizeof(GX_SPRITE_FRAME) * framecount);
frame = info->ewi.sprite.framelist;
if (reader.EnterSection("framelist"))
{
for (index = 0; index < framecount; index++)
{
if (reader.EnterSection("sprite_frame"))
{
frame->gx_sprite_frame_pixelmap = ReadPixelmapId(reader, project, display, "pixelmap");
reader.ReadValue("x_offset", frame->gx_sprite_frame_x_offset);
reader.ReadValue("y_offset", frame->gx_sprite_frame_y_offset);
reader.ReadInt("delay", val);
frame->gx_sprite_frame_delay = val;
reader.ReadInt("background", val);
frame->gx_sprite_frame_background_operation = val;
reader.ReadUnsigned("alpha", uval);
frame->gx_sprite_frame_alpha = (unsigned char) uval;
reader.CloseSection(TRUE);
}
frame++;
}
reader.CloseSection(TRUE);
}
}
}
void sprite_service_provider::UpdateSpriteFrameInfo(widget_info *info)
{
studiox_project* project = GetOpenProject();
if (!project)
{
return;
}
int display = project->GetDisplayIndex(info);
if (display < 0)
{
return;
}
CString name;
project->GetResourceName(display, RES_TYPE_PIXELMAP, info->pixelmap_id[0], name);
int active_theme = project->mDisplays[display].active_theme;
res_info* rinfo = project->FindResource(display, active_theme, RES_TYPE_PIXELMAP, name);
if (info->ewi.sprite.framelist)
{
delete info->ewi.sprite.framelist;
info->ewi.sprite.framelist = NULL;
info->ewi.sprite.frame_count = 0;
}
if (rinfo && rinfo->map_list.GetCount())
{
info->ewi.sprite.frame_count = rinfo->GetPixelmapFrameCount();
if (info->ewi.sprite.frame_count > MAX_SPRITE_FRAMES)
{
info->ewi.sprite.frame_count = MAX_SPRITE_FRAMES;
}
info->ewi.sprite.framelist = new GX_SPRITE_FRAME[info->ewi.sprite.frame_count];
memset(info->ewi.sprite.framelist, 0, sizeof(GX_SPRITE_FRAME) * info->ewi.sprite.frame_count);
GX_SPRITE_FRAME* frame;
for (int frameindex = 0; frameindex < info->ewi.sprite.frame_count; frameindex++)
{
frame = &info->ewi.sprite.framelist[frameindex];
frame->gx_sprite_frame_alpha = 255;
frame->gx_sprite_frame_delay = rinfo->GetPixelmapDelayTime(frameindex);
frame->gx_sprite_frame_delay /= GX_SYSTEM_TIMER_MS;
frame->gx_sprite_frame_pixelmap = info->pixelmap_id[0];
}
}
GX_WIDGET* widget = info->widget;
if (widget)
{
GX_SPRITE* sprite = (GX_SPRITE*)widget;
gx_sprite_frame_list_set(sprite, info->ewi.sprite.framelist, info->ewi.sprite.frame_count);
}
}
void sprite_service_provider::AssignPixelmap(widget_info *info, int index,
GX_RESOURCE_ID pixmap_id)
{
if (info->pixelmap_id[index] != pixmap_id)
{
info->pixelmap_id[index] = pixmap_id;
UpdateSpriteFrameInfo(info);
}
else
{
GX_WIDGET* widget = info->widget;
if (widget)
{
GX_SPRITE* sprite = (GX_SPRITE*)widget;
gx_sprite_frame_list_set(sprite, info->ewi.sprite.framelist, info->ewi.sprite.frame_count);
}
}
}
void sprite_service_provider::Autosize(widget_info *info)
{
GX_PIXELMAP *map = NULL;
GX_VALUE border_width;
int map_index;
int max_map_width = -1;
int max_map_height = -1;
GX_SPRITE_FRAME *frame;
studiox_project *project = GetOpenProject();
int display = project->GetDisplayIndex(info);
int active_theme = project->mDisplays[display].active_theme;
if (display >= 0)
{
frame = info->ewi.sprite.framelist;
for (map_index = 0; map_index < info->ewi.sprite.frame_count; map_index++)
{
if (frame->gx_sprite_frame_pixelmap)
{
res_info *resource = project->FindResource(display, active_theme, RES_TYPE_PIXELMAP, frame->gx_sprite_frame_pixelmap);
if (resource)
{
map = resource->GetPixelmap();
if (map)
{
if (map->gx_pixelmap_width > max_map_width)
{
max_map_width = map->gx_pixelmap_width;
}
if (map->gx_pixelmap_height > max_map_height)
{
max_map_height = map->gx_pixelmap_height;
}
}
}
}
}
}
if (max_map_height <= 0 || max_map_width <= 0)
{
return;
}
// check to see if new size if any different
GX_RECTANGLE newsize = info->widget->gx_widget_size;
gx_widget_border_width_get(info->widget, &border_width);
newsize.gx_rectangle_right = newsize.gx_rectangle_left + max_map_width + (border_width * 2) - 1;
newsize.gx_rectangle_bottom = newsize.gx_rectangle_top + max_map_height + (border_width * 2) - 1;
if (!gx_utility_rectangle_compare(&newsize, &info->widget->gx_widget_size))
{
gx_widget_resize(info->widget, &newsize);
info->size = newsize;
GetPropsWin()->WidgetWasMoved();
}
}