Add graphics and text display to plex panel
This commit is contained in:
parent
2d1a3db3e2
commit
9d1714cc7c
BIN
img/plex_background.jpg
Normal file
BIN
img/plex_background.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 472 KiB |
@ -46,6 +46,9 @@ const char* IMAGE_LOCATIONS[] = {
|
|||||||
"shower.png",
|
"shower.png",
|
||||||
"snowday.png",
|
"snowday.png",
|
||||||
"snownight.png",
|
"snownight.png",
|
||||||
|
|
||||||
|
//plex
|
||||||
|
"plex_background.jpg",
|
||||||
|
|
||||||
};
|
};
|
||||||
size_t IMAGE_LOCATIONS_LENGTH = sizeof(IMAGE_LOCATIONS)/sizeof(IMAGE_LOCATIONS[0]);
|
size_t IMAGE_LOCATIONS_LENGTH = sizeof(IMAGE_LOCATIONS)/sizeof(IMAGE_LOCATIONS[0]);
|
||||||
|
@ -78,8 +78,28 @@ void plex::update(){
|
|||||||
//parse the result
|
//parse the result
|
||||||
json_doc.Parse(json_string.c_str());
|
json_doc.Parse(json_string.c_str());
|
||||||
|
|
||||||
|
std::cerr << json_string << "\n";
|
||||||
|
|
||||||
//update internal state
|
//update internal state
|
||||||
//const rapidjson::Value& curr_entry = json_doc["value"];
|
rapidjson::Value& curr_entry = json_doc["response"]["data"]["data"];
|
||||||
|
|
||||||
|
for(short i = 0; i < 4; ++i){
|
||||||
|
entries.push_back({
|
||||||
|
truncate(curr_entry[i]["friendly_name"].GetString(),
|
||||||
|
PLEX_MAX_STRING_LENGTH),
|
||||||
|
truncate(curr_entry[i]["ip_address"].GetString(),
|
||||||
|
PLEX_MAX_STRING_LENGTH),
|
||||||
|
truncate(curr_entry[i]["title"].GetString(),
|
||||||
|
PLEX_MAX_STRING_LENGTH),
|
||||||
|
truncate(curr_entry[i]["state"].IsNull() ? "Historical" : "Playing",
|
||||||
|
PLEX_MAX_STRING_LENGTH),
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cerr << entries[i].friendly_name << "\n";
|
||||||
|
std::cerr << entries[i].ip_address << "\n";
|
||||||
|
std::cerr << entries[i].title << "\n";
|
||||||
|
std::cerr << entries[i].state << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,15 +108,216 @@ void plex::update(){
|
|||||||
// displayed, based on data in the json feed
|
// displayed, based on data in the json feed
|
||||||
void plex::update_texture(){
|
void plex::update_texture(){
|
||||||
std::cerr << "PLEX::UPDATE_TEXTURE\n";
|
std::cerr << "PLEX::UPDATE_TEXTURE\n";
|
||||||
|
uint8_t o_red, o_green, o_blue, o_alpha;
|
||||||
SDL_Rect tgt;
|
SDL_Rect tgt;
|
||||||
|
|
||||||
|
//save the old colors
|
||||||
|
SDL_GetRenderDrawColor(board::getRenderer(), &o_red,
|
||||||
|
&o_green, &o_blue, &o_alpha);
|
||||||
|
|
||||||
SDL_SetRenderTarget(board::getRenderer(), _texture);
|
SDL_SetRenderTarget(board::getRenderer(), _texture);
|
||||||
SDL_RenderClear(board::getRenderer());
|
SDL_RenderClear(board::getRenderer());
|
||||||
|
|
||||||
|
//set the new color
|
||||||
|
SDL_SetRenderDrawColor(board::getRenderer(),
|
||||||
|
PLEX_BGBOX_RED, PLEX_BGBOX_GREEN,
|
||||||
|
PLEX_BGBOX_BLUE, PLEX_BGBOX_ALPHA);
|
||||||
|
|
||||||
|
//background image
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getImage("plex_background.jpg"), NULL, NULL);
|
||||||
|
|
||||||
|
constexpr int GAP_SIZE = 10;
|
||||||
|
|
||||||
|
//draw the outline rectangles
|
||||||
|
tgt.x = GAP_SIZE;
|
||||||
|
tgt.y = DEF_OVERLAY_BAR_HEIGHT + GAP_SIZE;
|
||||||
|
tgt.w = (SCREEN_WIDTH / 3) - (2*GAP_SIZE);
|
||||||
|
tgt.h = (SCREEN_HEIGHT / 2) - DEF_OVERLAY_BAR_HEIGHT - (2*GAP_SIZE);
|
||||||
|
SDL_RenderFillRect(board::getRenderer(), &tgt);
|
||||||
|
|
||||||
|
tgt.x = GAP_SIZE;
|
||||||
|
tgt.y = (SCREEN_HEIGHT / 2) + GAP_SIZE;
|
||||||
|
tgt.w = (SCREEN_WIDTH / 3) - (2*GAP_SIZE);
|
||||||
|
tgt.h = (SCREEN_HEIGHT / 2) - DEF_OVERLAY_BAR_HEIGHT - (2*GAP_SIZE);
|
||||||
|
SDL_RenderFillRect(board::getRenderer(), &tgt);
|
||||||
|
|
||||||
|
tgt.x = (SCREEN_WIDTH / 3) + GAP_SIZE;
|
||||||
|
tgt.y = DEF_OVERLAY_BAR_HEIGHT + GAP_SIZE;
|
||||||
|
tgt.w = (SCREEN_WIDTH / 3) - (2*GAP_SIZE);
|
||||||
|
tgt.h = (SCREEN_HEIGHT / 2) - DEF_OVERLAY_BAR_HEIGHT - (2*GAP_SIZE);
|
||||||
|
SDL_RenderFillRect(board::getRenderer(), &tgt);
|
||||||
|
|
||||||
|
tgt.x = (SCREEN_WIDTH / 3) + GAP_SIZE;
|
||||||
|
tgt.y = (SCREEN_HEIGHT / 2) + GAP_SIZE;
|
||||||
|
tgt.w = (SCREEN_WIDTH / 3) - (2*GAP_SIZE);
|
||||||
|
tgt.h = (SCREEN_HEIGHT / 2) - DEF_OVERLAY_BAR_HEIGHT - (2*GAP_SIZE);
|
||||||
|
SDL_RenderFillRect(board::getRenderer(), &tgt);
|
||||||
|
|
||||||
|
tgt.x = ((2*SCREEN_WIDTH) / 3) + GAP_SIZE;
|
||||||
|
tgt.y = DEF_OVERLAY_BAR_HEIGHT + GAP_SIZE;
|
||||||
|
tgt.w = (SCREEN_WIDTH / 3) - (2*GAP_SIZE);
|
||||||
|
tgt.h = (SCREEN_HEIGHT) - (2*DEF_OVERLAY_BAR_HEIGHT) - (2*GAP_SIZE);
|
||||||
|
SDL_RenderFillRect(board::getRenderer(), &tgt);
|
||||||
|
|
||||||
|
//draw info for first box
|
||||||
|
{
|
||||||
|
tgt.x = GAP_SIZE;
|
||||||
|
tgt.y = DEF_OVERLAY_BAR_HEIGHT + GAP_SIZE;
|
||||||
|
constexpr int index = 0;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].title.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].title,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].friendly_name.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].friendly_name,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].ip_address.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].ip_address,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].state.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].state,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw the second box
|
||||||
|
{
|
||||||
|
tgt.x = GAP_SIZE;
|
||||||
|
tgt.y = (SCREEN_HEIGHT / 2) + GAP_SIZE;
|
||||||
|
constexpr int index = 1;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].title.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].title,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].friendly_name.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].friendly_name,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].ip_address.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].ip_address,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].state.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].state,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//third box
|
||||||
|
{
|
||||||
|
tgt.x = (SCREEN_WIDTH / 3) + GAP_SIZE;
|
||||||
|
tgt.y = DEF_OVERLAY_BAR_HEIGHT + GAP_SIZE;
|
||||||
|
constexpr int index = 2;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].title.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].title,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].friendly_name.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].friendly_name,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].ip_address.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].ip_address,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].state.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].state,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//draw info for fourth box
|
||||||
|
{
|
||||||
|
tgt.x = (SCREEN_WIDTH / 3) + GAP_SIZE;
|
||||||
|
tgt.y = (SCREEN_HEIGHT / 2) + GAP_SIZE;
|
||||||
|
constexpr int index = 3;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].title.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].title,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].friendly_name.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].friendly_name,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].ip_address.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].ip_address,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
tgt.y += tgt.h;
|
||||||
|
TTF_SizeText(board::getFont( {"Roboto_Mono/RobotoMono-Medium.ttf", 28 } ),
|
||||||
|
entries[index].state.c_str(),
|
||||||
|
&tgt.w, &tgt.h);
|
||||||
|
SDL_RenderCopy(board::getRenderer(),
|
||||||
|
board::getString(entries[index].state,
|
||||||
|
{"Roboto_Mono/RobotoMono-Medium.ttf", 28 }),
|
||||||
|
NULL, &tgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SDL_SetRenderTarget(board::getRenderer(), NULL);
|
SDL_SetRenderTarget(board::getRenderer(), NULL);
|
||||||
|
|
||||||
|
//reset back to the old render color
|
||||||
|
SDL_SetRenderDrawColor(board::getRenderer(),
|
||||||
|
o_red, o_green, o_blue, o_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
@ -114,6 +335,18 @@ void plex::initTexture(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Helper function to truncate a string with an elipsis
|
||||||
|
std::string plex::truncate(std::string str, size_t width, bool show_ellipsis){
|
||||||
|
if(str.length() > width){
|
||||||
|
if(show_ellipsis)
|
||||||
|
return str.substr(0, width - 3) + "...";
|
||||||
|
else
|
||||||
|
return str.substr(0, width);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Curl callback function
|
// Curl callback function
|
||||||
size_t dashboard::panel::plex::curl_callback(void* contents, size_t size,
|
size_t dashboard::panel::plex::curl_callback(void* contents, size_t size,
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace dashboard::panel {
|
namespace dashboard::panel {
|
||||||
class plex : public panel {
|
class plex : public panel {
|
||||||
@ -33,10 +34,22 @@ namespace dashboard::panel {
|
|||||||
void update_texture();
|
void update_texture();
|
||||||
void initTexture();
|
void initTexture();
|
||||||
|
|
||||||
|
std::string truncate(std::string, size_t, bool = true);
|
||||||
|
|
||||||
CURL* api_curl;
|
CURL* api_curl;
|
||||||
std::string json_string;
|
std::string json_string;
|
||||||
rapidjson::Document json_doc;
|
rapidjson::Document json_doc;
|
||||||
|
|
||||||
|
struct plex_entry {
|
||||||
|
std::string friendly_name;
|
||||||
|
std::string ip_address;
|
||||||
|
std::string title;
|
||||||
|
std::string state;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<plex_entry> entries;
|
||||||
|
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> _last_update;
|
std::chrono::time_point<std::chrono::high_resolution_clock> _last_update;
|
||||||
std::chrono::milliseconds _update_interval;
|
std::chrono::milliseconds _update_interval;
|
||||||
};
|
};
|
||||||
|
@ -6,13 +6,18 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "def_overlay_config.hpp"
|
||||||
|
|
||||||
namespace dashboard::panel {
|
namespace dashboard::panel {
|
||||||
//This will be displayed at the top left on the status bar. Set to a blank
|
//This will be displayed at the top left on the status bar. Set to a blank
|
||||||
//string to not show anything
|
//string to not show anything
|
||||||
constexpr char PLEX_TITLE[] = "Plex";
|
constexpr char PLEX_TITLE[] = "Plex";
|
||||||
|
|
||||||
//Tautili endpoint
|
//Tautili endpoint
|
||||||
constexpr char PLEX_URL_SOURCE[] = "http://192.168.1.104:8181/api/v2?apikey=<KEY_GOES_HERE>&cmd=";
|
constexpr char PLEX_URL_SOURCE[] = "http://192.168.1.104:8181/api/v2?apikey=64af06e0497342f7a5862462ddbbd309&cmd=get_history&length=5";
|
||||||
|
|
||||||
|
//How many characters of a show title should we show?
|
||||||
|
constexpr size_t PLEX_MAX_STRING_LENGTH = 35;
|
||||||
|
|
||||||
//Default time the slid is shown on screen, in ms
|
//Default time the slid is shown on screen, in ms
|
||||||
//Default 15s
|
//Default 15s
|
||||||
@ -22,4 +27,11 @@ namespace dashboard::panel {
|
|||||||
//Default 30s
|
//Default 30s
|
||||||
constexpr size_t PLEX_UPDATE_INTERVAL = 30000;
|
constexpr size_t PLEX_UPDATE_INTERVAL = 30000;
|
||||||
|
|
||||||
|
//Color for background bounding boxes
|
||||||
|
constexpr uint8_t PLEX_BGBOX_RED = 0xD3;
|
||||||
|
constexpr uint8_t PLEX_BGBOX_GREEN = 0xD3;
|
||||||
|
constexpr uint8_t PLEX_BGBOX_BLUE = 0xD3;
|
||||||
|
constexpr uint8_t PLEX_BGBOX_ALPHA = 0x7F;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user