void ResourceEditWindow::AddWidgetListItemsRecursive(TBWidget *widget, int depth) { if (depth > 0) // Ignore the root { // Add a new ResourceItem for this widget TBStr str; const char *classname = widget->GetClassName(); if (!*classname) classname = "<Unknown widget type>"; str.SetFormatted("% *s%s", depth - 1, "", classname); if (ResourceItem *item = new ResourceItem(widget, str)) m_widget_list_source.AddItem(item); } for (TBWidget *child = widget->GetFirstChild(); child; child = child->GetNext()) AddWidgetListItemsRecursive(child, depth + 1); }
void DemoApplication::RenderFrame(int window_w, int window_h) { // Override RenderFrame without calling super, since we want // to inject code between BeginPaint/EndPaint. // Application::RenderFrame(window_w, window_h); // Render g_renderer->BeginPaint(window_w, window_h); GetRoot()->InvokePaint(TBWidget::PaintProps()); #if defined(TB_RUNTIME_DEBUG_INFO) && defined(TB_IMAGE) // Enable to debug image manager fragments //g_image_manager->Debug(); #endif frame_counter++; frame_counter_total++; // Update the FPS counter double time = TBSystem::GetTimeMS(); if (time > frame_counter_reset_time + 1000) { fps = (int) ((frame_counter / (time - frame_counter_reset_time)) * 1000); frame_counter_reset_time = time; frame_counter = 0; } // Draw FPS TBWidgetValue *continuous_repaint_val = g_value_group.GetValue(TBIDC("continous-repaint")); bool continuous_repaint = continuous_repaint_val ? !!continuous_repaint_val->GetInt() : 0; TBStr str; if (continuous_repaint) str.SetFormatted("FPS: %d Frame %d", fps, frame_counter_total); else str.SetFormatted("Frame %d", frame_counter_total); GetRoot()->GetFont()->DrawString(5, 5, TBColor(255, 255, 255), str); g_renderer->EndPaint(); // If we want continous updates or got animations running, reinvalidate immediately if (continuous_repaint || TBAnimationManager::HasAnimationsRunning()) GetRoot()->Invalidate(); }
void TestSpeed(TEST test) { const char *title = ""; const int iteration_count = 300; double total_time; if (test == TEST_INFLATE) { title = "Inflate + layout speed"; double start_time = TBSystem::GetTimeMS(); for(int i = 0; i < iteration_count; i++) { TBWindow *win = new TBWindow; g_widgets_reader->LoadFile(win, "layout/main_layout.tb.txt"); win->SetText(title); win->SetSize(100 + i, 100 + i); win->Close(); } total_time = TBSystem::GetTimeMS() - start_time; } else { title = "Resizing layout speed"; TBWindow *win = new TBWindow; win->SetText(title); g_widgets_reader->LoadFile(win, "layout/main_layout.tb.txt"); double start_time = TBSystem::GetTimeMS(); for(int i = 0; i < iteration_count; i++) win->SetSize(100 + i, 100 + i); total_time = TBSystem::GetTimeMS() - start_time; win->Close(); } TBStr text; text.SetFormatted( "Total time for %d iterations:\n" "%dms\n" "Average time per iteration:\n" "%.2fms", iteration_count, (int)(total_time), (float)(total_time) / (float)iteration_count); TBMessageWindow *msg_win = new TBMessageWindow(GetParentRoot(), TBIDC("")); msg_win->Show(title, text); }
void TBHashTable::Debug() { TBTempBuffer line; line.AppendString("Hash table: "); int total_count = 0; for (uint32 i = 0; i < m_num_buckets; i++) { int count = 0; ITEM *item = m_buckets[i]; while (item) { count++; item = item->next; } TBStr tmp; tmp.SetFormatted("%d ", count); line.AppendString(tmp); total_count += count; } TBStr tmp; tmp.SetFormatted(" (total: %d of %d buckets)\n", total_count, m_num_buckets); line.AppendString(tmp); TBDebugOut(line.GetData()); }
void MainWindow::OnMessageReceived(TBMessage *msg) { if (msg->message == TBIDC("instantmsg")) { TBMessageWindow *msg_win = new TBMessageWindow(this, TBIDC("test_dialog")); msg_win->Show("Message window", "Instant message received!"); } else if (msg->message == TBIDC("busy")) { // Keep the message queue busy by posting another "busy" message. PostMessage(TBIDC("busy"), nullptr); } else if (msg->message == TBIDC("delayedmsg")) { TBStr text; text.SetFormatted("Delayed message received!\n\n" "It was received %d ms after its intended fire time.", (int)(TBSystem::GetTimeMS() - msg->GetFireTime())); TBMessageWindow *msg_win = new TBMessageWindow(this, TBIDC("")); msg_win->Show("Message window", text); } }
bool AdvancedListWindow::OnEvent(const TBWidgetEvent &ev) { TBSelectList *select = GetWidgetByIDAndType<TBSelectList>("list"); if (select && ev.type == EVENT_TYPE_CHANGED && ev.target->GetID() == TBIDC("filter")) { select->SetFilter(ev.target->GetText()); return true; } else if (select && ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("add")) { TBStr name = GetTextByID(TBIDC("add_name")); if (!name.IsEmpty()) m_source->AddItem(new AdvancedItem(name, TBIDC("boy_item"), true)); return true; } else if (select && ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("delete all")) { m_source->DeleteAllItems(); return true; } return DemoWindow::OnEvent(ev); }
void IncludeFile(int line_nr, const char *filename) { // Read the included file into a new TBNode and then // move all the children to m_target_node. TBTempBuffer include_filename; include_filename.AppendPath(m_filename); include_filename.AppendString(filename); TBNode content; if (content.ReadFile(include_filename.GetData())) { while (TBNode *content_n = content.GetFirstChild()) { content.Remove(content_n); m_target_node->Add(content_n); } } else { TBStr err; err.SetFormatted("Referenced file \"%s\" was not found!", include_filename.GetData()); OnError(line_nr, err); } }
bool TBClipboard::GetText(TBStr &text) { bool success = false; if (HasText() && OpenClipboard(NULL)) { if (HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT)) { wchar_t *pchData = (wchar_t*) GlobalLock(hClipboardData); int len = WideCharToMultiByte(CP_UTF8, 0, pchData, -1, NULL, 0, NULL, NULL); if (char *utf8 = new char[len]) { WideCharToMultiByte(CP_UTF8, 0, pchData, -1, utf8, len, NULL, NULL); success = text.Set(utf8); delete [] utf8; } GlobalUnlock(hClipboardData); } CloseClipboard(); } return success; }
bool MainWindow::OnEvent(const TBWidgetEvent &ev) { if (ev.type == EVENT_TYPE_CLICK) { if (ev.target->GetID() == TBIDC("new")) { new MainWindow(); return true; } if (ev.target->GetID() == TBIDC("msg")) { PostMessage(TBIDC("instantmsg"), nullptr); return true; } else if (ev.target->GetID() == TBIDC("busymsg")) { if (ev.target->GetValue() == 1) { // Post the first "busy" message when we check the checkbox. assert(!GetMessageByID(TBIDC("busy"))); if (!GetMessageByID(TBIDC("busy"))) { PostMessage(TBIDC("busy"), nullptr); TBMessageWindow *msg_win = new TBMessageWindow(this, TBIDC("test_dialog")); msg_win->Show("Message window", "The message loop is now constantly busy with messages to process.\n\n" "The main thread should be working hard, but input & animations should still be running smoothly."); } } else { // Remove any pending "busy" message when we uncheck the checkbox. assert(GetMessageByID(TBIDC("busy"))); if (TBMessage *busymsg = GetMessageByID(TBIDC("busy"))) DeleteMessage(busymsg); } return true; } else if (ev.target->GetID() == TBIDC("delayedmsg")) { PostMessageDelayed(TBIDC("delayedmsg"), nullptr, 2000); return true; } else if (ev.target->GetID() == TBIDC("TBWindow.close")) { // Intercept the TBWindow.close message and stop it from bubbling // to TBWindow (prevent the window from closing) TBMessageWindow *msg_win = new TBMessageWindow(this, TBIDC("confirm_close_dialog")); TBMessageWindowSettings settings(TB_MSG_YES_NO, TBIDC("Icon48")); settings.dimmer = true; settings.styling = true; msg_win->Show("Are you sure?", "Really <color #0794f8>close</color> the window?", &settings); return true; } else if (ev.target->GetID() == TBIDC("confirm_close_dialog")) { if (ev.ref_id == TBIDC("TBMessageWindow.yes")) Close(); return true; } else if (ev.target->GetID() == TBIDC("reload skin bitmaps")) { int reload_count = 10; double t1 = TBSystem::GetTimeMS(); for (int i = 0; i < reload_count; i++) g_tb_skin->ReloadBitmaps(); double t2 = TBSystem::GetTimeMS(); TBStr message; message.SetFormatted("Reloading the skin graphics %d times took %dms", reload_count, (int)(t2 - t1)); TBMessageWindow *msg_win = new TBMessageWindow(ev.target, TBID()); msg_win->Show("GFX load performance", message); return true; } else if (ev.target->GetID() == TBIDC("test context lost")) { g_renderer->InvokeContextLost(); g_renderer->InvokeContextRestored(); TBMessageWindow *msg_win = new TBMessageWindow(ev.target, TBID()); msg_win->Show("Context lost & restore", "Called InvokeContextLost and InvokeContextRestored.\n\n" "Does everything look fine?"); return true; } else if (ev.target->GetID() == TBIDC("test-layout")) { TBStr resource_file("Demo/demo01/ui_resources/"); resource_file.Append(ev.target->data.GetString()); new LayoutWindow(resource_file); return true; } else if (ev.target->GetID() == TBIDC("test-connections")) { new ConnectionWindow(); return true; } else if (ev.target->GetID() == TBIDC("test-list")) { new AdvancedListWindow(&advanced_source); return true; } else if (ev.target->GetID() == TBIDC("test-image")) { new ImageWindow(); return true; } else if (ev.target->GetID() == TBIDC("test-page")) { new PageWindow(); return true; } else if (ev.target->GetID() == TBIDC("test-animations")) { new AnimationsWindow(); return true; } else if (ev.target->GetID() == TBIDC("test-scroll-container")) { new ScrollContainerWindow(); return true; } else if (ev.target->GetID() == TBIDC("test-skin-conditions")) { (new DemoWindow())->LoadResourceFile("Demo/demo01/ui_resources/test_skin_conditions01.tb.txt"); (new DemoWindow())->LoadResourceFile("Demo/demo01/ui_resources/test_skin_conditions02.tb.txt"); return true; } else if (ev.target->GetID() == TBIDC("test-resource-edit")) { ResourceEditWindow *res_edit_win = new ResourceEditWindow(); res_edit_win->Load("Demo/demo01/ui_resources/resource_edit_test.tb.txt"); GetParent()->AddChild(res_edit_win); return true; } else if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("debug settings")) { #ifdef TB_RUNTIME_DEBUG_INFO ShowDebugInfoSettingsWindow(GetParentRoot()); #else TBMessageWindow *msg_win = new TBMessageWindow(ev.target, TBID()); msg_win->Show("Debug settings", "Debug settings is only available in builds " "compiled with TB_RUNTIME_DEBUG_INFO defined.\n\n" "Debug builds enable this by default."); #endif return true; } } return DemoWindow::OnEvent(ev); }
bool TBClipboard::GetText(TBStr &text) { return text.Set(clipboard); }
bool TBClipboard::SetText(const char *text) { return clipboard.Set(text); }
bool TBClipboard::HasText() { return !clipboard.IsEmpty(); }
void TBClipboard::Empty() { clipboard.Clear(); }
namespace tb { #ifdef TB_RUNTIME_DEBUG_INFO void TBDebugOut(const char *str) { // TODO: //batb->log << str; //printf("%s", str); } #endif // TB_RUNTIME_DEBUG_INFO //////////////////////////////////////////////////////////////////////////////// // TBSystem // this function is called by TBMessageHandler when the time for the // next message to be delivered got changed. however, we do not use // such wake-up system in our game application, instead a continuous // loop, so we do not care about this notification. void TBSystem::RescheduleTimer(double fire_time) { } double TBSystem::GetTimeMS() { return batb::gui::tbsystem_time; } // only for touch platforms int TBSystem::GetLongClickDelayMS() { return 500; } // only for touch platforms int TBSystem::GetPanThreshold() { // FIXME! // (probably not necessary, only for touch platforms...) return 5 * GetDPI() / 96; } // only for touch platforms int TBSystem::GetPixelsPerLine() { return 40 * GetDPI() / 96; } // we currently use this during our GUI setup for fonts // FIXME: make our TB implementation independent of this, // so the view across different screens is mostly consistent. // we are also using MSAA typically, anyway int TBSystem::GetDPI() { // FIX: Implement! return 96; } //////////////////////////////////////////////////////////////////////////////// // clipboard (empty) // static TBStr clipboard; ///< Obviosly not a full implementation since it ignores the OS :) void TBClipboard::Empty() { clipboard.Clear(); } bool TBClipboard::HasText() { return !clipboard.IsEmpty(); } bool TBClipboard::SetText(const char *text) { return clipboard.Set(text); } bool TBClipboard::GetText(TBStr &text) { return text.Set(clipboard); } } // namespace tb