diff --git a/Makefile b/Makefile index 2d2a957..e40bb20 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ LDFLAGS = -g LDLIBS += -L lib/ #LDLIBS += -L lib_web/ -LD_DYNAMIC_LIBS = -lraylib -lsdbus-c++ -lmagic #only enable if dynamic mode +LD_DYNAMIC_LIBS = -lraylib -lsdbus-c++ -lmagic -lcurl #only enable if dynamic mode LD_STATIC_LIBS = -l:libraylib.a #only enable if static mode EXTRA_DIRS = $(OBJ_DIR)/rlImGui diff --git a/src/main.cpp b/src/main.cpp index 425d1eb..4af4f75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include #include #include +#include extern "C" { #include "testc.h" } @@ -136,6 +137,53 @@ std::vector GetMprisServices() { return ret; } +void DrawPlay(Vector2 Pos, float scale, Color color) { + Vector2 backtop = (Vector2) { .x=-0.29f, .y=-0.40f }; + Vector2 backbot = (Vector2) { .x=-0.29f, .y=0.40f}; + Vector2 front = (Vector2) {.x = 0.5f, .y=0}; + + backtop = Vector2Scale(backtop, scale); + backbot = Vector2Scale(backbot, scale); + front = Vector2Scale(front, scale); + + backtop = Vector2Add(backtop, Pos); + backbot = Vector2Add(backbot, Pos); + front = Vector2Add(front, Pos); + + DrawTriangle(backtop, backbot, front, color); +} + +void DrawStop(Vector2 Pos, float scale, Color color) { + Vector2 topleft = (Vector2) {.x = -0.353f, .y = -0.353f }; + Vector2 botright = (Vector2) {.x = 0.353f, .y = 0.353f }; + topleft = Vector2Scale(topleft, scale); + botright = Vector2Scale(botright, scale*2); + + topleft = Vector2Add(topleft, Pos); + + DrawRectangleV(topleft, botright, color); +} + +void DrawPause(Vector2 Pos, float scale, Color color) { + Vector2 topleft = (Vector2) {.x = -0.353f, .y = -0.353f }; + + + Vector2 bar1topleft = Vector2Scale(topleft, scale); + bar1topleft = Vector2Add(bar1topleft, Pos); + + Vector2 bar2topleft = Vector2Add(topleft, (Vector2) {0.706f*0.6f, .y=0}); + bar2topleft = Vector2Scale(bar2topleft, scale); + bar2topleft = Vector2Add(bar2topleft, Pos); + + Vector2 size = (Vector2) {.x=0.706f *0.4f, .y = 0.706f }; + size = Vector2Scale(size, scale); + + topleft = Vector2Add(topleft, Pos); + + DrawRectangleV(bar1topleft, size, color); + DrawRectangleV(bar2topleft, size, color); +} + float ScaleToFit(Vector2 src, Vector2 dst) { float ratio = std::min(dst.x/src.x, dst.y/src.y); return ratio; @@ -158,8 +206,10 @@ int main(int argc, char *argv[]) { TestC(); TestCPPFunc(); + curl_global_init(CURL_GLOBAL_ALL); bool run = true; + bool showIMgui = false; bool showDemoWindow = false; @@ -216,76 +266,98 @@ int main(int argc, char *argv[]) { DrawTextureEx(current_player.tex.tex, (Vector2) {0,0}, 0, ScaleToFit(imagesize, winwidth), WHITE); - // start ImGui content - rlImGuiBegin(); - // if you want windows to dock to the viewport, call this. -#ifdef IMGUI_HAS_DOCK - ImGui::DockSpaceOverViewport(); -#endif + if ( IsWindowFocused() ) { + const float buttonsize = 0.1; + Vector2 screen = (Vector2) {(float) GetScreenWidth(), (float) GetScreenHeight()}; + Vector2 centerline; + centerline.x = screen.x / 2; + centerline.y = screen.y * 0.8; - // show a simple menu bar - if (ImGui::BeginMainMenuBar()) { - if (ImGui::BeginMenu("File")) { -#ifdef IMGUI_HAS_DOCK - if (ImGui::MenuItem("Enable Docking")) { - ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable; - } - if (ImGui::MenuItem("Disable Docking")) { - ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_DockingEnable; - } -#endif - if (ImGui::MenuItem("Quit")) - run = false; + Color transblack = BLACK; + transblack.a = (200); + DrawCircleV(centerline, 0.05*GetScreenWidth(), transblack); - ImGui::EndMenu(); + if (current_player.playstate == "Playing") { + DrawPause(centerline, 0.1*GetScreenWidth(), WHITE); + } else { + DrawPlay(centerline, 0.1*GetScreenWidth(), WHITE); } - - if (ImGui::BeginMenu("Players")) { - for (auto item : serviceList) { - if (ImGui::MenuItem(item.c_str())) { - current_player = MprisPlayer(item); - } - } - ImGui::EndMenu(); - } - - if (ImGui::BeginMenu("Window")) { - if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow)) - showDemoWindow = !showDemoWindow; - - ImGui::EndMenu(); - } - ImGui::EndMainMenuBar(); - } - - // show some windows - - if (ImGui::Begin("Player Control")) { - ImGui::Text("%s", current_player.GetIdentity().c_str()); - if (ImGui::Button("Prev")) { - current_player.Prev(); - } - if (ImGui::Button("Play/Pause")) { + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointCircle(GetMousePosition(), centerline, 0.05*GetScreenWidth()) ) { current_player.PausePlay(); + current_player.playstate = current_player.playstate == "Playing" ? "Paused" : "Playing"; } - if (ImGui::Button("Next")) { - current_player.Next(); - } - if (ImGui::Button("Refresh")) { - current_player.Refresh(); - current_player.UpdateTexture(); - } - //rlImGuiImage(¤t_player.tex.tex); - rlImGuiImageSize(¤t_player.tex.tex,300,300); + + } - ImGui::End(); - if (showDemoWindow) - ImGui::ShowDemoWindow(&showDemoWindow); - // end ImGui Content - rlImGuiEnd(); + if (IsKeyPressed(KEY_SLASH)) { + showIMgui = !showIMgui; + } + + // start ImGui content + + if (showIMgui) { + rlImGuiBegin(); + + // if you want windows to dock to the viewport, call this. + // show a simple menu bar + if (ImGui::BeginMainMenuBar()) { + if (ImGui::BeginMenu("File")) { + + if (ImGui::MenuItem("Quit")) + run = false; + + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Players")) { + for (auto item : serviceList) { + if (ImGui::MenuItem(item.c_str())) { + current_player = MprisPlayer(item); + } + } + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Window")) { + if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow)) + showDemoWindow = !showDemoWindow; + + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } + + // show some windows + + if (ImGui::Begin("Player Control")) { + ImGui::Text("%s", current_player.GetIdentity().c_str()); + if (ImGui::Button("Prev")) { + current_player.Prev(); + } + if (ImGui::Button("Play/Pause")) { + current_player.PausePlay(); + } + if (ImGui::Button("Next")) { + current_player.Next(); + } + if (ImGui::Button("Refresh")) { + current_player.Refresh(); + current_player.UpdateTexture(); + } + //rlImGuiImage(¤t_player.tex.tex); + rlImGuiImageSize(¤t_player.tex.tex,300,300); + } + ImGui::End(); + + if (showDemoWindow) + ImGui::ShowDemoWindow(&showDemoWindow); + + // end ImGui Content + rlImGuiEnd(); + } EndDrawing(); //---------------------------------------------------------------------------------- @@ -296,6 +368,6 @@ int main(int argc, char *argv[]) { //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- - + curl_global_cleanup(); return 0; } diff --git a/src/mpris_connection.cpp b/src/mpris_connection.cpp index 1360bcf..8022d15 100644 --- a/src/mpris_connection.cpp +++ b/src/mpris_connection.cpp @@ -5,9 +5,11 @@ #define IMGUI_DEFINE_MATH_OPERATORS #include "imgui.h" +#include +#include #include -#include #include +#include #include MprisPlayer::MprisPlayer(std::string servicename) { @@ -53,6 +55,7 @@ void MprisPlayer::Refresh() { identity = PlayerProxy->getProperty("Identity") .onInterface("org.mpris.MediaPlayer2") .get(); + playstate = PlayerProxy->getProperty("PlaybackStatus").onInterface("org.mpris.MediaPlayer2.Player").get(); current_metadata = PlayerProxy->getProperty("Metadata") .onInterface("org.mpris.MediaPlayer2.Player") .get>(); @@ -64,12 +67,60 @@ void MprisPlayer::Refresh() { return; } + +static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, + void* userp) { + size_t realsize = size * nmemb; + auto& mem = *static_cast(userp); + mem.append(static_cast(contents), realsize); + return realsize; +} + void MprisPlayer::UpdateTexture() { std::string filename = image_path_cache; + std::cout << filename << std::endl; if (filename.length() > 0) { + if (filename.c_str()[0] == 'h') { + CURL* curl_handle; + CURLcode res; + + std::string chunk; + + + curl_handle = curl_easy_init(); + curl_easy_setopt(curl_handle, CURLOPT_URL, filename.c_str()); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &chunk); + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + // added options that may be required + curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); // redirects + curl_easy_setopt(curl_handle, CURLOPT_HTTPPROXYTUNNEL, 1L); // corp. proxies etc. + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // we want it all + // curl_easy_setopt(curl_handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + + res = curl_easy_perform(curl_handle); + + if(res != CURLE_OK) { + std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << '\n'; + } else { + std::cout << chunk.size() << " bytes retrieved\n"; + } + + std::ofstream output("/tmp/mpris-miniplayer-out"); + + if (output.is_open()) { + output << chunk; + output.close(); + } + filename = "file:///tmp/mpris-miniplayer-out"; + + curl_easy_cleanup(curl_handle); + + + } if (filename.c_str()[0] == 'f') { std::cout << "parsing as file" << std::endl; - std::cout << filename << std::endl; std::string path = filename.substr(7); FILE * f = fopen(path.c_str(), "r"); if (f == NULL) { diff --git a/src/mpris_connection.hpp b/src/mpris_connection.hpp index eacd5d4..18a4b6b 100644 --- a/src/mpris_connection.hpp +++ b/src/mpris_connection.hpp @@ -37,6 +37,7 @@ class MprisPlayer { void Next(); void Prev(); std::string identity; + std::string playstate; std::string GetIdentity(); std::unordered_map current_metadata; std::unordered_map GetCurrentMetadata();