Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
719400068a | |||
aaf8c6adc1 | |||
dc081ae2aa |
@ -35,6 +35,16 @@ namespace Components {
|
||||
float fade {1.f};
|
||||
};
|
||||
|
||||
struct ConvertedTimeCache {
|
||||
// calling localtime is expensive af
|
||||
int tm_year {0};
|
||||
int tm_yday {0};
|
||||
int tm_mon {0};
|
||||
int tm_mday {0};
|
||||
int tm_hour {0};
|
||||
int tm_min {0};
|
||||
};
|
||||
|
||||
} // Components
|
||||
|
||||
static constexpr float lerp(float a, float b, float t) {
|
||||
@ -324,7 +334,8 @@ float ChatGui4::render(float time_delta) {
|
||||
//tmp_view.use<Message::Components::Timestamp>();
|
||||
//tmp_view.each([&](const Message3 e, Message::Components::ContactFrom& c_from, Message::Components::ContactTo& c_to, Message::Components::Timestamp ts
|
||||
//) {
|
||||
uint64_t prev_ts {0};
|
||||
//uint64_t prev_ts {0};
|
||||
Components::ConvertedTimeCache prev_time {};
|
||||
auto tmp_view = msg_reg.view<Message::Components::Timestamp>();
|
||||
for (auto view_it = tmp_view.rbegin(), view_last = tmp_view.rend(); view_it != view_last; view_it++) {
|
||||
const Message3 e = *view_it;
|
||||
@ -342,15 +353,12 @@ float ChatGui4::render(float time_delta) {
|
||||
// TODO: why?
|
||||
ImGui::TableNextRow(0, TEXT_BASE_HEIGHT);
|
||||
|
||||
{ // check if date changed
|
||||
// TODO: find defined ways of casting to time_t
|
||||
std::time_t prev = prev_ts / 1000;
|
||||
std::time_t next = ts.ts / 1000;
|
||||
std::tm prev_tm = *std::localtime(&prev);
|
||||
std::tm next_tm = *std::localtime(&next);
|
||||
if (msg_reg.all_of<Components::ConvertedTimeCache>(e)) { // check if date changed
|
||||
// TODO: move conversion up?
|
||||
const auto& next_time = msg_reg.get<Components::ConvertedTimeCache>(e);
|
||||
if (
|
||||
prev_tm.tm_yday != next_tm.tm_yday ||
|
||||
prev_tm.tm_year != next_tm.tm_year // making sure
|
||||
prev_time.tm_yday != next_time.tm_yday ||
|
||||
prev_time.tm_year != next_time.tm_year // making sure
|
||||
) {
|
||||
// name
|
||||
if (ImGui::TableNextColumn()) {
|
||||
@ -359,14 +367,14 @@ float ChatGui4::render(float time_delta) {
|
||||
// msg
|
||||
if (ImGui::TableNextColumn()) {
|
||||
ImGui::TextDisabled("DATE CHANGED from %d.%d.%d to %d.%d.%d",
|
||||
1900+prev_tm.tm_year, 1+prev_tm.tm_mon, prev_tm.tm_mday,
|
||||
1900+next_tm.tm_year, 1+next_tm.tm_mon, next_tm.tm_mday
|
||||
1900+prev_time.tm_year, 1+prev_time.tm_mon, prev_time.tm_mday,
|
||||
1900+next_time.tm_year, 1+next_time.tm_mon, next_time.tm_mday
|
||||
);
|
||||
}
|
||||
ImGui::TableNextRow(0, TEXT_BASE_HEIGHT);
|
||||
}
|
||||
|
||||
prev_ts = ts.ts;
|
||||
prev_time = next_time;
|
||||
}
|
||||
|
||||
|
||||
@ -519,12 +527,24 @@ float ChatGui4::render(float time_delta) {
|
||||
|
||||
// ts
|
||||
if (ImGui::TableNextColumn()) {
|
||||
auto time = std::chrono::system_clock::to_time_t(
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>{std::chrono::milliseconds{ts.ts}}
|
||||
);
|
||||
auto localtime = std::localtime(&time);
|
||||
if (!msg_reg.all_of<Components::ConvertedTimeCache>(e)) {
|
||||
auto time = std::chrono::system_clock::to_time_t(
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>{std::chrono::milliseconds{ts.ts}}
|
||||
);
|
||||
auto localtime = std::localtime(&time);
|
||||
msg_reg.emplace<Components::ConvertedTimeCache>(
|
||||
e,
|
||||
localtime->tm_year,
|
||||
localtime->tm_yday,
|
||||
localtime->tm_mon,
|
||||
localtime->tm_mday,
|
||||
localtime->tm_hour,
|
||||
localtime->tm_min
|
||||
);
|
||||
}
|
||||
const auto& ctc = msg_reg.get<Components::ConvertedTimeCache>(e);
|
||||
|
||||
ImGui::Text("%.2d:%.2d", localtime->tm_hour, localtime->tm_min);
|
||||
ImGui::Text("%.2d:%.2d", ctc.tm_hour, ctc.tm_min);
|
||||
}
|
||||
|
||||
// extra
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "./image_loader_webp.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <webp/demux.h>
|
||||
#include <webp/mux.h>
|
||||
#include <webp/encode.h>
|
||||
@ -21,13 +22,16 @@ ImageLoaderWebP::ImageInfo ImageLoaderWebP::loadInfoFromMemory(const uint8_t* da
|
||||
// Tune 'dec_options' as needed.
|
||||
dec_options.color_mode = MODE_RGBA;
|
||||
|
||||
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
|
||||
if (dec == nullptr) {
|
||||
std::unique_ptr<WebPAnimDecoder, decltype(&WebPAnimDecoderDelete)> dec{
|
||||
WebPAnimDecoderNew(&webp_data, &dec_options),
|
||||
&WebPAnimDecoderDelete
|
||||
};
|
||||
if (!static_cast<bool>(dec)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
WebPAnimInfo anim_info;
|
||||
WebPAnimDecoderGetInfo(dec, &anim_info);
|
||||
WebPAnimDecoderGetInfo(dec.get(), &anim_info);
|
||||
res.width = anim_info.canvas_width;
|
||||
res.height = anim_info.canvas_height;
|
||||
res.file_ext = "webp";
|
||||
@ -48,22 +52,25 @@ ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t*
|
||||
// Tune 'dec_options' as needed.
|
||||
dec_options.color_mode = MODE_RGBA;
|
||||
|
||||
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
|
||||
if (dec == nullptr) {
|
||||
std::unique_ptr<WebPAnimDecoder, decltype(&WebPAnimDecoderDelete)> dec{
|
||||
WebPAnimDecoderNew(&webp_data, &dec_options),
|
||||
&WebPAnimDecoderDelete
|
||||
};
|
||||
if (!static_cast<bool>(dec)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
WebPAnimInfo anim_info;
|
||||
WebPAnimDecoderGetInfo(dec, &anim_info);
|
||||
WebPAnimDecoderGetInfo(dec.get(), &anim_info);
|
||||
res.width = anim_info.canvas_width;
|
||||
res.height = anim_info.canvas_height;
|
||||
res.file_ext = "webp";
|
||||
|
||||
int prev_timestamp = 0;
|
||||
while (WebPAnimDecoderHasMoreFrames(dec)) {
|
||||
while (WebPAnimDecoderHasMoreFrames(dec.get())) {
|
||||
uint8_t* buf;
|
||||
int timestamp;
|
||||
WebPAnimDecoderGetNext(dec, &buf, ×tamp);
|
||||
WebPAnimDecoderGetNext(dec.get(), &buf, ×tamp);
|
||||
// ... (Render 'buf' based on 'timestamp').
|
||||
// ... (Do NOT free 'buf', as it is owned by 'dec').
|
||||
|
||||
@ -74,8 +81,6 @@ ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t*
|
||||
new_frame.data.insert(new_frame.data.end(), buf, buf+(res.width*res.height*4));
|
||||
}
|
||||
|
||||
WebPAnimDecoderDelete(dec);
|
||||
|
||||
assert(anim_info.frame_count == res.frames.size());
|
||||
|
||||
return res;
|
||||
|
@ -376,7 +376,7 @@ Screen* MainScreen::render(float time_delta, bool&) {
|
||||
}
|
||||
|
||||
Screen* MainScreen::tick(float time_delta, bool& quit) {
|
||||
quit = !tc.iterate(); // compute
|
||||
quit = !tc.iterate(time_delta); // compute
|
||||
|
||||
tcm.iterate(time_delta); // compute
|
||||
|
||||
|
@ -83,6 +83,7 @@ bool SendImagePopup::load(void) {
|
||||
}
|
||||
}
|
||||
|
||||
assert(preview_image.textures.empty());
|
||||
preview_image.timestamp_last_rendered = Message::getTimeMS();
|
||||
preview_image.current_texture = 0;
|
||||
for (const auto& [ms, data] : original_image.frames) {
|
||||
@ -173,7 +174,7 @@ void SendImagePopup::render(float time_delta) {
|
||||
|
||||
// TODO: add cancel shortcut (esc)
|
||||
if (ImGui::BeginPopupModal("send image##SendImagePopup", nullptr/*, ImGuiWindowFlags_NoDecoration*/)) {
|
||||
const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
|
||||
//const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
|
||||
const auto TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
|
||||
|
||||
preview_image.doAnimation(Message::getTimeMS());
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "./tox_client.hpp"
|
||||
#include "toxcore/tox.h"
|
||||
|
||||
// meh, change this
|
||||
#include <exception>
|
||||
@ -121,10 +120,13 @@ ToxClient::ToxClient(std::string_view save_path, std::string_view save_password)
|
||||
}
|
||||
|
||||
ToxClient::~ToxClient(void) {
|
||||
if (_tox_profile_dirty) {
|
||||
saveToxProfile();
|
||||
}
|
||||
tox_kill(_tox);
|
||||
}
|
||||
|
||||
bool ToxClient::iterate(void) {
|
||||
bool ToxClient::iterate(float time_delta) {
|
||||
Tox_Err_Events_Iterate err_e_it = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
auto* events = tox_events_iterate(_tox, false, &err_e_it);
|
||||
if (err_e_it == TOX_ERR_EVENTS_ITERATE_OK && events != nullptr) {
|
||||
@ -136,7 +138,8 @@ bool ToxClient::iterate(void) {
|
||||
|
||||
tox_events_free(events);
|
||||
|
||||
if (_tox_profile_dirty) {
|
||||
_save_heat -= time_delta;
|
||||
if (_tox_profile_dirty && _save_heat <= 0.f) {
|
||||
saveToxProfile();
|
||||
}
|
||||
|
||||
@ -180,5 +183,6 @@ void ToxClient::saveToxProfile(void) {
|
||||
}
|
||||
|
||||
_tox_profile_dirty = false;
|
||||
_save_heat = 10.f;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
||||
std::string _tox_profile_path;
|
||||
std::string _tox_profile_password;
|
||||
bool _tox_profile_dirty {true}; // set in callbacks
|
||||
float _save_heat {0.f};
|
||||
|
||||
public:
|
||||
//ToxClient(/*const CommandLine& cl*/);
|
||||
@ -34,7 +35,7 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
||||
void setDirty(void) { _tox_profile_dirty = true; }
|
||||
|
||||
// returns false when we shoul stop the program
|
||||
bool iterate(void);
|
||||
bool iterate(float time_delta);
|
||||
void stop(void); // let it know it should exit
|
||||
|
||||
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
||||
|
Reference in New Issue
Block a user