//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(); }
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); }