Docs update and news section, ok button, versioing, about and project properties (wip)

This commit is contained in:
Anthony 2023-12-30 22:23:08 +01:00
parent caa0e73935
commit 628a72adf7
16 changed files with 1728 additions and 847 deletions

2
.gitignore vendored
View file

@ -63,3 +63,5 @@ story-editor-v2/src/.vscode/
build-story-editor-v2-Desktop-Debug/ build-story-editor-v2-Desktop-Debug/
build-story-editor-Desktop-Debug/ build-story-editor-Desktop-Debug/
docs/.vitepress/cache/

View file

@ -4,7 +4,14 @@ import { defineConfig } from 'vitepress'
export default defineConfig({ export default defineConfig({
title: "Open Story Teller", title: "Open Story Teller",
description: "Make your own device that tells stories", description: "Make your own device that tells stories",
lastUpdated: true,
cleanUrls: true,
themeConfig: { themeConfig: {
logo: { src: '/logo_hat_only.png', width: 29, height: 24 },
// https://vitepress.dev/reference/default-theme-config // https://vitepress.dev/reference/default-theme-config
nav: [ nav: [
{ text: 'Home', link: '/' }, { text: 'Home', link: '/' },
@ -55,6 +62,11 @@ export default defineConfig({
} }
], ],
footer: {
message: 'Source code under the MIT License, art under the CC0 License.',
copyright: 'Copyright © 2020-present Anthony Rabine'
},
socialLinks: [ socialLinks: [
{ icon: 'github', link: 'https://github.com/arabine/open-story-teller' } { icon: 'github', link: 'https://github.com/arabine/open-story-teller' }
] ]

View file

@ -0,0 +1,44 @@
<script setup>
import DefaultTheme from 'vitepress/theme'
import { onMounted } from 'vue'
import { ref } from 'vue'
const lastNews = ref([]);
onMounted(() => {
fetch('https://piaille.fr/api/v1/timelines/tag/openstoryteller?limit=5').then(
resp => resp.json() // this returns a promise
).then(messages => {
// lastNews = ref([]);
for (const m of messages) {
if (m.account.username === "arabine") {
// console.log(m)
console.log(m.content);
lastNews.value.push({ content: m.content, date: new Date(m.created_at).toDateString() })
}
}
}).catch(ex => {
console.error(ex);
})
});
</script>
<template>
<div class="vp-doc custom-block">
<h1>Latest news</h1>
<div v-for="item in lastNews">
<h3>{{item.date}}</h3>
<p v-html="item.content"></p>
</div>
</div>
</template>
<style scoped>
</style>

View file

@ -3,10 +3,13 @@ import { h } from 'vue'
import Theme from 'vitepress/theme' import Theme from 'vitepress/theme'
import './style.css' import './style.css'
import HomeContent from './HomeContent.vue'
export default { export default {
...Theme, ...Theme,
Layout: () => { Layout: () => {
return h(Theme.Layout, null, { return h(Theme.Layout, null, {
'home-features-after': () => h(HomeContent)
// https://vitepress.dev/guide/extending-default-theme#layout-slots // https://vitepress.dev/guide/extending-default-theme#layout-slots
}) })
}, },

View file

@ -6,9 +6,6 @@ hero:
name: "Open Story Teller" name: "Open Story Teller"
text: "Hardware and software that tell stories" text: "Hardware and software that tell stories"
tagline: Make your own, its free sofware tagline: Make your own, its free sofware
image:
src: /logo.png
alt: logo
actions: actions:
- theme: brand - theme: brand
text: Getting started text: Getting started
@ -16,6 +13,9 @@ hero:
- theme: alt - theme: alt
text: Assembly guidelines text: Assembly guidelines
link: /guide-intro link: /guide-intro
image:
src: /logo.png
alt: logo
features: features:
- title: Easy to repair - title: Easy to repair

2369
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
{ {
"type": "module",
"devDependencies": { "devDependencies": {
"vitepress": "^1.0.0-alpha.73" "vitepress": "^1.0.0-rc.33"
}, },
"scripts": { "scripts": {
"docs:dev": "vitepress dev", "docs:dev": "vitepress dev",
@ -8,6 +9,6 @@
"docs:preview": "vitepress preview" "docs:preview": "vitepress preview"
}, },
"dependencies": { "dependencies": {
"vue": "^3.2.47" "vue": "^3.3.13"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -126,7 +126,7 @@ bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, Res
nlohmann::json j = nlohmann::json::parse(f); nlohmann::json j = nlohmann::json::parse(f);
m_nodes.clear(); // m_nodes.clear();
manager.Clear(); manager.Clear();
if (j.contains("project")) if (j.contains("project"))
@ -256,7 +256,7 @@ void StoryProject::Save(const nlohmann::json &model, ResourceManager &manager)
std::ofstream o(m_story_file_path); std::ofstream o(m_story_file_path);
o << std::setw(4) << j << std::endl; o << std::setw(4) << j << std::endl;
} }
/*
void StoryProject::CreateTree() void StoryProject::CreateTree()
{ {
// Algorithm: level order traversal of N-ary tree // Algorithm: level order traversal of N-ary tree
@ -289,6 +289,15 @@ void StoryProject::CreateTree()
nlist.pop(); nlist.pop();
} }
} }
*/
void StoryProject::Clear()
{
m_uuid = "";
m_working_dir = "";
m_story_file_path = "";
m_initialized = false;
}
void StoryProject::EraseString(std::string &theString, const std::string &toErase) void StoryProject::EraseString(std::string &theString, const std::string &toErase)
{ {

View file

@ -6,13 +6,8 @@
#include <filesystem> #include <filesystem>
#include "json.hpp" #include "json.hpp"
#include <memory>
#include <random>
#include "json.hpp" #include "json.hpp"
#include "resource_manager.h" #include "resource_manager.h"
#include "audio_player.h"
// FIXME : Structure très Lunii style, à utiliser pour la conversion peut-être ... // FIXME : Structure très Lunii style, à utiliser pour la conversion peut-être ...
@ -48,30 +43,26 @@ struct StoryNode
struct StoryProject struct StoryProject
{ {
public:
enum ImageFormat { IMG_FORMAT_BMP_4BITS, IMG_FORMAT_QOIF, IMG_FORMAT_COUNT }; enum ImageFormat { IMG_FORMAT_BMP_4BITS, IMG_FORMAT_QOIF, IMG_FORMAT_COUNT };
enum SoundFormat { SND_FORMAT_WAV, SND_FORMAT_QOAF, SND_FORMAT_COUNT }; enum SoundFormat { SND_FORMAT_WAV, SND_FORMAT_QOAF, SND_FORMAT_COUNT };
StoryProject(); StoryProject();
~StoryProject(); ~StoryProject();
/*
std::vector<StoryNode> m_nodes; std::vector<StoryNode> m_nodes;
std::string m_type; std::string m_type;
std::string m_code; std::string m_code;
StoryNode *m_tree; StoryNode *m_tree;
*/
bool Load(const std::string &file_path, nlohmann::json &model, ResourceManager &manager); bool Load(const std::string &file_path, nlohmann::json &model, ResourceManager &manager);
void Save(const nlohmann::json &model, ResourceManager &manager); void Save(const nlohmann::json &model, ResourceManager &manager);
void CreateTree(); void CreateTree();
void Clear() void Clear();
{
m_uuid = "";
m_working_dir = "";
m_story_file_path = "";
m_initialized = false;
}
void SetImageFormat(ImageFormat format); void SetImageFormat(ImageFormat format);
void SetSoundFormat(SoundFormat format); void SetSoundFormat(SoundFormat format);
@ -100,9 +91,9 @@ struct StoryProject
std::string GetTitleImage() const { return m_titleImage; } std::string GetTitleImage() const { return m_titleImage; }
std::string GetTitleSound() const { return m_titleSound; } std::string GetTitleSound() const { return m_titleSound; }
public:
// Initialize with an existing project // Initialize with an existing project
void Initialize(const std::string &file_path); void Initialize(const std::string &file_path);
const bool IsInitialized() const { return m_initialized; }
void New(const std::string &uuid, const std::string &file_path); void New(const std::string &uuid, const std::string &file_path);
static void EraseString(std::string &theString, const std::string &toErase); static void EraseString(std::string &theString, const std::string &toErase);

View file

@ -189,7 +189,7 @@ target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
../software/chip32/ ../software/chip32/
) )
add_definitions(-DIMGUI_USE_WCHAR32) add_definitions(-DIMGUI_USE_WCHAR32 -DVERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DVERSION_MINOR=${PROJECT_VERSION_MINOR} -DVERSION_PATCH=${PROJECT_VERSION_PATCH})
add_link_options(-static-libgcc -static-libstdc++) add_link_options(-static-libgcc -static-libstdc++)
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0) target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)

View file

@ -50,10 +50,9 @@ void EmulatorWindow::Draw()
ImGui::PushFont(ImGui::GetFont()); ImGui::PushFont(ImGui::GetFont());
if (ImGui::Button(ICON_MDI_CHECK_CIRCLE_OUTLINE, ImVec2(50, 50)))
if (ImGui::Button(ICON_MDI_PLAY_CIRCLE_OUTLINE, ImVec2(50, 50)))
{ {
m_story.Play(); m_story.Ok();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_MDI_STOP_CIRCLE_OUTLINE, ImVec2(50, 50))) if (ImGui::Button(ICON_MDI_STOP_CIRCLE_OUTLINE, ImVec2(50, 50)))
@ -80,6 +79,12 @@ void EmulatorWindow::Draw()
{ {
m_story.Build(); m_story.Build();
} }
ImGui::SameLine();
if (ImGui::Button("Build & Play"))
{
m_story.Play();
}
ImGui::SameLine(); ImGui::SameLine();
WindowBase::EndDraw(); WindowBase::EndDraw();

View file

@ -32,6 +32,7 @@ public:
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(unsigned long nodeId) = 0; virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(unsigned long nodeId) = 0;
virtual std::string GetNodeEntryLabel(unsigned long nodeId) = 0; virtual std::string GetNodeEntryLabel(unsigned long nodeId) = 0;
virtual void Play() = 0; virtual void Play() = 0;
virtual void Ok() = 0;
virtual void Pause() = 0; virtual void Pause() = 0;
virtual void Next() = 0; virtual void Next() = 0;
virtual void Previous() = 0; virtual void Previous() = 0;

View file

@ -1,7 +1,7 @@
#include "main_window.h" #include "main_window.h"
#include <filesystem> #include <filesystem>
#include <random> #include <random>
#include <SDL.h>
#include "platform_folders.h" #include "platform_folders.h"
#include "uuid.h" #include "uuid.h"
#include "media_converter.h" #include "media_converter.h"
@ -19,6 +19,8 @@
#include "IconsMaterialDesignIcons.h" #include "IconsMaterialDesignIcons.h"
#include "ImGuiFileDialog.h" #include "ImGuiFileDialog.h"
static std::string gVersion;
MainWindow::MainWindow() MainWindow::MainWindow()
: m_emulatorWindow(*this) : m_emulatorWindow(*this)
, m_resourcesWindow(*this) , m_resourcesWindow(*this)
@ -26,6 +28,8 @@ MainWindow::MainWindow()
, m_player(*this) , m_player(*this)
{ {
gVersion = std::to_string(VERSION_MAJOR) + '.' + std::to_string(VERSION_MINOR) + '.' + std::to_string(VERSION_PATCH);
// VM Initialize // VM Initialize
m_chip32_ctx.stack_size = 512; m_chip32_ctx.stack_size = 512;
@ -78,6 +82,11 @@ void MainWindow::Play()
} }
} }
void MainWindow::Ok()
{
m_eventQueue.push({VmEventType::EvOkButton});
}
void MainWindow::Pause() void MainWindow::Pause()
{ {
@ -280,6 +289,9 @@ void MainWindow::DrawMainMenuBar()
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (!m_story.IsInitialized())
ImGui::BeginDisabled();
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Save project")) if (ImGui::MenuItem("Save project"))
{ {
@ -296,6 +308,9 @@ void MainWindow::DrawMainMenuBar()
showParameters = true; showParameters = true;
} }
if (!m_story.IsInitialized())
ImGui::EndDisabled();
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -318,7 +333,10 @@ void MainWindow::DrawMainMenuBar()
if (showParameters) if (showParameters)
{ {
ImGui::OpenPopup("Options"); if (m_story.IsInitialized())
{
ImGui::OpenPopup("ProjectPropertiesPopup");
}
} }
if (showNewProject) if (showNewProject)
@ -341,18 +359,19 @@ void MainWindow::DrawMainMenuBar()
if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::Text("Story Editor V2"); ImGui::Text("Story Editor - v%s", gVersion.c_str());
ImGui::Text("http://www.openstoryteller.org");
ImGui::Separator(); ImGui::Separator();
ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Platform"); ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Platform");
ImGui::Text("http://www.openstoryteller.org");
// ImGui::Text("%s", SDL_GetPlatform()); ImGui::Text("%s", SDL_GetPlatform());
// ImGui::Text("CPU cores: %d", SDL_GetCPUCount()); ImGui::Text("CPU cores: %d", SDL_GetCPUCount());
// ImGui::Text("RAM: %.2f GB", SDL_GetSystemRAM() / 1024.0f); ImGui::Text("RAM: %.2f GB", SDL_GetSystemRAM() / 1024.0f);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::Separator(); ImGui::Separator();
ImGui::SameLine(300); ImGui::SameLine(300);
if (ImGui::Button("Close", ImVec2(120, 40))) if (ImGui::Button("Close", ImVec2(100, 35)))
{ {
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -441,33 +460,38 @@ void MainWindow::NewProjectPopup()
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName(); std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string projdir = ImGuiFileDialog::Instance()->GetCurrentPath(); std::string projdir = ImGuiFileDialog::Instance()->GetCurrentPath();
std::string uuid = UUID().String(); if (!std::filesystem::is_directory(projdir))
auto p = std::filesystem::path(projdir) / uuid / std::filesystem::path("project.json"); {
m_story.Initialize(p.generic_string());
m_story.SetDisplayFormat(320, 240); std::string uuid = UUID().String();
m_story.SetImageFormat(StoryProject::IMG_FORMAT_QOIF); auto p = std::filesystem::path(projdir) / uuid / std::filesystem::path("project.json");
m_story.SetSoundFormat(StoryProject::SND_FORMAT_WAV); m_story.Initialize(p.generic_string());
m_story.SetName("New project");
m_story.SetUuid(uuid);
SaveProject(); m_story.SetDisplayFormat(320, 240);
OpenProject(p.generic_string()); m_story.SetImageFormat(StoryProject::IMG_FORMAT_QOIF);
m_story.SetSoundFormat(StoryProject::SND_FORMAT_WAV);
m_story.SetName("New project");
m_story.SetUuid(uuid);
SaveProject();
OpenProject(p.generic_string());
}
} }
// close // close
ImGuiFileDialog::Instance()->Close(); ImGuiFileDialog::Instance()->Close();
} }
}
/* void MainWindow::ProjectPropertiesPopup()
{
static std::string projdir; static std::string projdir;
// Always center this window when appearing // Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter(); ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("NewProjectPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize)) if (ImGui::BeginPopupModal("ProjectPropertiesPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::Text("New project parameters (directory must be empty)"); ImGui::Text("New project parameters (directory must be empty)");
ImGui::Separator(); ImGui::Separator();
@ -615,8 +639,6 @@ void MainWindow::NewProjectPopup()
if (valid) if (valid)
{ {
auto p = std::filesystem::path(projdir) / std::filesystem::path("project.json");
m_story.Initialize(p.generic_string());
if (display_item_current_idx == 0) if (display_item_current_idx == 0)
{ {
@ -630,10 +652,8 @@ void MainWindow::NewProjectPopup()
m_story.SetImageFormat(GetImageFormat(image_item_current_idx)); m_story.SetImageFormat(GetImageFormat(image_item_current_idx));
m_story.SetSoundFormat(GetSoundFormat(sound_item_current_idx)); m_story.SetSoundFormat(GetSoundFormat(sound_item_current_idx));
m_story.SetName(project_name); m_story.SetName(project_name);
m_story.SetUuid(UUID().String());
SaveProject(); SaveProject();
OpenProject(p.generic_string());
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -650,7 +670,6 @@ void MainWindow::NewProjectPopup()
{ {
projdir = ""; projdir = "";
} }
*/
} }
void MainWindow::SaveProject() void MainWindow::SaveProject()
@ -701,7 +720,8 @@ void MainWindow::OpenProject(const std::string &filename)
void MainWindow::RefreshProjectInformation() void MainWindow::RefreshProjectInformation()
{ {
m_gui.SetWindowTitle("Story Editor - " + m_story.GetProjectFilePath()); std::string fullText = "Story Editor " + gVersion + " - " + m_story.GetProjectFilePath();
m_gui.SetWindowTitle(fullText);
} }
@ -759,6 +779,7 @@ void MainWindow::Loop()
NewProjectPopup(); NewProjectPopup();
OpenProjectDialog(); OpenProjectDialog();
ProjectPropertiesPopup();
if (aboutToClose) if (aboutToClose)
{ {

View file

@ -18,6 +18,7 @@
#include "story_project.h" #include "story_project.h"
#include "i_story_manager.h" #include "i_story_manager.h"
#include "thread_safe_queue.h" #include "thread_safe_queue.h"
#include "audio_player.h"
struct DebugContext struct DebugContext
{ {
@ -145,6 +146,7 @@ private:
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(unsigned long nodeId) override; virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(unsigned long nodeId) override;
virtual std::string GetNodeEntryLabel(unsigned long nodeId) override; virtual std::string GetNodeEntryLabel(unsigned long nodeId) override;
virtual void Play() override; virtual void Play() override;
virtual void Ok() override;
virtual void Pause() override; virtual void Pause() override;
virtual void Next() override; virtual void Next() override;
virtual void Previous() override; virtual void Previous() override;
@ -174,6 +176,7 @@ private:
void ProcessStory(); void ProcessStory();
void StepInstruction(); void StepInstruction();
void RefreshProjectInformation(); void RefreshProjectInformation();
void ProjectPropertiesPopup();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View file

@ -1,5 +1,4 @@
#include "properties_window.h" #include "properties_window.h"
#include "gui.h"
PropertiesWindow::PropertiesWindow() PropertiesWindow::PropertiesWindow()
: WindowBase("Properties") : WindowBase("Properties")
@ -16,15 +15,10 @@ void PropertiesWindow::Initialize() {
void PropertiesWindow::Draw() void PropertiesWindow::Draw()
{ {
// if (!IsVisible())
// {
// return;
// }
WindowBase::BeginDraw(); WindowBase::BeginDraw();
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver); ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
ImGui::SeparatorText("Selected node"); ImGui::SeparatorText("Selected node");