1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-02-04 07:13:17 +08:00
guix/guix_studio/resource_item.cpp

2261 lines
60 KiB
C++

#include "studiox_includes.h"
#include "resource_tree.h"
#include "resource_item_provider.h"
#include "resource_view_provider.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define ITEM_HEIGHT 22
#define COLOR_BOX_SPACE 4
#define COLOR_TEXT_SPACE 8
#define ICON_HORZ_SPACE 8
#define ITEM_VERT_SPACE 6
#define TREE_INDENT 16
#define FONT_PREVIEW_COLUMN_WIDTH 120
#define FONT_PIXEL_COLUMN_WIDTH 30
#define FONT_STORAGE_COLUMN_WIDTH 50
#define PIXELMAP_DIMENSION_COLUMN_WIDTH 60
#define PIXELMAP_STORAGE_COLUMN_WIDTH 60
#define STRING_ID_COLUMN_WIDTH 120
extern CFont TitleFont;
extern CFont MediumFont;
extern CFont NormalFont;
extern CFont ViewHeaderFont;
extern CString target_class_name;
///////////////////////////////////////////////////////////////////////////////
// this constructor is used for most items:
resource_item::resource_item(resource_tree *tree, res_info *get)
{
Init();
mpTree = tree;
mpRes = get;
if (mpRes->type == RES_TYPE_FOLDER)
{
if ((mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER) ||
(mpRes->folder_id == DEFAULT_PIXELMAP_FOLDER))
{
m_open = FALSE;
}
else
{
m_open = TRUE;
}
}
else
{
switch (mpRes->type)
{
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
SetIcon(IDB_ADD_RESOURCE, IDB_ADD_RESOURCE_HIGHLIGHT);
break;
default:
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// this constructor is used for String Table items
resource_item::resource_item(resource_tree *tree, CString &name, CString &val)
{
Init();
mpTree = tree;
mpRes = NULL;
string_id = name;
display_id = name;
string_val = val;
}
///////////////////////////////////////////////////////////////////////////////
resource_item::~resource_item()
{
// must delete all my children as well as myself
resource_item *test;
while(m_first)
{
test = m_first->m_next;
delete m_first;
m_first = test;
}
if (m_preview_mem)
{
delete [] m_preview_mem;
}
if (m_pResItemProvider)
{
UiaDisconnectProvider(m_pResItemProvider);
m_pResItemProvider->Release();
m_pResItemProvider = NULL;
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Init()
{
m_first = m_next = m_parent = NULL;
m_indent = 0;
m_icon_id = 0;
m_icon_id_highlight = 0;
m_icon_height = 0;
m_icon_width = 0;
m_string_arrow_icon_width = 0;
m_boxcolor = MakeColorRef(0);
m_open = FALSE;
m_visible = FALSE;
m_selected = FALSE;
m_preview_mem = NULL;
m_size.SetRect(0, 0, 0, 0);
m_sys_dpi = GetSystemDPI();
int text_scaler = GetTextScaler();
m_item_height = GetScaledValue(ITEM_HEIGHT, m_sys_dpi, text_scaler);
m_header_height = GetScaledValue(VIEW_HEADER_HEIGHT, m_sys_dpi, text_scaler);
m_font_preview_width = GetScaledValue(FONT_PREVIEW_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_font_pixel_width = GetScaledValue(FONT_PIXEL_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_font_storage_width = GetScaledValue(FONT_STORAGE_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_pixelmap_dimension_width = GetScaledValue(PIXELMAP_DIMENSION_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_pixelmap_storage_width = GetScaledValue(PIXELMAP_STORAGE_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_thumbnail_size = GetScaledValue(THUMBNAIL_SIZE, m_sys_dpi, text_scaler);
m_string_id_width = GetScaledValue(STRING_ID_COLUMN_WIDTH, m_sys_dpi, text_scaler);
m_pResItemProvider = NULL;
m_Id = resource_view::CreateUniqueId();
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Attach(resource_item *child)
{
child->m_next = NULL;
if (m_first)
{
resource_item *test = m_first;
while(test->Next())
{
test = test->Next();
}
test->m_next = child;
}
else
{
m_first = child;
}
child ->m_parent = this;
if (m_open && m_visible)
{
child->SetVisible(TRUE);
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Detach()
{
resource_item *previous;
if (m_parent)
{
if (m_parent->m_first == this)
{
// the easy case, first child:
m_parent->m_first = m_next;
}
else
{
previous = m_parent->m_first;
while(previous->m_next != this)
{
previous = previous->m_next;
}
previous->m_next = m_next;
}
}
m_next = NULL;
m_parent = NULL;
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::SetVisible(BOOL bVisible)
{
m_visible = bVisible;
resource_item* child = First();
if ((GetResType() >= RES_TYPE_FOLDER) && IsOpen())
{
while (child)
{
child->SetVisible(TRUE);
child = child->Next();
}
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Open()
{
if (!m_open)
{
m_open = TRUE;
resource_item* child = First();
while (child)
{
child->SetVisible(TRUE);
child = child->Next();
}
mpTree->PositionItems();
GetResItemProvider()->RaiseExpandCollapseAutomationEvent(FALSE, TRUE);
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Close()
{
if ((mpRes->type <= RES_TYPE_FOLDER) && m_open)
{
m_open = FALSE;
resource_item *child = First();
while(child)
{
child->SetVisible(FALSE);
child = child->Next();
}
mpTree->PositionItems();
GetResItemProvider()->RaiseExpandCollapseAutomationEvent(TRUE, FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
resource_item *resource_item::Previous()
{
resource_item* previous = NULL;
if (m_parent->m_first != this)
{
previous = m_parent->m_first;
while (previous->m_next != this)
{
previous = previous->m_next;
}
}
return previous;
}
///////////////////////////////////////////////////////////////////////////////
resource_item *resource_item::Last()
{
resource_item* child = First();
while (child->Next())
{
child = child->Next();
}
return child;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::GetWin32CompatiblePixelWidth(int pixel_width, int color_format)
{
switch(color_format)
{
case GX_COLOR_FORMAT_MONOCHROME:
case GX_COLOR_FORMAT_MONOCHROME_INVERTED:
pixel_width += 7;
pixel_width /= 8; // get bytes
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
return pixel_width * 8;
case GX_COLOR_FORMAT_2BIT_GRAY:
case GX_COLOR_FORMAT_2BIT_GRAY_INVERTED:
pixel_width += 3;
pixel_width /= 4; // get bytes
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
return pixel_width * 4;
case GX_COLOR_FORMAT_4BIT_GRAY:
case GX_COLOR_FORMAT_4BIT_GRAY_INVERTED:
case GX_COLOR_FORMAT_4BIT_VGA:
pixel_width++;
pixel_width /= 2; // bytes
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
return pixel_width * 2;
case GX_COLOR_FORMAT_8BIT_GRAY:
case GX_COLOR_FORMAT_8BIT_GRAY_INVERTED:
case GX_COLOR_FORMAT_8BIT_PALETTE:
case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
break;
case GX_COLOR_FORMAT_5551BGRX:
case GX_COLOR_FORMAT_1555XRGB:
case GX_COLOR_FORMAT_565RGB:
case GX_COLOR_FORMAT_4444ARGB:
case GX_COLOR_FORMAT_4444BGRA:
case GX_COLOR_FORMAT_565BGR:
pixel_width *= 2; // bytes
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
return pixel_width / 2;
case GX_COLOR_FORMAT_24RGB:
case GX_COLOR_FORMAT_24BGR:
pixel_width *= 3;
pixel_width += 3;
pixel_width &= 0xfffc; // multiple of 4 bytes
return pixel_width / 3;
case GX_COLOR_FORMAT_24XRGB:
case GX_COLOR_FORMAT_24BGRX:
case GX_COLOR_FORMAT_32BGRA:
case GX_COLOR_FORMAT_32ARGB:
break;
}
return pixel_width;
}
///////////////////////////////////////////////////////////////////////////////
// grayscale palette
GX_COLOR gray_palette[16] = {
0x00000000,
0x00111111,
0x00222222,
0x00333333,
0x00444444,
0x00555555,
0x00666666,
0x00777777,
0x00888888,
0x00999999,
0x00aaaaaa,
0x00bbbbbb,
0x00cccccc,
0x00dddddd,
0x00eeeeee,
0x00ffffff
};
///////////////////////////////////////////////////////////////////////////////
void resource_item::MakeFontPreview()
{
GX_VALUE width;
int height;
GX_BRUSH *brush;
GX_RECTANGLE rect;
GX_CANVAS temp_canvas;
GX_DISPLAY temp_display;
char *prev_string = NULL;
studiox_project *project = GetOpenProject();
if (!project || !mpRes)
{
return;
}
if (mpRes->font)
{
#ifdef _UNICODE
int char_count = mpRes->name.GetLength() * 6 + 1;
char *utf8buf = new char[char_count];
// convert Unicode to UTF8
WideCharToMultiByte(CP_UTF8, 0, mpRes->name.GetString(), -1, utf8buf, char_count, NULL, NULL);
prev_string = utf8buf;
#else
prev_string = mpRes->name.GetBuffer();
#endif
GX_STRING string;
string.gx_string_ptr = prev_string;
string.gx_string_length = strlen(prev_string);
gx_system_string_width_get_ext(mpRes->font, &string, &width);
if (!width)
{
// maybe this font only has the numeric characters?
prev_string = "0123456789";
string.gx_string_ptr = prev_string;
string.gx_string_length = strlen(prev_string);
gx_system_string_width_get_ext(mpRes->font, &string, &width);
}
height = mpRes->font->gx_font_line_height;
// if we don't have anything to
if (!width || !height)
{
delete[] utf8buf;
return;
}
// create a temporary screen and temporary
// canvas to make a bitmap:
int display_index = project->GetDisplayIndex(mpRes);
if (display_index >= 0)
{
int color_format = project->mDisplays[display_index].colorformat;
width = GetWin32CompatiblePixelWidth(width, color_format);
int memsize = guix_studio_create_display(&temp_display, "preview display",
width, height, color_format, project->mHeader.target_cpu,
IsRenesasDave2D(project), IsDave2dFontFormat(project, display_index), gray_palette, 16, project->mHeader.palette_mode_aa_text_colors);
if (memsize)
{
m_preview_mem = new UCHAR[memsize];
gx_canvas_create(&temp_canvas, "preview",
&temp_display, GX_CANVAS_SIMPLE,
width, height, (GX_COLOR*)m_preview_mem, memsize);
gx_utility_rectangle_define(&rect, 0, 0, width - 1, height - 1);
gx_canvas_drawing_initiate(&temp_canvas, NULL, &rect);
gx_context_raw_brush_define(COLOR_BLACK, COLOR_WHITE, GX_BRUSH_SOLID_FILL);
gx_context_brush_width_set(0);
gx_context_brush_get(&brush);
brush->gx_brush_font = mpRes->font;
gx_canvas_rectangle_draw(&rect);
gx_canvas_text_draw_ext(0, 0, &string);
gx_canvas_drawing_complete(&temp_canvas, FALSE);
// destroy the canvas, but keep the memory pointer:
gx_canvas_delete(&temp_canvas);
// copy the screen bitmap info locally:
GX_WIN32_DISPLAY_DRIVER_DATA* data = (GX_WIN32_DISPLAY_DRIVER_DATA*)temp_display.gx_display_driver_data;
m_bitmap = data->win32_driver_bmpinfo;
// delete the temporary screen
guix_studio_delete_display(&temp_display);
}
}
#ifdef _UNICODE
delete[] utf8buf;
#endif
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::MakePixelmapPreview()
{
UINT width;
int height;
GX_RECTANGLE rect;
GX_DISPLAY temp_display;
GX_CANVAS temp_canvas;
studiox_project *project = GetOpenProject();
GX_PIXELMAP *map;
if (!mpRes || !project)
{
return;
}
if (mpRes->thumbnail)
{
map = mpRes->thumbnail;
}
else
{
map = mpRes->GetPixelmap();
}
if (map)
{
width = map->gx_pixelmap_width;
height = map->gx_pixelmap_height;
int display_index = project->GetDisplayIndex(mpRes);
int color_format = project->mDisplays[display_index].colorformat;
int active_theme = project->mDisplays[display_index].active_theme;
width = GetWin32CompatiblePixelWidth(width, color_format);
int memsize = guix_studio_create_display(&temp_display, "preview display",
width, height, color_format,
project->mHeader.target_cpu, IsRenesasDave2D(project), IsDave2dFontFormat(project, display_index),
project->mDisplays[display_index].themes[active_theme].palette,
project->mDisplays[display_index].themes[active_theme].palette_total_size,
project->mHeader.palette_mode_aa_text_colors);
if (memsize)
{
m_preview_mem = new UCHAR[memsize];
gx_canvas_create(&temp_canvas, "preview",
&temp_display, GX_CANVAS_SIMPLE,
width, height, (GX_COLOR *) m_preview_mem, memsize);
gx_utility_rectangle_define(&rect, 0, 0, width -1, height - 1);
gx_canvas_drawing_initiate(&temp_canvas, NULL, &rect);
GX_COLOR fill_color = ColorRefToGxColor(GetSysColor(COLOR_WINDOW));
gx_context_raw_brush_define(fill_color, fill_color, GX_BRUSH_SOLID_FILL);
gx_context_brush_width_set(0);
gx_canvas_rectangle_draw(&rect);
// set the fill color to medium gray, so that alphamap will be drawn to preview canvas in visible manner:
fill_color = 0xff808080;
gx_context_raw_brush_define(fill_color, fill_color, GX_BRUSH_SOLID_FILL);
gx_canvas_pixelmap_draw(0, 0, map);
gx_canvas_drawing_complete(&temp_canvas, FALSE);
// destroy the canvas, but keep the memory pointer:
gx_canvas_delete(&temp_canvas);
// copy the screen bitmap info locally:
GX_WIN32_DISPLAY_DRIVER_DATA *data = (GX_WIN32_DISPLAY_DRIVER_DATA *) temp_display.gx_display_driver_data;
m_bitmap = data->win32_driver_bmpinfo;
// delete the temporary screen
guix_studio_delete_display(&temp_display);
}
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::RebuildPreview()
{
if (m_preview_mem)
{
delete [] m_preview_mem;
m_preview_mem = NULL;
}
int type = RES_TYPE_STRING;
if (mpRes)
{
type = mpRes->type;
}
switch(type)
{
case RES_TYPE_FONT:
MakeFontPreview();
break;
case RES_TYPE_PIXELMAP:
MakePixelmapPreview();
break;
case RES_TYPE_COLOR:
m_boxcolor = MakeColorRef(GetRGBColor());
break;
default:
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintThemeHeader(CDC *dc)
{
CRect boxrect;
CFont *old_font;
CDC dcMemory;
CBitmap fillmap;
CBitmap rightmap;
fillmap.LoadBitmap(IDB_HEADER_BACKGROUND);
BITMAP bm;
int vspace;
int icon_id = m_icon_id;
int width, height;
// go through hoops to get bitmap width:
fillmap.GetObject(sizeof(BITMAP), &bm);
width = bm.bmWidth;
dcMemory.CreateCompatibleDC(dc);
dcMemory.SelectObject(&fillmap);
int xpos = m_size.left;
dc->SetBkColor(RGB(128, 128, 128));
while (xpos < m_size.right)
{
dc->StretchBlt(xpos, m_size.top, width, m_header_height, &dcMemory, 0, 0, width, bm.bmHeight, SRCCOPY);
xpos += width;
}
if (IsSelected())
{
//highlight selected item
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.top += 1;
rect.bottom -= 2;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
if (m_icon_id_highlight)
{
icon_id = m_icon_id_highlight;
}
}
boxrect = m_size;
boxrect.bottom = boxrect.top + m_header_height;
boxrect.left += 8;
if (icon_id)
{
vspace = boxrect.bottom - boxrect.top;
vspace -= m_icon_height;
vspace /= 2;
PaintIcon(dc, icon_id, boxrect.left, boxrect.top + vspace);
boxrect.left += m_icon_width + ICON_HORZ_SPACE;
}
dc->SetTextColor(RGB(255, 255, 255));
dc->SetBkColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
CString title;
title.Format(_T("Theme: \"%s\""), mpRes->name);
old_font = dc->SelectObject(&ViewHeaderFont);
dc->DrawText(title, boxrect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
dc->SelectObject(old_font);
//paint up and down icons
CBitmap map;
BITMAP bitmap;
map.LoadBitmap(IDB_UP_ARROW_GRAY);
map.GetBitmap(&bitmap);
width = MulDiv(bitmap.bmWidth, m_sys_dpi, DEFAULT_DPI_96);
height = MulDiv(bitmap.bmHeight, m_sys_dpi, DEFAULT_DPI_96);
m_up_icon_rect.left = m_size.right - width - 7;
m_up_icon_rect.top = m_size.top + 2;
m_up_icon_rect.right = m_up_icon_rect.left + width;
m_up_icon_rect.bottom = m_up_icon_rect.top + height;
dcMemory.SelectObject(&map);
dc->StretchBlt(m_up_icon_rect.left, m_up_icon_rect.top, width, height, &dcMemory, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
map.DeleteObject();
map.LoadBitmap(IDB_DOWN_ARROW_GRAY);
map.GetBitmap(&bitmap);
m_down_icon_rect.left = m_up_icon_rect.left;
m_down_icon_rect.top = m_up_icon_rect.bottom;
m_down_icon_rect.right = m_down_icon_rect.left + width;
m_down_icon_rect.bottom = m_down_icon_rect.top + height;
dcMemory.SelectObject(&map);
dc->StretchBlt(m_down_icon_rect.left, m_down_icon_rect.top, width, height, &dcMemory, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintIcon(CDC *dc, int icon_id, int x, int y)
{
CDC dcMemory;
CBitmap icon;
BITMAP bmp;
icon.LoadBitmap(icon_id);
dcMemory.CreateCompatibleDC(dc);
dcMemory.SelectObject(icon);
icon.GetObject(sizeof(BITMAP), &bmp);
dc->StretchBlt(x, y, m_icon_width, m_icon_height, &dcMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintGroupHeader(CDC *dc)
{
CRect boxrect;
CFont *old_font;
CDC dcMemory;
CBitmap fillmap;
CBitmap rightmap;
fillmap.LoadBitmap(IDB_HEADER_BACKGROUND);
BITMAP bm;
int vspace;
int icon_id = m_icon_id;
int width, height;
// go through hoops to get bitmap width:
fillmap.GetObject(sizeof(BITMAP), &bm);
width = bm.bmWidth;
dcMemory.CreateCompatibleDC(dc);
dcMemory.SelectObject(&fillmap);
int xpos = m_size.left;
while(xpos < m_size.right)
{
dc->StretchBlt(xpos, m_size.top, width, m_header_height, &dcMemory, 0, 0, width, bm.bmHeight, SRCCOPY);
xpos += width;
}
if (IsSelected())
{
//highlight selected item
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.bottom = rect.top + m_header_height - 3;
rect.top += 1;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
if (m_icon_id_highlight)
{
icon_id = m_icon_id_highlight;
}
}
boxrect = m_size;
boxrect.bottom = boxrect.top + m_header_height;
boxrect.left += 8;
if (icon_id)
{
vspace = boxrect.bottom - boxrect.top;
vspace -= m_icon_height;
vspace /= 2;
PaintIcon(dc, icon_id, boxrect.left, boxrect.top + vspace);
boxrect.left += m_icon_width + ICON_HORZ_SPACE;
}
if (IsOpen())
{
rightmap.LoadBitmap(IDB_MINUS);
}
else
{
rightmap.LoadBitmap(IDB_PLUS);
}
rightmap.GetObject(sizeof(BITMAP), &bm);
width = MulDiv(bm.bmWidth, m_sys_dpi, DEFAULT_DPI_96);
height = MulDiv(bm.bmHeight, m_sys_dpi, DEFAULT_DPI_96);
vspace = boxrect.bottom - boxrect.top;
vspace -= height;
vspace /= 2;
dcMemory.SelectObject(&rightmap);
dc->StretchBlt(boxrect.right - width - 8, boxrect.top + vspace, width, height,
&dcMemory, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
dc->SetTextColor(RGB(255, 255, 255));
dc->SetBkColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
old_font = dc->SelectObject(&ViewHeaderFont);
dc->DrawText(mpRes->name, boxrect, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
dc->SelectObject(old_font);
// paint the gray background for the column header
if (m_open)
{
boxrect = m_size;
boxrect.top += m_header_height;
//CBrush *old_brush;
CBrush fillbrush;
fillbrush.CreateSolidBrush(RGB(229, 229, 229));
dc->FillRect(&boxrect, &fillbrush);
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintFolderHeader(CDC *dc)
{
CRect boxrect;
CFont *old_font;
int vspace;
// Draw folder icon
boxrect = m_size;
boxrect.bottom = boxrect.top + m_header_height;
boxrect.left += 8;
vspace = boxrect.bottom - boxrect.top;
vspace -= m_icon_height;
vspace /= 2;
if (IsOpen())
{
PaintIcon(dc, IDB_FOLDER_OPEN, boxrect.left, boxrect.top + vspace);
}
else
{
PaintIcon(dc, IDB_FOLDER_CLOSE, boxrect.left, boxrect.top + vspace);
}
boxrect.left += m_icon_width + ICON_HORZ_SPACE;
// Draw folder name
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.left = boxrect.left - 3;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
}
dc->SetBkColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
old_font = dc->SelectObject(&ViewHeaderFont);
dc->DrawText(mpRes->name, boxrect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
dc->SelectObject(old_font);
CPen *old_pen;
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
old_pen = dc->SelectObject(&line_pen);
// Draw line across the bottom
dc->MoveTo(m_size.left, m_size.bottom);
dc->LineTo(m_size.right, m_size.bottom);
dc->SelectObject(old_pen);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintColorItemLines(CDC *dc, int offset)
{
CPen *old_pen;
// draw vertical line
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
old_pen = dc->SelectObject(&line_pen);
dc->MoveTo(m_size.left + m_item_height + (COLOR_BOX_SPACE << 1),
m_size.top + offset);
dc->LineTo(m_size.left + m_item_height + (COLOR_BOX_SPACE << 1),
m_size.bottom);
// draw line across the bottom
dc->MoveTo(m_size.left, m_size.bottom);
dc->LineTo(m_size.right, m_size.bottom);
dc->SelectObject(old_pen);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintColorGroupColumnHeader(CDC *dc)
{
PaintColorItemLines(dc, m_header_height - 1);
// draw the text:
// column headers are always black on gray, no matter system color settings
dc->SetTextColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
CFont *old_font = dc->SelectObject(&MediumFont);
dc->TextOut(m_size.left + m_item_height + (COLOR_BOX_SPACE << 1) + COLOR_TEXT_SPACE,
m_size.top + m_header_height + 2,
_T("Name"));
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintColorItem(CDC *dc)
{
CBrush boxbrush;
CBrush *old_brush;
CFont *old_font;
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
UINT nDrawFormat = DT_LEFT|DT_TOP|DT_SINGLELINE|DT_VCENTER;
PaintColorItemLines(dc, 0);
CRect boxrect = m_size;
boxrect.left += COLOR_BOX_SPACE;
boxrect.right = boxrect.left + m_item_height - 1;
boxrect.DeflateRect(2, 3);
boxbrush.CreateSolidBrush(m_boxcolor);
old_brush = dc->SelectObject(&boxbrush);
dc->Rectangle(boxrect);
boxrect.left = m_size.left + m_item_height + (COLOR_BOX_SPACE << 1) + COLOR_TEXT_SPACE;
boxrect.right = m_size.left + GetWidth(dc);
old_font = dc->SelectObject(&NormalFont);
dc->SetBkColor(GetSysColor(COLOR_WINDOW));
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.left = m_size.left + m_item_height + (COLOR_BOX_SPACE << 1) + 1;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
}
dc->DrawText(mpRes->name, boxrect, nDrawFormat);
dc->SelectObject(old_font);
dc->SelectObject(old_brush);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintFontItemLines(CDC *dc, int offset)
{
CPen *old_pen;
// draw vertical lines
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
old_pen = dc->SelectObject(&line_pen);
dc->MoveTo(m_size.left + m_font_preview_width,
m_size.top + offset);
dc->LineTo(m_size.left + m_font_preview_width,
m_size.bottom);
dc->MoveTo(m_size.left + m_font_preview_width + m_font_pixel_width,
m_size.top + offset);
dc->LineTo(m_size.left + m_font_preview_width + m_font_pixel_width,
m_size.bottom);
dc->MoveTo(m_size.right - m_font_storage_width,
m_size.top + offset);
dc->LineTo(m_size.right - m_font_storage_width,
m_size.bottom);
// draw line across the bottom
dc->MoveTo(m_size.left, m_size.bottom);
dc->LineTo(m_size.right, m_size.bottom);
dc->SelectObject(old_pen);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintFontGroupColumnHeader(CDC *dc)
{
PaintFontItemLines(dc, m_header_height - 1);
// draw the text:
// column headers are always black on gray, no matter system color settings
dc->SetTextColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
CFont *old_font = dc->SelectObject(&MediumFont);
RECT rect = m_size;
rect.top += m_header_height + 2;
rect.left += 4;
rect.right = rect.left + m_font_preview_width - 8;
dc->DrawText(_T("View"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = rect.left + m_font_pixel_width - 8;
dc->DrawText(_T("Pix"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = m_size.right - m_font_storage_width - 4;
dc->DrawText(_T("Name"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = m_size.right - 4;
dc->DrawText(_T("Size"), &rect, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintFontItem(CDC *dc)
{
CRect boxrect;
CFont *old_font;
TCHAR pix_size[20];
//Draw font preview
boxrect = m_size;
boxrect.left += 4;
boxrect.right = m_size.left + m_font_preview_width - 4;
if (m_preview_mem)
{
int offset = (boxrect.Height() - m_bitmap.gx_bmp_header.biHeight) / 2;
guix_bitmap_flush(dc->GetSafeHdc(), boxrect.left, boxrect.top + offset,
boxrect.right - boxrect.left + 1, m_preview_mem, &m_bitmap);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc->SetBkColor(GetSysColor(COLOR_WINDOW));
dc->DrawText(mpRes->name, boxrect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_VCENTER);
}
//Draw pix size
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.left = m_size.left + m_font_preview_width + 1;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
}
PaintFontItemLines(dc, 0);
dc->SetBkColor(GetSysColor(COLOR_WINDOW));
old_font = dc->SelectObject(&NormalFont);
boxrect.left = boxrect.right + 8;
boxrect.right = boxrect.left + m_font_pixel_width - 8;
_itot(mpRes->font_height, pix_size, 10);
dc->DrawText(pix_size, boxrect, DT_RIGHT | DT_TOP | DT_SINGLELINE | DT_VCENTER);
//Draw font name
boxrect.left = boxrect.right + 8;
boxrect.right = m_size.right - m_font_storage_width - 4;
dc->DrawText(mpRes->name, boxrect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_VCENTER);
// Display resource storage.
boxrect.left = boxrect.right + 8;
boxrect.right = m_size.right - 4;
int storage = (mpRes->storage_size + 1023) >> 10;
CString str = NumberFormatWithCommas(storage);
str.Append(_T("KB"));
dc->DrawText(str, &boxrect, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintPixelmapItemLines(CDC *dc, int offset)
{
CPen *old_pen;
int xpos;
// draw vertical line
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
old_pen = dc->SelectObject(&line_pen);
xpos = m_size.left + m_thumbnail_size + (ITEM_VERT_SPACE * 2);
dc->MoveTo(xpos, m_size.top + offset);
dc->LineTo(xpos, m_size.bottom);
xpos += m_pixelmap_dimension_width;
dc->MoveTo(xpos, m_size.top + offset);
dc->LineTo(xpos, m_size.bottom);
xpos = m_size.right - m_pixelmap_storage_width;
dc->MoveTo(xpos, m_size.top + offset);
dc->LineTo(xpos, m_size.bottom);
// draw line across the bottom
dc->MoveTo(m_size.left, m_size.bottom);
dc->LineTo(m_size.right, m_size.bottom);
dc->SelectObject(old_pen);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintPixelmapGroupColumnHeader(CDC *dc)
{
PaintPixelmapItemLines(dc, m_header_height - 1);
// draw the text:
dc->SetTextColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
CFont *old_font = dc->SelectObject(&MediumFont);
RECT rect = m_size;
rect.top += m_header_height + 2;
rect.left += 4;
rect.right = rect.left + m_thumbnail_size + (ITEM_VERT_SPACE * 2) - 8;
dc->DrawText(_T("View"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = rect.left + m_pixelmap_dimension_width - 8;
dc->DrawText(_T("Dims"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = m_size.right - m_pixelmap_storage_width - 4;
dc->DrawText(_T("Name"), &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
rect.left = rect.right + 8;
rect.right = m_size.right - 4;
dc->DrawText(_T("Size"), &rect, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintPixelmapItem(CDC *dc)
{
CRect boxrect = m_size;
boxrect.left += 4;
boxrect.right = boxrect.left + m_thumbnail_size + (ITEM_VERT_SPACE * 2) - 8;
// Draw pixelmap preview
if (m_preview_mem)
{
int vspace = boxrect.bottom - boxrect.top + 1;
vspace -= m_bitmap.gx_bmp_header.biHeight;
vspace /= 2;
int hspace = m_thumbnail_size;
hspace -= m_bitmap.gx_bmp_header.biWidth;
hspace /= 2;
if (hspace < 0)
{
hspace = 0;
}
guix_bitmap_flush(dc->GetSafeHdc(),
boxrect.left + hspace,
boxrect.top + vspace,
boxrect.right - boxrect.left + 1,
m_preview_mem, &m_bitmap);
}
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
CRect rect = m_size;
rect.left = m_size.left + m_thumbnail_size + (ITEM_VERT_SPACE * 2) + 1;
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&rect, &brush);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
}
PaintPixelmapItemLines(dc, 0);
dc->SetBkMode(TRANSPARENT);
CFont *old_font = dc->SelectObject(&NormalFont);
CString str;
// Draw pixelmap size.
boxrect.left = boxrect.right + 8;
boxrect.right = boxrect.left + m_pixelmap_dimension_width - 8;
GX_PIXELMAP* map = mpRes->GetPixelmap();
if (map)
{
str.Format(_T("%d x %d"), map->gx_pixelmap_width, map->gx_pixelmap_height);
dc->DrawText(str, &boxrect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
}
// Draw pixelmap name.
boxrect.left = boxrect.right + 8;
boxrect.right = m_size.right - m_pixelmap_storage_width - 4;
dc->DrawText(mpRes->name, &boxrect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
// Draw resource storage size.
boxrect.left = boxrect.right + 8;
boxrect.right = m_size.right - 8;
int storage = (mpRes->storage_size + 1023) >> 10;
str = NumberFormatWithCommas(storage);
str.Append(_T("KB"));
dc->DrawText(str, &boxrect, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintStringItemLines(CDC *dc, int offset)
{
CPen *old_pen;
// draw vertical lines
CPen line_pen(PS_SOLID, 1, RGB(192, 192, 192));
old_pen = dc->SelectObject(&line_pen);
dc->MoveTo(m_size.left + m_string_id_width,
m_size.top + offset);
dc->LineTo(m_size.left + m_string_id_width,
m_size.bottom);
// draw line across the bottom
dc->MoveTo(m_size.left, m_size.bottom);
dc->LineTo(m_size.right, m_size.bottom);
dc->SelectObject(old_pen);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintStringGroupColumnHeader(CDC *dc)
{
PaintStringItemLines(dc, m_header_height - 1);
CRect textrect;
int xpos;
// draw the text:
// column headers are always white on gray, no matter the system color settings.
dc->SetTextColor(RGB(0, 0, 0));
dc->SetBkMode(TRANSPARENT);
CFont *old_font = dc->SelectObject(&MediumFont);
dc->TextOut(m_size.left + 4,
m_size.top + m_header_height + 2,
_T("String ID"));
studiox_project *project = GetOpenProject();
if (project && mpRes)
{
int display = project->GetDisplayIndex(mpRes);
if (display < 0)
{
return;
}
string_table *table = project->mDisplays[display].stable;
if (!table)
{
return;
}
int language = table->GetActiveLanguage();
xpos = m_size.left + m_string_id_width + 4;
textrect.SetRect(xpos, m_size.top + m_header_height + 2,
m_size.right - 32, m_size.bottom);
dc->DrawText(project->mHeader.languages[language].name, &textrect, DT_LEFT);
CBitmap map;
BITMAP bmp;
map.LoadBitmap(IDB_RIGHT_ARROW);
map.GetBitmap(&bmp);
int dpi = GetSystemDPI();
m_string_arrow_icon_width = MulDiv(bmp.bmWidth, dpi, DEFAULT_DPI_96);
xpos = m_size.right - m_string_arrow_icon_width;
PaintBmp(dc, xpos, m_size.top + m_header_height + 6, IDB_RIGHT_ARROW);
xpos -= m_string_arrow_icon_width;
PaintBmp(dc, xpos, m_size.top + m_header_height + 6, IDB_LEFT_ARROW);
}
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintStringItem(CDC *dc)
{
int left = m_size.left + 4;
CRect textrect = m_size;
textrect.left += 4;
textrect.right = m_size.left + m_string_id_width - 4;
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&m_size, &brush);
}
else
{
dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
}
PaintStringItemLines(dc, 0);
CFont *old_font = dc->SelectObject(&NormalFont);
dc->DrawText(display_id, &textrect, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
textrect.left = m_size.left + m_string_id_width + 4;
textrect.right = m_size.right - 4;
#ifdef _UNICODE
DrawTextW(*dc, string_val.GetString(), -1, &textrect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
#else
wchar_t *uni_text = CStringToWideChar(string_val);
if (uni_text)
{
DrawTextW(*dc, uni_text, -1, &textrect, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
delete [] uni_text;
}
#endif
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintAddNewItem(CDC* dc)
{
CFont *old_font = dc->SelectObject(&NormalFont);
int icon_id = m_icon_id;
if (IsSelected())
{
//highlight selected item
dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
CBrush brush(GetSysColor(COLOR_HIGHLIGHT));
//FillRect does not include the rectangle's right and bottom sides
dc->FillRect(&m_size, &brush);
if (m_icon_id_highlight)
{
icon_id = m_icon_id_highlight;
}
}
else
{
dc->SetTextColor(GetSysColor(COLOR_MENUTEXT));
}
if (icon_id)
{
int offset = (m_size.Height() - m_icon_height) >> 1;
PaintIcon(dc, icon_id, m_size.left + 8, m_size.top + offset);
}
CRect boxrect = m_size;
boxrect.left += m_icon_width + 16;
dc->SetBkColor(GetSysColor(COLOR_WINDOW));
dc->DrawText(mpRes->name, &boxrect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
dc->SelectObject(old_font);
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::Paint(CDC *dc)
{
if (m_visible)
{
int type = GetResType();
switch(type)
{
case RES_TYPE_HEADER:
if (mpRes->folder_id == THEME_HEADER)
{
PaintThemeHeader(dc);
}
break;
case RES_TYPE_GROUP:
PaintGroupHeader(dc);
if (m_open)
{
switch(mpRes->folder_id)
{
case COLOR_GROUP:
PaintColorGroupColumnHeader(dc);
break;
case FONT_GROUP:
PaintFontGroupColumnHeader(dc);
break;
case PIXELMAP_GROUP:
PaintPixelmapGroupColumnHeader(dc);
break;
case STRING_GROUP:
PaintStringGroupColumnHeader(dc);
break;
default:
break;
}
}
break;
case RES_TYPE_FOLDER:
if ((mpRes->folder_id == DEFAULT_PIXELMAP_FOLDER) ||
(mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER))
{
PaintFolderHeader(dc);
}
break;
case RES_TYPE_COLOR:
PaintColorItem(dc);
break;
case RES_TYPE_FONT:
PaintFontItem(dc);
break;
case RES_TYPE_PIXELMAP:
PaintPixelmapItem(dc);
break;
case RES_TYPE_STRING:
PaintStringItem(dc);
break;
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
PaintAddNewItem(dc);
break;
default:
break;
}
if (m_open && m_first)
{
m_first->Paint(dc);
}
}
if (m_next)
{
m_next->Paint(dc);
}
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::GetItemHeight()
{
return m_item_height;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::GetHeight()
{
int height = 0;
int type = RES_TYPE_STRING;
if (mpRes)
{
type = mpRes->type;
}
switch(type)
{
case RES_TYPE_HEADER:
if (mpRes->folder_id == THEME_HEADER)
{
return m_header_height;
}
else
{
return 0;
}
break;
case RES_TYPE_GROUP:
if (m_open)
{
return m_header_height + m_item_height;
}
else
{
return m_header_height;
}
break;
case RES_TYPE_STRING:
case RES_TYPE_COLOR:
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
height = m_item_height;
break;
case RES_TYPE_FOLDER:
if ((mpRes->folder_id == DEFAULT_PIXELMAP_FOLDER) ||
(mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER))
{
return m_header_height;
}
return 0;
case RES_TYPE_FONT:
if (!m_preview_mem)
{
MakeFontPreview();
}
if (m_preview_mem)
{
height = MulDiv(m_bitmap.gx_bmp_header.biHeight, m_sys_dpi, DEFAULT_DPI_96) + 4;
}
else
{
height = m_item_height;
}
break;
case RES_TYPE_PIXELMAP:
if (!m_preview_mem)
{
MakePixelmapPreview();
}
height = m_item_height;
if (m_preview_mem)
{
if (m_bitmap.gx_bmp_header.biHeight > height)
{
height = m_bitmap.gx_bmp_header.biHeight;
}
}
height += ITEM_VERT_SPACE * 2;
break;
default:
break;
}
return height;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::GetWidth(CDC *dc)
{
CFont *old_font;
int width = 0;
int type = RES_TYPE_STRING;
if (mpRes)
{
type = mpRes->type;
}
switch(type)
{
case RES_TYPE_HEADER:
break;
case RES_TYPE_GROUP:
width = 8 + (m_indent * TREE_INDENT);
old_font = dc->SelectObject(&MediumFont);
width += dc->GetTextExtent(mpRes->name).cx;
dc->SelectObject(old_font);
break;
case RES_TYPE_COLOR:
width = m_item_height + (COLOR_BOX_SPACE << 1);
width += dc->GetTextExtent(mpRes->name).cx + (COLOR_TEXT_SPACE << 1);
if (width < mpTree->GetViewWidth())
{
width = mpTree->GetViewWidth();
}
break;
case RES_TYPE_FONT:
if (!m_preview_mem)
{
MakeFontPreview();
}
if (m_preview_mem)
{
width = m_bitmap.gx_bmp_header.biWidth + 8;
}
else
{
old_font = dc->SelectObject(&NormalFont);
width = dc->GetTextExtent(mpRes->name).cx;
dc->SelectObject(old_font);
}
if (width < mpTree->GetViewWidth())
{
width = mpTree->GetViewWidth();
}
break;
case RES_TYPE_PIXELMAP:
width = mpTree->GetViewWidth();
break;
case RES_TYPE_STRING:
width = 8 + (m_indent * TREE_INDENT);
width += dc->GetTextExtent(display_id).cx;
width += dc->GetTextExtent(string_val).cx;
break;
default:
width = 8 + (m_indent * TREE_INDENT);
old_font = dc->SelectObject(&NormalFont);
width += dc->GetTextExtent(mpRes->name).cx;
dc->SelectObject(old_font);
break;
}
return width;
}
#if 0
int resource_item::LayoutColorGrid(int top)
{
CRect childsize;
int step = COLOR_BOX_SIZE + COLOR_BOX_SPACE;
top += COLOR_BOX_SPACE;
childsize.SetRect(m_size.left + COLOR_BOX_SPACE,
top,
m_size.left + step - 1,
top + COLOR_BOX_SIZE - 1);
resource_item *child = First();
while(child)
{
child->SetPos(childsize);
if (childsize.right + step > m_size.right)
{
top += step;
childsize.SetRect(m_size.left + COLOR_BOX_SPACE,
top,
m_size.left + step - 1,
top + COLOR_BOX_SIZE - 1);
}
else
{
childsize.OffsetRect(step, 0);
}
child = child->Next();
}
if (mpRes->resource_id == CUSTOM_COLOR_FOLDER)
{
if (childsize.right + step > m_size.right)
{
top += step;
m_add_icon_y = top;
m_add_icon_x = m_size.left + COLOR_BOX_SPACE;
}
else
{
m_add_icon_y = top;
m_add_icon_x = childsize.left;
}
}
return top + step;
}
#endif
///////////////////////////////////////////////////////////////////////////////
resource_item *resource_item::SortFirst()
{
resource_item *winner = NULL;
resource_item *child = First();
while(child)
{
switch(child->GetResType())
{
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
break;
default:
if (!winner)
{
winner = child;
}
else
{
if (_tcscmp(child->mpRes->name, winner->mpRes->name) < 0)
{
winner = child;
}
}
break;
}
child = child->Next();
}
return winner;
}
///////////////////////////////////////////////////////////////////////////////
resource_item *resource_item::SortNext(resource_item *current)
{
resource_item *winner = NULL;
resource_item *child = First();
while(child)
{
switch (child->GetResType())
{
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
break;
default:
if (_tcscmp(child->mpRes->name, current->mpRes->name) > 0)
{
if (!winner)
{
winner = child;
}
else
{
if (_tcscmp(child->mpRes->name, winner->mpRes->name) < 0)
{
winner = child;
}
}
}
break;
}
child = child->Next();
}
return winner;
}
///////////////////////////////////////////////////////////////////////////////
resource_item* resource_item::FindAddNewItem()
{
resource_item* child = First();
while (child)
{
switch (child->GetResType())
{
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
return child;
default:
break;
}
child = child->Next();
}
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
resource_item* resource_item::NavigateFirst()
{
resource_item* first = NULL;
switch (GetResType())
{
case RES_TYPE_FOLDER:
first = SortFirst();
break;
case RES_TYPE_GROUP:
first = First();
if (first->GetResType() == RES_TYPE_FOLDER)
{
switch (first->mpRes->folder_id)
{
case DEFAULT_COLOR_FOLDER:
case CUSTOM_COLOR_FOLDER:
case DEFAULT_FONT_FOLDER:
case CUSTOM_FONT_FOLDER:
// Skip folders which is invisible.
first = first->SortFirst();
break;
}
}
break;
default:
first = First();
break;
}
return first;
}
///////////////////////////////////////////////////////////////////////////////
resource_item* resource_item::NavigateLast()
{
resource_item* last = NULL;
resource_item* next;
switch (GetResType())
{
case RES_TYPE_FOLDER:
if (mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER)
{
last = FindAddNewItem();
}
else
{
next = SortFirst();
do
{
last = next;
next = SortNext(last);
} while (next);
}
break;
case RES_TYPE_GROUP:
last = Last();
if (last->GetResType() == RES_TYPE_FOLDER)
{
switch (last->mpRes->folder_id)
{
case DEFAULT_COLOR_FOLDER:
case CUSTOM_COLOR_FOLDER:
case DEFAULT_FONT_FOLDER:
case CUSTOM_FONT_FOLDER:
// Skip folders which is invisible.
last = last->FindAddNewItem();
break;
}
}
break;
default:
last = Last();
break;
}
return last;
}
///////////////////////////////////////////////////////////////////////////////
resource_item* resource_item::NavigateNext()
{
resource_item* next = NULL;
resource_item* parent;
switch (GetResType())
{
case RES_TYPE_FONT:
case RES_TYPE_COLOR:
case RES_TYPE_PIXELMAP:
// Pick parent item.
parent = Parent();
if (parent->GetResType() == RES_TYPE_FOLDER)
{
// Sort next item.
next = parent->SortNext(this);
if (next == NULL)
{
switch (parent->mpRes->folder_id)
{
case DEFAULT_COLOR_FOLDER:
case DEFAULT_FONT_FOLDER:
// Set the first custom color/font item to be the next sibling of the last default color/font item.
parent = parent->Next();
if (parent)
{
next = parent->SortFirst();
}
break;
}
if (next == NULL)
{
next = parent->FindAddNewItem();
}
}
}
break;
case RES_TYPE_ADD_COLOR:
case RES_TYPE_ADD_FONT:
case RES_TYPE_ADD_PIXELMAP:
case RES_TYPE_ADD_STRING:
break;
default:
next = Next();
break;
}
return next;
}
///////////////////////////////////////////////////////////////////////////////
resource_item* resource_item::NavigateParent()
{
int restype = GetResType();
if (restype == RES_TYPE_HEADER ||
restype == RES_TYPE_GROUP)
{
return NULL;
}
resource_item* parent = Parent();
if (parent && parent->GetResType() == RES_TYPE_FOLDER)
{
switch (parent->mpRes->folder_id)
{
case DEFAULT_COLOR_FOLDER:
case CUSTOM_COLOR_FOLDER:
case DEFAULT_FONT_FOLDER:
case CUSTOM_FONT_FOLDER:
// Skip folders which is invisible
parent = parent->Parent();
break;
}
}
return parent;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::LayoutFolderChildren(CDC *dc, int top)
{
resource_item *child;
CRect size;
int height;
int width;
child = SortFirst();
while(child)
{
height = child->GetHeight();
width = child->GetWidth(dc);
size.SetRect(0, top, width, top + height - 1);
child->SetPos(size);
top += height;
child = SortNext(child);
}
resource_item* pAdd = FindAddNewItem();
if (pAdd)
{
//position "Add New" icon
height = pAdd->GetHeight();
width = mpTree->GetViewWidth();
size.SetRect(0, top, width, top + height);
pAdd->SetPos(size);
top += height;
}
return top;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::CheckClickCommand(CPoint &click)
{
CRect size;
if (!mpRes)
{
return CMD_NO_COMMAND;
}
if ((mpRes->type == RES_TYPE_HEADER) &&
(mpRes->folder_id == THEME_HEADER))
{
if (m_up_icon_rect.PtInRect(click))
{
return CMD_INC_THEME;
}
else if (m_down_icon_rect.PtInRect(click))
{
return CMD_DEC_THEME;
}
}
else if (mpRes->type == RES_TYPE_GROUP &&
mpRes->folder_id == STRING_GROUP)
{
// test here for inc/dec language commands:
size.right = m_size.right;
size.left = size.right - m_string_arrow_icon_width;
size.top = m_size.top + m_header_height + 6;
size.bottom = size.top + m_string_arrow_icon_width;
if (size.PtInRect(click))
{
return CMD_INC_LANGUAGE;
}
size.OffsetRect(-12, 0);
if (size.PtInRect(click))
{
return CMD_DEC_LANGUAGE;
}
}
return CMD_NO_COMMAND;
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::SetColorValue(GX_COLOR val)
{
if (mpRes)
{
mpRes->colorval = val;
RebuildPreview();
}
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::SetIcon(int IconId, int IconIdHighlight)
{
m_icon_id = IconId;
m_icon_id_highlight = IconIdHighlight;
CBitmap icon;
BITMAP bmp;
if (IconId)
{
if (icon.LoadBitmap(IconId))
{
icon.GetBitmap(&bmp);
m_icon_width = MulDiv(bmp.bmWidth, m_sys_dpi, DEFAULT_DPI_96);
m_icon_height = MulDiv(bmp.bmHeight, m_sys_dpi, DEFAULT_DPI_96);
}
}
}
///////////////////////////////////////////////////////////////////////////////
COLORREF resource_item::MakeColorRef(GX_COLOR val)
{
UCHAR Red = (UCHAR) (val >> 16);
UCHAR Green = (UCHAR) ((val >> 8) & 0xff);
UCHAR Blue = (UCHAR) (val & 0xff);
return(RGB(Red, Green, Blue));
}
///////////////////////////////////////////////////////////////////////////////
GX_COLOR resource_item::GetRGBColor(int display_index)
{
GX_COLOR *palette;
int palsize;
GX_COLOR color = 0;
studiox_project *project = GetOpenProject();
if (mpRes == NULL || project == NULL)
{
return color;
}
if (mpRes->type != RES_TYPE_COLOR)
{
return color;
}
if (display_index == -1)
{
display_index = project->GetDisplayIndex(mpRes);
}
/* only 8bit driver need get rgb color from palette table now.
4bpp driver contains palette table but we can calculate its gray value directly. */
if (project->mDisplays[display_index].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE)
{
int active_theme = project->mDisplays[display_index].active_theme;
// colorval is a palette index, lookup rgb and convert to COLORREF
palette = project->mDisplays[display_index].themes[active_theme].palette;
palsize = project->mDisplays[display_index].themes[active_theme].palette_predefined;
if ((ULONG) mpRes->colorval >= (ULONG) palsize)
{
/* this should not be allowed to happen, but just as a safety check
if the palette size has been changed and we didn't update the color
indexes correctly, do a final safety check here
*/
mpRes->colorval = 0;
}
if (palette && ((int) mpRes->colorval >= 0 && (int) mpRes->colorval < palsize))
{
color = palette[mpRes->colorval];
}
}
else
{
color = mpRes->colorval;
}
if (!IsAlphaFormat(project->mDisplays[display_index].colorformat))
{
color |= 0xff000000;
}
return color;
}
///////////////////////////////////////////////////////////////////////////////
int resource_item::GetResType()
{
if (mpRes)
{
return mpRes->type;
}
return RES_TYPE_STRING;
}
///////////////////////////////////////////////////////////////////////////////
resource_item_provider* resource_item::GetResItemProvider()
{
if (m_pResItemProvider == NULL)
{
m_pResItemProvider = new resource_item_provider(this);
}
return m_pResItemProvider;
}
///////////////////////////////////////////////////////////////////////////////
CString resource_item::GetName()
{
int type = GetResType();
switch(type)
{
case RES_TYPE_STRING:
return string_val;
}
if (mpRes)
{
return mpRes->name;
}
return _T("");
}
///////////////////////////////////////////////////////////////////////////////
CString resource_item::GetDescription()
{
int type = GetResType();
CString description(L"");
switch (type)
{
case RES_TYPE_FONT:
if (mpRes)
{
description.Format(L"Pix: %d, Name: %s, Size: %d kilobyte", mpRes->font_height, mpRes->name, (mpRes->storage_size + 1023) >> 10);
}
break;
case RES_TYPE_PIXELMAP:
if(mpRes)
{
GX_PIXELMAP *map = mpRes->GetPixelmap();
if (map)
{
description.Format(L"Dims: %d by %d, Name: %s, Size: %d kilobyte", map->gx_pixelmap_width, map->gx_pixelmap_height, mpRes->name,
(mpRes->storage_size + 1023) >> 10);
}
}
break;
case RES_TYPE_STRING:
description.Format(L"String ID: %s, String value: %s", string_id, string_val);
break;
}
return description;
}
///////////////////////////////////////////////////////////////////////////////
void resource_item::PaintHighlightRect(CDC* dc, CRect *rect)
{
//Draw a blue rectangle to highlight the item
CPen penBlue(PS_SOLID, 2, GetSysColor(COLOR_HIGHLIGHT));
CPen *pOldPen = dc->SelectObject(&penBlue);
CBrush *pOldBrush = (CBrush *)dc->SelectStockObject(NULL_BRUSH);
dc->Rectangle(*rect);
dc->SelectObject(pOldPen);
dc->SelectObject(pOldBrush);
}
///////////////////////////////////////////////////////////////////////////////
BOOL resource_item::IsSelected()
{
resource_view* view = GetResourceView();
if (view && (GetFocus() == view->GetSafeHwnd()) && (mpTree->GetCurrentItem() == this))
{
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL resource_item::IsAlphaFormat(int color_format)
{
if (color_format == GX_COLOR_FORMAT_32ARGB ||
color_format == GX_COLOR_FORMAT_32BGRA ||
color_format == GX_COLOR_FORMAT_4444ARGB ||
color_format == GX_COLOR_FORMAT_4444BGRA)
{
return TRUE;
}
return FALSE;
}