mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 13:21:13 +00:00
Added a new "syncing" banner to the MainLayout. This also exposed some
bugs related to relative positioning in Window.
This commit is contained in:
parent
8b1cac7f9b
commit
5d2a3bcc2e
@ -41,10 +41,15 @@
|
||||
namespace musik { namespace core {
|
||||
class IIndexer {
|
||||
public:
|
||||
sigslot::signal0<> SynchronizeStart;
|
||||
sigslot::signal0<> SynchronizeEnd;
|
||||
sigslot::signal0<> Started;
|
||||
sigslot::signal1<int> Finished;
|
||||
sigslot::signal0<> PathsUpdated;
|
||||
sigslot::signal0<> TrackRefreshed;
|
||||
sigslot::signal1<int> Progress;
|
||||
|
||||
enum State {
|
||||
StateIdle,
|
||||
StateIndexing
|
||||
};
|
||||
|
||||
virtual ~IIndexer() { }
|
||||
|
||||
@ -52,5 +57,6 @@ namespace musik { namespace core {
|
||||
virtual void RemovePath(const std::string& path) = 0;
|
||||
virtual void GetPaths(std::vector<std::string>& paths) = 0;
|
||||
virtual void Synchronize(bool restart = false) = 0;
|
||||
virtual State GetState() = 0;
|
||||
};
|
||||
} }
|
||||
|
@ -57,7 +57,7 @@
|
||||
|
||||
static const std::string TAG = "Indexer";
|
||||
static const int MAX_THREADS = 2;
|
||||
static const size_t NOTIFY_INTERVAL = 300;
|
||||
static const size_t TRANSACTION_INTERVAL = 300;
|
||||
|
||||
using namespace musik::core;
|
||||
using namespace musik::core::sdk;
|
||||
@ -85,6 +85,7 @@ Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename)
|
||||
, restart(false)
|
||||
, filesSaved(0)
|
||||
, exit(false)
|
||||
, state(StateIdle)
|
||||
, prefs(Preferences::ForComponent(prefs::components::Settings))
|
||||
, readSemaphore(prefs->GetInt(prefs::keys::MaxTagReadThreads, MAX_THREADS)) {
|
||||
this->dbFilename = dbFilename;
|
||||
@ -214,13 +215,15 @@ void Indexer::FinalizeSync() {
|
||||
}
|
||||
|
||||
/* notify observers */
|
||||
this->TrackRefreshed();
|
||||
this->Progress(this->filesSaved);
|
||||
|
||||
/* unload reader DLLs*/
|
||||
this->metadataReaders.clear();
|
||||
|
||||
this->RunAnalyzers();
|
||||
|
||||
this->state = StateIdle;
|
||||
|
||||
IndexerTrack::ResetIdCache();
|
||||
}
|
||||
|
||||
@ -297,6 +300,8 @@ void Indexer::ReadMetadataFromFile(
|
||||
}
|
||||
}
|
||||
|
||||
++this->filesSaved;
|
||||
|
||||
#ifdef MULTI_THREADED_INDEXER
|
||||
this->readSemaphore.post();
|
||||
#endif
|
||||
@ -330,12 +335,12 @@ void Indexer::SyncDirectory(
|
||||
std::vector<Thread> threads;
|
||||
|
||||
for( ; file != end && !this->Exited() && !this->Restarted(); file++) {
|
||||
if (this->filesSaved > NOTIFY_INTERVAL) {
|
||||
if (this->filesSaved > TRANSACTION_INTERVAL) {
|
||||
if (this->trackTransaction) {
|
||||
this->trackTransaction->CommitAndRestart();
|
||||
}
|
||||
|
||||
this->TrackRefreshed();
|
||||
this->Progress(this->filesSaved);
|
||||
this->filesSaved = 0;
|
||||
}
|
||||
if (is_directory(file->status())) {
|
||||
@ -378,7 +383,8 @@ void Indexer::ThreadLoop() {
|
||||
this->restart = false;
|
||||
|
||||
if(!firstTime || (firstTime && prefs->GetBool(prefs::keys::SyncOnStartup, true))) { /* first time through the loop skips this */
|
||||
this->SynchronizeStart();
|
||||
this->state = StateIndexing;
|
||||
this->Started();
|
||||
|
||||
this->dbConnection.Open(this->dbFilename.c_str(), 0); /* ensure the db is open */
|
||||
|
||||
@ -405,7 +411,11 @@ void Indexer::ThreadLoop() {
|
||||
|
||||
this->FinalizeSync();
|
||||
this->dbConnection.Close(); /* TODO: raii */
|
||||
this->SynchronizeEnd();
|
||||
|
||||
if (!restart) {
|
||||
this->Finished(this->filesSaved);
|
||||
}
|
||||
|
||||
musik::debug::info(TAG, "done!");
|
||||
} /* end skip */
|
||||
|
||||
|
@ -66,6 +66,7 @@ namespace musik { namespace core {
|
||||
virtual void RemovePath(const std::string& paths);
|
||||
virtual void GetPaths(std::vector<std::string>& paths);
|
||||
virtual void Synchronize(bool restart = false);
|
||||
virtual State GetState() { return this->state; }
|
||||
|
||||
private:
|
||||
void ThreadLoop();
|
||||
@ -101,6 +102,7 @@ namespace musik { namespace core {
|
||||
|
||||
bool restart;
|
||||
bool exit;
|
||||
State state;
|
||||
|
||||
boost::mutex stateMutex;
|
||||
boost::condition waitCondition;
|
||||
|
@ -149,7 +149,7 @@ int main(int argc, char* argv[])
|
||||
Layout consoleLayout(new ConsoleLayout(transport, library));
|
||||
Layout settingsLayout(new SettingsLayout(library, transport));
|
||||
|
||||
Main mainLayout(new MainLayout());
|
||||
Main mainLayout(new MainLayout(library));
|
||||
|
||||
std::vector<std::string> paths;
|
||||
library->Indexer()->GetPaths(paths);
|
||||
|
@ -83,8 +83,8 @@ BrowseLayout::BrowseLayout(
|
||||
: LayoutBase()
|
||||
, playback(playback) {
|
||||
this->library = library;
|
||||
this->library->Indexer()->TrackRefreshed.connect(this, &BrowseLayout::OnIndexerProgress);
|
||||
this->library->Indexer()->SynchronizeEnd.connect(this, &BrowseLayout::OnIndexerProgress);
|
||||
this->library->Indexer()->Progress.connect(this, &BrowseLayout::OnIndexerProgress);
|
||||
this->library->Indexer()->Finished.connect(this, &BrowseLayout::OnIndexerProgress);
|
||||
this->InitializeWindows();
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ BrowseLayout::~BrowseLayout() {
|
||||
|
||||
void BrowseLayout::OnLayout() {
|
||||
size_t cx = this->GetWidth(), cy = this->GetHeight();
|
||||
size_t x = this->GetX(), y = this->GetY();
|
||||
size_t x = 0, y = 0;
|
||||
|
||||
size_t categoryWidth = std::min(MAX_CATEGORY_WIDTH, cx / 4);
|
||||
|
||||
@ -161,7 +161,7 @@ void BrowseLayout::OnVisibilityChanged(bool visible) {
|
||||
}
|
||||
}
|
||||
|
||||
void BrowseLayout::OnIndexerProgress() {
|
||||
void BrowseLayout::OnIndexerProgress(int count) {
|
||||
this->categoryList->Requery();
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace musik {
|
||||
private:
|
||||
void InitializeWindows();
|
||||
|
||||
void OnIndexerProgress();
|
||||
void OnIndexerProgress(int count);
|
||||
void RequeryTrackList(cursespp::ListWindow *view);
|
||||
|
||||
void OnCategoryViewSelectionChanged(
|
||||
|
@ -96,17 +96,15 @@ ConsoleLayout::~ConsoleLayout() {
|
||||
void ConsoleLayout::OnLayout() {
|
||||
const int cx = this->GetWidth();
|
||||
const int cy = this->GetHeight();
|
||||
const int x = this->GetX();
|
||||
const int y = this->GetY();
|
||||
|
||||
const int leftCx = cx / 2;
|
||||
const int rightCx = cx - leftCx;
|
||||
|
||||
/* top left */
|
||||
this->output->MoveAndResize(x, y, leftCx, cy - 3);
|
||||
this->output->MoveAndResize(0, 0, leftCx, cy - 3);
|
||||
|
||||
/* bottom left */
|
||||
this->commands->MoveAndResize(x, cy - 3, leftCx, 3);
|
||||
this->commands->MoveAndResize(0, cy - 3, leftCx, 3);
|
||||
|
||||
/* right */
|
||||
this->logs->MoveAndResize(cx / 2, 0, rightCx, cy);
|
||||
|
@ -72,7 +72,7 @@ LibraryLayout::~LibraryLayout() {
|
||||
}
|
||||
|
||||
void LibraryLayout::OnLayout() {
|
||||
int x = this->GetX(), y = this->GetY();
|
||||
int x = 0, y = 0;
|
||||
int cx = this->GetWidth(), cy = this->GetHeight();
|
||||
|
||||
int mainHeight = cy - TRANSPORT_HEIGHT;
|
||||
|
@ -35,24 +35,45 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <cursespp/Screen.h>
|
||||
#include <cursespp/Colors.h>
|
||||
|
||||
#include <core/runtime/Message.h>
|
||||
#include <app/util/PreferenceKeys.h>
|
||||
|
||||
#include "SettingsLayout.h"
|
||||
#include "MainLayout.h"
|
||||
|
||||
#define MESSAGE_INDEXER_STARTED 1000
|
||||
#define MESSAGE_INDEXER_PROGRESS 1001
|
||||
#define MESSAGE_INDEXER_FINISHED 1002
|
||||
|
||||
#define SYNCING_TEXT_FORMAT "syncing metadata (%d tracks processed)"
|
||||
|
||||
using namespace musik;
|
||||
using namespace musik::box;
|
||||
using namespace musik::core;
|
||||
using namespace musik::core::runtime;
|
||||
using namespace cursespp;
|
||||
|
||||
MainLayout::MainLayout()
|
||||
static void updateSyncingText(TextLabel* label, int updates) {
|
||||
label->SetText(boost::str(boost::format(
|
||||
SYNCING_TEXT_FORMAT) % updates), cursespp::text::AlignCenter);
|
||||
}
|
||||
|
||||
MainLayout::MainLayout(ILibraryPtr library)
|
||||
: shortcutsFocused(false)
|
||||
, topLevelLayout(nullptr)
|
||||
, syncUpdateCount(0)
|
||||
, library(library)
|
||||
, LayoutBase() {
|
||||
this->Initialize();
|
||||
|
||||
this->prefs = Preferences::ForComponent("settings");
|
||||
this->ResizeToViewport();
|
||||
|
||||
library->Indexer()->Started.connect(this, &MainLayout::OnIndexerStarted);
|
||||
library->Indexer()->Finished.connect(this, &MainLayout::OnIndexerFinished);
|
||||
library->Indexer()->Progress.connect(this, &MainLayout::OnIndexerProgress);
|
||||
}
|
||||
|
||||
MainLayout::~MainLayout() {
|
||||
@ -65,8 +86,20 @@ void MainLayout::ResizeToViewport() {
|
||||
void MainLayout::OnLayout() {
|
||||
size_t cx = Screen::GetWidth(), cy = Screen::GetHeight();
|
||||
|
||||
int yOffset = 0;
|
||||
|
||||
auto state = this->library->Indexer()->GetState();
|
||||
if (state == IIndexer::StateIndexing) {
|
||||
yOffset = 1;
|
||||
this->syncing->MoveAndResize(0, 0, cx, 1);
|
||||
this->syncing->Show();
|
||||
}
|
||||
else {
|
||||
this->syncing->Hide();
|
||||
}
|
||||
|
||||
if (this->layout) {
|
||||
this->layout->MoveAndResize(0, 0, cx, cy - 1);
|
||||
this->layout->MoveAndResize(0, yOffset, cx, cy - 1 - yOffset);
|
||||
this->layout->Show();
|
||||
this->layout->BringToTop();
|
||||
|
||||
@ -81,6 +114,10 @@ void MainLayout::OnLayout() {
|
||||
void MainLayout::Initialize() {
|
||||
this->shortcuts.reset(new ShortcutsWindow());
|
||||
this->AddWindow(this->shortcuts);
|
||||
|
||||
this->syncing.reset(new TextLabel());
|
||||
this->syncing->SetContentColor(CURSESPP_BANNER);
|
||||
this->AddWindow(this->syncing);
|
||||
}
|
||||
|
||||
cursespp::IWindowPtr MainLayout::GetFocus() {
|
||||
@ -201,3 +238,34 @@ bool MainLayout::KeyPress(const std::string& key) {
|
||||
|
||||
return this->layout ? this->layout->KeyPress(key) : false;
|
||||
}
|
||||
|
||||
void MainLayout::ProcessMessage(musik::core::runtime::IMessage &message) {
|
||||
int type = message.Type();
|
||||
if (type == MESSAGE_INDEXER_STARTED) {
|
||||
updateSyncingText(this->syncing.get(), 0);
|
||||
this->syncUpdateCount = 0;
|
||||
|
||||
if (!syncing->IsVisible()) {
|
||||
this->Layout();
|
||||
}
|
||||
}
|
||||
else if (type == MESSAGE_INDEXER_FINISHED) {
|
||||
this->Layout();
|
||||
}
|
||||
else if (type == MESSAGE_INDEXER_PROGRESS) {
|
||||
this->syncUpdateCount += (int)message.UserData1();
|
||||
updateSyncingText(this->syncing.get(), this->syncUpdateCount);
|
||||
}
|
||||
}
|
||||
|
||||
void MainLayout::OnIndexerStarted() {
|
||||
this->PostMessage(MESSAGE_INDEXER_STARTED);
|
||||
}
|
||||
|
||||
void MainLayout::OnIndexerProgress(int count) {
|
||||
this->PostMessage(MESSAGE_INDEXER_PROGRESS, count);
|
||||
}
|
||||
|
||||
void MainLayout::OnIndexerFinished(int count) {
|
||||
this->PostMessage(MESSAGE_INDEXER_FINISHED);
|
||||
}
|
@ -39,6 +39,8 @@
|
||||
#include <cursespp/ShortcutsWindow.h>
|
||||
#include <cursespp/IViewRoot.h>
|
||||
#include <core/support/Preferences.h>
|
||||
#include <core/library/ILibrary.h>
|
||||
#include <core/runtime/IMessageTarget.h>
|
||||
|
||||
#include "ITopLevelLayout.h"
|
||||
|
||||
@ -55,7 +57,7 @@ namespace musik {
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
MainLayout();
|
||||
MainLayout(musik::core::ILibraryPtr library);
|
||||
virtual ~MainLayout();
|
||||
|
||||
virtual bool KeyPress(const std::string& key);
|
||||
@ -69,7 +71,14 @@ namespace musik {
|
||||
|
||||
void SetMainLayout(std::shared_ptr<cursespp::LayoutBase> layout);
|
||||
|
||||
virtual void ProcessMessage(musik::core::runtime::IMessage &message);
|
||||
|
||||
private:
|
||||
void OnIndexerStarted();
|
||||
void OnIndexerProgress(int count);
|
||||
void OnIndexerFinished(int count);
|
||||
|
||||
|
||||
void Initialize();
|
||||
cursespp::IWindowPtr BlurShortcuts();
|
||||
void FocusShortcuts();
|
||||
@ -77,9 +86,12 @@ namespace musik {
|
||||
std::shared_ptr<musik::core::Preferences> prefs;
|
||||
std::shared_ptr<cursespp::ShortcutsWindow> shortcuts;
|
||||
std::shared_ptr<cursespp::LayoutBase> layout;
|
||||
std::shared_ptr<cursespp::TextLabel> syncing;
|
||||
musik::core::ILibraryPtr library;
|
||||
cursespp::IWindowPtr lastFocus;
|
||||
ITopLevelLayout* topLevelLayout;
|
||||
bool shortcutsFocused;
|
||||
int syncUpdateCount;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ SearchLayout::~SearchLayout() {
|
||||
|
||||
void SearchLayout::OnLayout() {
|
||||
size_t cx = this->GetWidth(), cy = this->GetHeight();
|
||||
size_t x = this->GetX(), y = this->GetY();
|
||||
size_t x = 0, y = 0;
|
||||
|
||||
size_t inputWidth = cx / 2;
|
||||
size_t inputX = x + ((cx - inputWidth) / 2);
|
||||
|
@ -76,7 +76,7 @@ TrackSearchLayout::~TrackSearchLayout() {
|
||||
|
||||
void TrackSearchLayout::OnLayout() {
|
||||
size_t cx = this->GetWidth(), cy = this->GetHeight();
|
||||
int x = this->GetX(), y = this->GetY();
|
||||
int x = 0, y = 0;
|
||||
|
||||
size_t inputWidth = cx / 2;
|
||||
size_t inputX = x + ((cx - inputWidth) / 2);
|
||||
|
@ -165,9 +165,6 @@ void App::Run(ILayoutPtr layout) {
|
||||
|
||||
bool quit = false;
|
||||
|
||||
bool wasVisible = true;
|
||||
bool visible = true;
|
||||
|
||||
this->state.input = nullptr;
|
||||
this->state.keyHandler = nullptr;
|
||||
|
||||
@ -180,6 +177,7 @@ void App::Run(ILayoutPtr layout) {
|
||||
/* if the focused window is an input, allow it to draw a cursor */
|
||||
WINDOW *c = this->state.focused->GetContent();
|
||||
keypad(c, TRUE);
|
||||
wtimeout(c, IDLE_TIMEOUT_MS);
|
||||
ch = wgetch(c);
|
||||
}
|
||||
else {
|
||||
@ -231,15 +229,11 @@ void App::Run(ILayoutPtr layout) {
|
||||
resizeAt = 0;
|
||||
}
|
||||
|
||||
if (visible || (!visible && wasVisible)) {
|
||||
this->CheckShowOverlay();
|
||||
this->EnsureFocusIsValid();
|
||||
Window::WriteToScreen(this->state.input);
|
||||
}
|
||||
this->CheckShowOverlay();
|
||||
this->EnsureFocusIsValid();
|
||||
|
||||
Window::WriteToScreen(this->state.input);
|
||||
Window::MessageQueue().Dispatch();
|
||||
|
||||
wasVisible = visible;
|
||||
}
|
||||
|
||||
overlays.Clear();
|
||||
|
@ -166,4 +166,6 @@ void Colors::Init(bool disableCustomColors) {
|
||||
init_pair(CURSESPP_OVERLAY_FRAME, blue, selected);
|
||||
init_pair(CURSESPP_OVERLAY_BACKGROUND, white, selected);
|
||||
init_pair(CURSESPP_OVERLAY_INPUT_FRAME, red, selected);
|
||||
|
||||
init_pair(CURSESPP_BANNER, black, orange);
|
||||
}
|
||||
|
@ -67,6 +67,8 @@
|
||||
#define CURSESPP_OVERLAY_BACKGROUND 22
|
||||
#define CURSESPP_OVERLAY_INPUT_FRAME 23
|
||||
|
||||
#define CURSESPP_BANNER 24
|
||||
|
||||
namespace cursespp {
|
||||
class Colors {
|
||||
private:
|
||||
|
@ -108,6 +108,8 @@ Window::Window(IWindow *parent) {
|
||||
this->width = 0;
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->lastAbsoluteX = 0;
|
||||
this->lastAbsoluteY = 0;
|
||||
this->contentColor = CURSESPP_DEFAULT_CONTENT_COLOR;
|
||||
this->frameColor = CURSESPP_DEFAULT_FRAME_COLOR;
|
||||
this->focusedContentColor = CURSESPP_DEFAULT_CONTENT_COLOR;
|
||||
@ -214,13 +216,21 @@ void Window::RecreateForUpdatedDimensions() {
|
||||
|
||||
void Window::MoveAndResize(int x, int y, int width, int height) {
|
||||
bool sizeChanged = this->width != width || this->height != height;
|
||||
bool positionChanged = this->x != x || this->y != y;
|
||||
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
int absX = this->GetAbsoluteX();
|
||||
int absY = this->GetAbsoluteY();
|
||||
|
||||
bool positionChanged =
|
||||
absX != this->lastAbsoluteX ||
|
||||
absY != this->lastAbsoluteY;
|
||||
|
||||
if (sizeChanged || positionChanged) {
|
||||
this->lastAbsoluteX = absX;
|
||||
this->lastAbsoluteY = absY;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->RecreateForUpdatedDimensions();
|
||||
}
|
||||
}
|
||||
@ -234,9 +244,14 @@ void Window::SetSize(int width, int height) {
|
||||
}
|
||||
|
||||
void Window::SetPosition(int x, int y) {
|
||||
if (this->x != x || this->y != y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
int absX = this->GetAbsoluteX();
|
||||
int absY = this->GetAbsoluteY();
|
||||
|
||||
if (absX != this->lastAbsoluteX || absY != this->lastAbsoluteY) {
|
||||
this->lastAbsoluteX = absX;
|
||||
this->lastAbsoluteY = absY;
|
||||
this->RecreateForUpdatedDimensions();
|
||||
}
|
||||
}
|
||||
|
@ -152,5 +152,6 @@ namespace cursespp {
|
||||
int64 contentColor, frameColor;
|
||||
int64 focusedContentColor, focusedFrameColor;
|
||||
int width, height, x, y;
|
||||
int lastAbsoluteX, lastAbsoluteY;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user