// ----------------------------------------------------------------------------- // Sets all colours in the current configuration to default // ----------------------------------------------------------------------------- void ColourConfiguration::loadDefaults() { // Read default colours auto pres = App::archiveManager().programResourceArchive(); auto entry_default_cc = pres->entryAtPath("config/colours/default.txt"); if (entry_default_cc) readConfiguration(entry_default_cc->data()); }
// ----------------------------------------------------------------------------- // SBrush class constructor // ----------------------------------------------------------------------------- SBrush::SBrush(const wxString& name) : name_{ name }, icon_{ name.AfterFirst('_') } { auto res = App::archiveManager().programResourceArchive(); if (res == nullptr) return; auto file = res->entryAtPath(fmt::format("icons/general/{}.png", icon_.ToStdString())); if (file == nullptr || file->size() == 0) { Log::error(2, wxString::Format("error, no file at icons/general/%s.png", icon_)); return; } image_ = std::make_unique<SImage>(); if (!image_->open(file->data(), 0, "png")) { Log::error(2, wxString::Format("couldn't load image data for icons/general/%s.png", icon_)); return; } image_->convertAlphaMap(SImage::AlphaSource::Alpha); center_.x = image_->width() >> 1; center_.y = image_->height() >> 1; }
// ---------------------------------------------------------------------------- // ParseTreeNode::parsePreprocessor // // Parses a preprocessor directive at [tz]'s current token // ---------------------------------------------------------------------------- bool ParseTreeNode::parsePreprocessor(Tokenizer& tz) { //Log::debug(S_FMT("Preprocessor %s", CHR(tz.current().text))); // #define if (tz.current() == "#define") parser_->define(tz.next().text); // #if(n)def else if (tz.current() == "#ifdef" || tz.current() == "#ifndef") { // Continue if condition succeeds bool test = true; if (tz.current() == "#ifndef") test = false; string define = tz.next().text; if (parser_->defined(define) == test) return true; // Failed condition, skip section int skip = 0; while (true) { auto& token = tz.next(); if (token == "#endif") skip--; else if (token == "#ifdef") skip++; else if (token == "#ifndef") skip++; // TODO: #else if (skip < 0) break; } } // #include else if (tz.current() == "#include") { // Include entry at the given path if we have an archive dir set if (archive_dir_) { // Get entry to include auto inc_path = tz.next().text; auto archive = archive_dir_->archive(); auto inc_entry = archive->entryAtPath(archive_dir_->getPath() + inc_path); if (!inc_entry) // Try absolute path inc_entry = archive->entryAtPath(inc_path); //Log::debug(S_FMT("Include %s", CHR(inc_path))); if (inc_entry) { // Save the current dir and set it to the included entry's dir auto orig_dir = archive_dir_; archive_dir_ = inc_entry->getParentDir(); // Parse text in the entry Tokenizer inc_tz; inc_tz.openMem(inc_entry->getMCData(), inc_entry->getName()); bool ok = parse(inc_tz); // Reset dir and abort if parsing failed archive_dir_ = orig_dir; if (!ok) return false; } else logError(tz, S_FMT("Include entry %s not found", CHR(inc_path))); } else tz.adv(); // Skip include path } // #endif (ignore) else if (tz.current() == "#endif") return true; // TODO: #else // Unrecognised else logError(tz, S_FMT("Unrecognised preprocessor directive \"%s\"", CHR(tz.current().text))); return true; }
/* DirArchive::updateChangedEntries * Updates entries/directories based on [changes] list *******************************************************************/ void DirArchive::updateChangedEntries(vector<dir_entry_change_t>& changes) { bool was_modified = isModified(); for (unsigned a = 0; a < changes.size(); a++) { ignored_file_changes.erase(changes[a].file_path); // Modified Entries if (changes[a].action == dir_entry_change_t::UPDATED) { ArchiveEntry* entry = entryAtPath(changes[a].entry_path); entry->importFile(changes[a].file_path); EntryType::detectEntryType(entry); file_modification_times[entry] = wxFileModificationTime(changes[a].file_path); } // Deleted Entries else if (changes[a].action == dir_entry_change_t::DELETED_FILE) removeEntry(entryAtPath(changes[a].entry_path)); // Deleted Directories else if (changes[a].action == dir_entry_change_t::DELETED_DIR) removeDir(changes[a].entry_path); // New Directory else if (changes[a].action == dir_entry_change_t::ADDED_DIR) { string name = changes[a].file_path; name.Remove(0, filename.Length()); if (name.StartsWith(separator)) name.Remove(0, 1); name.Replace("\\", "/"); ArchiveTreeNode* ndir = createDir(name); ndir->getDirEntry()->setState(0); ndir->getDirEntry()->exProp("filePath") = changes[a].file_path; } // New Entry else if (changes[a].action == dir_entry_change_t::ADDED_FILE) { string name = changes[a].file_path; name.Remove(0, filename.Length()); if (name.StartsWith(separator)) name.Remove(0, 1); name.Replace("\\", "/"); // Create entry wxFileName fn(name); ArchiveEntry* new_entry = new ArchiveEntry(fn.GetFullName()); // Setup entry info new_entry->setLoaded(false); new_entry->exProp("filePath") = changes[a].file_path; // Add entry and directory to directory tree ArchiveTreeNode* ndir = createDir(fn.GetPath(true, wxPATH_UNIX)); ndir->addEntry(new_entry); // Read entry data new_entry->importFile(changes[a].file_path); new_entry->setLoaded(true); time_t modtime = wxFileModificationTime(changes[a].file_path); file_modification_times[new_entry] = modtime; // Detect entry type EntryType::detectEntryType(new_entry); // Unload data if needed if (!archive_load_data) new_entry->unloadData(); // Set entry not modified new_entry->setState(0); } } // Preserve old modified state setModified(was_modified); }
// ----------------------------------------------------------------------------- // Initialises the start page // ----------------------------------------------------------------------------- void SStartPage::init() { // wxWebView #ifdef USE_WEBVIEW_STARTPAGE html_startpage_ = wxWebView::New( this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxWebViewBackendDefault, wxBORDER_NONE); html_startpage_->SetZoomType(App::platform() == App::MacOS ? wxWEBVIEW_ZOOM_TYPE_TEXT : wxWEBVIEW_ZOOM_TYPE_LAYOUT); // wxHtmlWindow #else html_startpage_ = new wxHtmlWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER, "startpage"); #endif // Add to sizer GetSizer()->Add(html_startpage_, 1, wxEXPAND); // Bind events #ifdef USE_WEBVIEW_STARTPAGE html_startpage_->Bind(wxEVT_WEBVIEW_NAVIGATING, &SStartPage::onHTMLLinkClicked, this); html_startpage_->Bind( wxEVT_WEBVIEW_ERROR, [&](wxWebViewEvent& e) { Log::error(S_FMT("wxWebView Error: %s", CHR(e.GetString()))); }); if (App::platform() == App::Platform::Windows) { html_startpage_->Bind(wxEVT_WEBVIEW_LOADED, [&](wxWebViewEvent& e) { html_startpage_->Reload(); }); } Bind(wxEVT_THREAD_WEBGET_COMPLETED, [&](wxThreadEvent& e) { latest_news_ = e.GetString(); latest_news_.Trim(); if (latest_news_ == "connect_failed" || latest_news_.empty()) latest_news_ = "<center>Unable to load latest SLADE news</center>"; load(false); }); #else html_startpage_->Bind(wxEVT_COMMAND_HTML_LINK_CLICKED, &SStartPage::onHTMLLinkClicked, this); #endif // Get data used to build the page auto res_archive = App::archiveManager().programResourceArchive(); if (res_archive) { entry_base_html_ = res_archive->entryAtPath(App::useWebView() ? "html/startpage.htm" : "html/startpage_basic.htm"); entry_css_ = res_archive->entryAtPath(web_dark_theme ? "html/theme-dark.css" : "html/theme-light.css"); entry_export_.push_back(res_archive->entryAtPath("html/base.css")); entry_export_.push_back(res_archive->entryAtPath("fonts/FiraSans-Regular.woff")); entry_export_.push_back(res_archive->entryAtPath("fonts/FiraSans-Italic.woff")); entry_export_.push_back(res_archive->entryAtPath("fonts/FiraSans-Medium.woff")); entry_export_.push_back(res_archive->entryAtPath("fonts/FiraSans-Bold.woff")); entry_export_.push_back(res_archive->entryAtPath("fonts/FiraSans-Heavy.woff")); entry_export_.push_back(res_archive->entryAtPath("logo_icon.png")); entry_export_.push_back(res_archive->entryAtPath("icons/entry_list/Rounded/archive.png")); entry_export_.push_back(res_archive->entryAtPath("icons/entry_list/Rounded/wad.png")); entry_export_.push_back(res_archive->entryAtPath("icons/entry_list/Rounded/zip.png")); entry_export_.push_back(res_archive->entryAtPath("icons/entry_list/Rounded/folder.png")); entry_export_.push_back(res_archive->entryAtPath("icons/general/open.png")); entry_export_.push_back(res_archive->entryAtPath("icons/general/newarchive.png")); entry_export_.push_back(res_archive->entryAtPath("icons/general/newzip.png")); entry_export_.push_back(res_archive->entryAtPath("icons/general/mapeditor.png")); entry_export_.push_back(res_archive->entryAtPath("icons/general/wiki.png")); // Load tips auto entry_tips = res_archive->entryAtPath("tips.txt"); if (entry_tips) { Tokenizer tz; tz.openMem((const char*)entry_tips->getData(), entry_tips->getSize(), entry_tips->getName()); while (!tz.atEnd() && tz.peekToken() != "") tips_.push_back(tz.getToken()); } } }