//static
void TBNodeRefTree::ResolveConditions(TBNode *parent_node)
{
	bool condition_ret = false;
	TBNode *node = parent_node->GetFirstChild();
	while (node)
	{
		bool delete_node = false;
		bool move_children = false;
		if (strcmp(node->GetName(), "@if") == 0)
		{
			condition_ret = node->GetValueFollowRef().GetInt() ? true : false;
			if (condition_ret)
				move_children = true;
			delete_node = true;
		}
		else if (strcmp(node->GetName(), "@else") == 0)
		{
			condition_ret = !condition_ret;
			if (condition_ret)
				move_children = true;
			delete_node = true;
		}

		// Make sure we'll skip any nodes added from a conditional branch.
		TBNode *node_next = node->GetNext();

		if (move_children)
		{
			// Resolve the branch first, since we'll skip it.
			ResolveConditions(node);
			while (TBNode *content = node->GetLastChild())
			{
				node->Remove(content);
				parent_node->AddAfter(content, node);
			}
		}

		if (delete_node)
			parent_node->Delete(node);
		else
			ResolveConditions(node);
		node = node_next;
	}
}
bool TBBFRenderer::Load(const char *filename, int size)
{
    m_size = size;
    if (!m_node.ReadFile(filename))
        return false;

    // Check for size nodes and get the one closest to the size we want.
    TBNode *size_node = nullptr;
    for (TBNode *n = m_node.GetFirstChild(); n; n = n->GetNext())
    {
        if (strcmp(n->GetName(), "size") == 0)
        {
            if (!size_node || ABS(m_size - n->GetValue().GetInt()) < ABS(m_size - size_node->GetValue().GetInt()))
                size_node = n;
        }
    }
    if (!size_node)
        return false;

    // Metrics
    m_metrics.ascent = size_node->GetValueInt("ascent", 0);
    m_metrics.descent = size_node->GetValueInt("descent", 0);
    m_metrics.height = m_metrics.ascent + m_metrics.descent;

    // Other data
    m_advance_delta = size_node->GetValueInt("advance_delta", 0);
    m_space_advance = size_node->GetValueInt("space_advance", 0);
    m_x_ofs = size_node->GetValueInt("x_ofs", 0);

    // Info
    m_rgb = m_node.GetValueInt("info>rgb", 0);

    // Get the path for the bitmap file.
    TBTempBuffer bitmap_filename;
    if (!bitmap_filename.AppendPath(filename))
        return false;

    // Append the bitmap filename for the given size.
    bitmap_filename.AppendString(size_node->GetValueString("bitmap", ""));

    m_img = TBImageLoader::CreateFromFile(bitmap_filename.GetData());

    return FindGlyphs();
}
示例#3
0
bool TBLanguage::Load(const char *filename)
{
	// Read the file into a node tree (even though it's only a flat list)
	TBNode node;
	if (!node.ReadFile(filename))
		return false;

	// Go through all nodes and add to the strings hash table
	TBNode *n = node.GetFirstChild();
	while (n)
	{
		const char *str = n->GetValue().GetString();
		TBStr *new_str = new TBStr(str);
		if (!new_str || !strings.Add(TBID(n->GetName()), new_str))
		{
			delete new_str;
			return false;
		}
		n = n->GetNext();
	}
	return true;
}
bool TBBFRenderer::FindGlyphs()
{
	if (!m_img)
		return false;

	const char *glyph_str = m_node.GetValueString("info>glyph_str", nullptr);
	if (!glyph_str)
		return false;

	int glyph_str_len = strlen(glyph_str);
	int i = 0;
	int x = 0;
	while (UCS4 uc = utf8::decode_next(glyph_str, &i, glyph_str_len))
	{
		if (GLYPH *glyph = FindNext(uc, x))
		{
			m_glyph_table.Add(uc, glyph); // OOM!
			x = glyph->x + glyph->w + 1;
		}
		else
			break;
	}
	return true;
}
bool TBWidgetsReader::CreateWidget(TBWidget *target, TBNode *node, WIDGET_Z add_child_z)
{
	CREATE_INFO info = { this, target->GetContentRoot(), node };

	// Find a widget creator from the node name
	TBWidgetFactory *wc = nullptr;
	for (wc = factories.GetFirst(); wc; wc = wc->GetNext())
		if (strcmp(node->GetName(), wc->name) == 0)
			break;

	// Create the widget
	TBWidget *new_widget = wc ? wc->Create(&info) : nullptr;
	if (!new_widget)
		return false;

	// Read generic properties

	SetIDFromNode(new_widget->GetID(), node->GetNode("id"));

	SetIDFromNode(new_widget->GetGroupID(), node->GetNode("group-id"));

	if (wc->sync_type == TBValue::TYPE_FLOAT)
		new_widget->SetValueDouble(node->GetValueFloat("value", 0));
	else
		new_widget->SetValue(node->GetValueInt("value", 0));

	if (TBNode *data_node = node->GetNode("data"))
		new_widget->data.Copy(data_node->GetValue());

	new_widget->SetIsGroupRoot(node->GetValueInt("is-group-root", new_widget->GetIsGroupRoot()) ? true : false);

	new_widget->SetIsFocusable(node->GetValueInt("is-focusable", new_widget->GetIsFocusable()) ? true : false);

	new_widget->SetWantLongClick(node->GetValueInt("want-long-click", new_widget->GetWantLongClick()) ? true : false);

	new_widget->SetIgnoreInput(node->GetValueInt("ignore-input", new_widget->GetIgnoreInput()) ? true : false);

	new_widget->SetOpacity(node->GetValueFloat("opacity", new_widget->GetOpacity()));

	if (const char *text = node->GetValueString("text", nullptr))
		new_widget->SetText(text);

	if (const char *connection = node->GetValueStringRaw("connection", nullptr))
	{
		// If we already have a widget value with this name, just connect to it and the widget will
		// adjust its value to it. Otherwise create a new widget value, and give it the value we
		// got from the resource.
		if (TBWidgetValue *value = g_value_group.GetValue(connection))
			new_widget->Connect(value);
		else if (TBWidgetValue *value = g_value_group.CreateValueIfNeeded(connection, wc->sync_type))
		{
			value->SetFromWidget(new_widget);
			new_widget->Connect(value);
		}
	}
	if (const char *gravity = node->GetValueString("gravity", nullptr))
	{
		WIDGET_GRAVITY g = WIDGET_GRAVITY_NONE;
		if (strstr(gravity, "left"))		g |= WIDGET_GRAVITY_LEFT;
		if (strstr(gravity, "top"))			g |= WIDGET_GRAVITY_TOP;
		if (strstr(gravity, "right"))		g |= WIDGET_GRAVITY_RIGHT;
		if (strstr(gravity, "bottom"))		g |= WIDGET_GRAVITY_BOTTOM;
		if (strstr(gravity, "all"))			g |= WIDGET_GRAVITY_ALL;
		if (!(g & WIDGET_GRAVITY_LEFT_RIGHT))
			g |= WIDGET_GRAVITY_LEFT;
		if (!(g & WIDGET_GRAVITY_TOP_BOTTOM))
			g |= WIDGET_GRAVITY_TOP;
		new_widget->SetGravity(g);
	}
	if (const char *state = node->GetValueString("state", nullptr))
	{
		if (strstr(state, "disabled"))
			new_widget->SetState(WIDGET_STATE_DISABLED, true);
	}
	if (const char *skin = node->GetValueString("skin", nullptr))
	{
		new_widget->SetSkinBg(skin);
	}

	if (TBNode *lp = node->GetNode("lp"))
	{
		LayoutParams layout_params;
		if (new_widget->GetLayoutParams())
			layout_params = *new_widget->GetLayoutParams();
		const TBDimensionConverter *dc = g_tb_skin->GetDimensionConverter();
		if (const char *str = lp->GetValueString("width", nullptr))
			layout_params.SetWidth(dc->GetPxFromString(str, LayoutParams::UNSPECIFIED));
		if (const char *str = lp->GetValueString("height", nullptr))
			layout_params.SetHeight(dc->GetPxFromString(str, LayoutParams::UNSPECIFIED));
		if (const char *str = lp->GetValueString("min-width", nullptr))
			layout_params.min_w = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		if (const char *str = lp->GetValueString("max-width", nullptr))
			layout_params.max_w = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		if (const char *str = lp->GetValueString("pref-width", nullptr))
			layout_params.pref_w = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		if (const char *str = lp->GetValueString("min-height", nullptr))
			layout_params.min_h = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		if (const char *str = lp->GetValueString("max-height", nullptr))
			layout_params.max_h = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		if (const char *str = lp->GetValueString("pref-height", nullptr))
			layout_params.pref_h = dc->GetPxFromString(str, LayoutParams::UNSPECIFIED);
		new_widget->SetLayoutParams(layout_params);
	}

	target->GetContentRoot()->OnInflateChild(new_widget);

	// Add the new widget to the hiearchy
	target->GetContentRoot()->AddChild(new_widget, add_child_z);

	// Read the font now when the widget is in the hiearchy so inheritance works.
	if (TBNode *font = node->GetNode("font"))
	{
		TBFontDescription fd = new_widget->GetCalculatedFontDescription();
		if (const char *size = font->GetValueString("size", nullptr))
		{
			int new_size = g_tb_skin->GetDimensionConverter()->GetPxFromString(size, fd.GetSize());
			fd.SetSize(new_size);
		}
		if (const char *name = font->GetValueString("name", nullptr))
			fd.SetID(name);
		new_widget->SetFontDescription(fd);
	}

	// Iterate through all nodes and create widgets
	for (TBNode *n = node->GetFirstChild(); n; n = n->GetNext())
		CreateWidget(new_widget, n, wc->add_child_z);

	if (node->GetValueInt("autofocus", 0))
		new_widget->SetFocus(WIDGET_FOCUS_REASON_UNKNOWN);

	return true;
}
void TBWidgetsReader::LoadNodeTree(TBWidget *target, TBNode *node)
{
	// Iterate through all nodes and create widgets
	for (TBNode *child = node->GetFirstChild(); child; child = child->GetNext())
		CreateWidget(target, child, WIDGET_Z_TOP);
}