// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved // Please see LICENSE.md in repository root for license information // https://github.com/AtomicGameEngine/AtomicGameEngine #include #include "rapidjson/prettywriter.h" #include "rapidjson/filestream.h" using namespace rapidjson; #include "AtomicEditor.h" #include #include #include #include #include #include #include #include "License/AELicenseSystem.h" #include "../Project/ProjectUtils.h" #include "../AEPreferences.h" #include "../AEEditor.h" #include "UI/Modal/UIModalOps.h" #include "UIWelcomeFrame.h" using namespace tb; namespace AtomicEditor { WelcomeFrame::WelcomeFrame(Context* context) : AEWidget(context), currentExampleLayout_(0), exampleCount_(0) { FileSystem* fileSystem = GetSubsystem(); #ifdef ATOMIC_PLATFORM_OSX exampleSourceDir_ = fileSystem->GetAppBundleResourceFolder(); #else exampleSourceDir_ = fileSystem->GetProgramDir(); #endif exampleInfoDir_ = exampleSourceDir_ + "ExampleInfo"; exampleSourceDir_ += "Examples"; UI* tbui = GetSubsystem(); tbui->LoadResourceFile(delegate_, "AtomicEditor/editor/ui/welcomeframe.tb.txt"); delegate_->SetGravity(WIDGET_GRAVITY_ALL); UpdateRecentProjects(); FillExamples(); } WelcomeFrame::~WelcomeFrame() { } void WelcomeFrame::AddExample(const String& name, const String& desc, const String& screenshot, const String& folder, const String& module) { TBLayout* exlayout = delegate_->GetWidgetByIDAndType(TBIDC("examples_layout")); assert(exlayout); if (!currentExampleLayout_) { currentExampleLayout_ = new TBLayout(); currentExampleLayout_->SetSpacing(8); exlayout->AddChild(currentExampleLayout_); } // 200x150 TBLayout* example = new TBLayout(); example->SetSkinBg(TBIDC("StarCondition")); example->SetAxis(AXIS_Y); example->SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY); example->SetLayoutSize(LAYOUT_SIZE_AVAILABLE); // IMAGE BUTTON TBID id = TBIDC(name.CString()); TBButton* button = new TBButton(); button->SetSkinBg("StarButton"); button->SetID(id); TBImageWidget* image = new TBImageWidget(); image->SetImage((exampleInfoDir_ + "/" + screenshot).CString()); image->SetSkinBg(TBIDC("ImageFrame")); TBRect rect(0, 0, image->GetImageWidth()/2, image->GetImageHeight()/2); image->SetRect(rect); // NAME FIELD TBTextField* nameField = new TBTextField(); nameField->SetSkinBg(TBIDC("ImageCaption")); nameField->SetText(name.CString()); TBRect nameRect(0, image->GetImageHeight()/2 - 16, image->GetImageWidth()/2, 16); nameField->SetRect(nameRect); nameField->SetGravity(WIDGET_GRAVITY_BOTTOM); image->AddChild(nameField); button->AddChild(image); LayoutParams lp; lp.min_w = image->GetImageWidth()/2; lp.min_h = image->GetImageHeight()/2; button->SetLayoutParams(lp); button->SetGravity(WIDGET_GRAVITY_LEFT); example->AddChild(button); // DESC TEXT TBEditField* descField = new TBEditField(); descField->SetStyling(true); descField->SetMultiline(true); descField->SetReadOnly(true); descField->SetWrapping(true); String styleDesc = "" + desc + ""; descField->SetText(styleDesc.CString()); descField->SetAdaptToContentSize(true); lp.min_h /= 2; lp.max_h = lp.min_h; lp.max_w = lp.min_w; descField->SetLayoutParams(lp); example->AddChild(descField); currentExampleLayout_->AddChild(example); exampleCount_++; // three across, todo, be smarter about this if (! (exampleCount_ % 3)) { currentExampleLayout_ = NULL; } ExampleInfo info; info.name = name; info.folder = folder; info.id = id; info.module = module; info.screenshot = exampleInfoDir_ + "/" + screenshot; exampleInfo_.Push(info); } void WelcomeFrame::FillExamples() { rapidjson::Document document; String exampleJsonFile = exampleInfoDir_ + "/Examples.json"; File jsonFile(context_, exampleJsonFile); if (!jsonFile.IsOpen()) return; String json; jsonFile.ReadText(json); if (!json.Length()) return; if (document.Parse<0>(json.CString()).HasParseError()) { LOGERRORF("Could not parse JSON data from %s", exampleJsonFile.CString()); return; } const Value::Member* examples = document.FindMember("Examples");; if (!examples || !examples->value.IsArray()) return; for (Value::ConstValueIterator itr = examples->value.Begin(); itr != examples->value.End(); itr++) { if (!(*itr).IsObject()) continue; const Value::Member* name = (*itr).FindMember("name"); const Value::Member* desc = (*itr).FindMember("desc"); const Value::Member* screenshot = (*itr).FindMember("screenshot"); const Value::Member* folder = (*itr).FindMember("folder"); const Value::Member* module = (*itr).FindMember("module"); if (!name || !desc || !screenshot || !folder || !module) continue; if (!name->value.IsString() || !desc->value.IsString() || !screenshot->value.IsString() || !folder->value.IsString() || !module->value.IsString()) { continue; } AddExample(name->value.GetString(), desc->value.GetString(), screenshot->value.GetString(), folder->value.GetString(), module->value.GetString()); } } void WelcomeFrame::UpdateRecentProjects() { TBSelectList* select = delegate_->GetWidgetByIDAndType(TBIDC("recentprojects")); if (!select) return; TBGenericStringItemSource* source = select->GetDefaultSource(); source->DeleteAllItems(); const Vector& recent = GetSubsystem()->GetRecentProjects(); for (unsigned i = 0; i < recent.Size(); i++) { source->AddItem(new TBGenericStringItem(recent[i].CString())); } } bool WelcomeFrame::OnEvent(const TBWidgetEvent &ev) { UIModalOps* ops = GetSubsystem(); FileSystem* fileSystem = GetSubsystem(); if (ev.type == EVENT_TYPE_CLICK) { if (ev.target) { if (ev.target->GetID() == TBIDC("getting_started")) { fileSystem->SystemOpen("http://atomicgameengine.com/videos"); } else if (ev.target->GetID() == TBIDC("forum")) { fileSystem->SystemOpen("http://atomicgameengine.com/forum"); } else if (ev.target->GetID() == TBIDC("atomic_github")) { fileSystem->SystemOpen("https://github.com/AtomicGameEngine/AtomicGameEngine"); } else if (ev.target->GetID() == TBIDC("examples_github")) { fileSystem->SystemOpen("https://github.com/AtomicGameEngine/AtomicExamples"); } else if (ev.target->GetID() == TBIDC("open project")) { GetSubsystem()->OpenProjectFileDialog(); return true; } else if (ev.target->GetID() == TBIDC("new project")) { GetSubsystem()->ShowNewProject(); return true; } else if (ev.target->GetID() == TBID("recentprojects")) { // we clicked the recent projects list TBSelectList* list = (TBSelectList*) ev.target; int value = list->GetValue(); if (value >= 0) { TBGenericStringItemSource* source = list->GetDefaultSource(); if (source->GetNumItems()) { String projectpath = String(source->GetItemString(value)); GetSubsystem()->LoadProject(projectpath); } } return true; } else { for (unsigned i = 0; i < exampleInfo_.Size(); i++) { List::Iterator itr = exampleInfo_.Begin(); while (itr != exampleInfo_.End()) { if (ev.target->GetID() == (*itr).id) { String exampleSourceDir = exampleSourceDir_ + "/" + (*itr).folder; // BEGIN LICENSE MANAGEMENT LicenseSystem* licenseSystem = GetSubsystem(); if (licenseSystem->IsStandardLicense()) { if ((*itr).module == "3D") { ops->ShowInfoModule3D(exampleSourceDir, (*itr).screenshot); return true; } } // END LICENSE MANAGEMENT ops->ShowCreateProject(exampleSourceDir, (*itr).screenshot); return true; } itr++; } } } } } return false; } }