Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Activity Tracker with theme support, add functionality to delete entries #1430

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions src/common/components/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
#include "utils/str.h"

#define MAX_NUM_VALUES 100
#define SCROLL_ACCELERATION_THRESHOLD 10
#define SCROLL_ACCELLERATION_MAX_SPEED 4

typedef enum list_type { LIST_SMALL,
LIST_LARGE } ListType;
typedef enum item_type { ACTION,
TOGGLE,
MULTIVALUE } ListItemType;
MULTIVALUE,
PLAYACTIVITY } ListItemType;

typedef struct ListItem {
int _id;
Expand Down Expand Up @@ -206,17 +209,37 @@ bool list_scrollTo(List *list, int active_pos)

bool list_keyUp(List *list, bool key_repeat)
{
static int key_hold_duration = 0;
static int scroll_speed = 1;

if (key_repeat && list->active_pos == 0)
return false;

int old_pos = list->active_pos;

if (key_repeat) {
key_hold_duration++;
if (scroll_speed < SCROLL_ACCELLERATION_MAX_SPEED && key_hold_duration % SCROLL_ACCELERATION_THRESHOLD == 0)
printf("scroll_speed: %d\n", ++scroll_speed);
}
else {
key_hold_duration = 0;
scroll_speed = 1;
}

// Wrap-around (move to bottom)
if (list->active_pos == 0) {
if (key_repeat)
return false;
list->active_pos = list->item_count - 1;
}
// Decrease selection (move up)
else
list->active_pos -= 1;
else if (list->active_pos - scroll_speed >= 0) {
list->active_pos -= scroll_speed;
}
else {
list->active_pos = 0;
}

list_ensureVisible(list, -1);

Expand All @@ -238,17 +261,33 @@ bool list_keyUp(List *list, bool key_repeat)

bool list_keyDown(List *list, bool key_repeat)
{
static int key_hold_duration = 0;
static int scroll_speed = 1;

int old_pos = list->active_pos;

if (key_repeat) {
if (scroll_speed < SCROLL_ACCELLERATION_MAX_SPEED && ++key_hold_duration % SCROLL_ACCELERATION_THRESHOLD == 0)
printf("scroll_speed: %d\n", ++scroll_speed);
}
else {
key_hold_duration = 0;
scroll_speed = 1;
}

// Wrap-around (move to top)
if (list->active_pos == list->item_count - 1) {
if (key_repeat)
return false;
list->active_pos = 0;
}
// Increase selection (move down)
else
list->active_pos += 1;
else if (list->active_pos + scroll_speed < list->item_count) {
list->active_pos += scroll_speed;
}
else {
list->active_pos = list->item_count - 1;
}

list_ensureVisible(list, 1);

Expand Down Expand Up @@ -412,13 +451,18 @@ void list_getItemValueLabel(ListItem *item, char *out_label)
sprintf(out_label, "%d", item->value);
}

void list_free(List *list)
//
// Free list resources
// icon_ptr_keep: pointer to a surface that should not be freed
// in case of multiple list entries sharing the surface
//
void list_free(List *list, SDL_Surface *icon_ptr_keep)
{
if (!list->_created)
return;
for (int i = 0; i < list->item_count; i++) {
ListItem *item = &list->items[i];
if (item->icon_ptr != NULL)
if (item->icon_ptr && item->icon_ptr != icon_ptr_keep)
SDL_FreeSurface((SDL_Surface *)item->icon_ptr);
if (item->preview_ptr != NULL)
SDL_FreeSurface((SDL_Surface *)item->preview_ptr);
Expand Down
26 changes: 25 additions & 1 deletion src/common/theme/render/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,30 @@ void theme_renderList(SDL_Surface *screen, List *list)
static int multivalue_width = 226;
int label_end = 640;
int offset_x = 20;
SDL_Color description_color = theme()->grid.color;

if (item->item_type == PLAYACTIVITY) {
static int digit_width = 0;
if (digit_width == 0) {
char *tmp_str = "7"; // our font is monospace, but others?
SDL_Surface *sdl_tmp = TTF_RenderUTF8_Blended(list_font, tmp_str, theme()->list.color);
digit_width = sdl_tmp->w;
SDL_FreeSurface(sdl_tmp);
}
char index_str[STR_MAX];
snprintf(index_str, STR_MAX, "%d", i + 1);
offset_x += 10 + strlen(index_str) * digit_width;

SDL_Surface *index_label = TTF_RenderUTF8_Blended(list_font, index_str, theme()->list.color);
SDL_Rect index_pos = {digit_width, item_bg_rect.y + index_label->h};
SDL_BlitSurface(index_label, NULL, screen, &index_pos);
SDL_FreeSurface(index_label);

label_end = RENDER_WIDTH - 80 - strlen(index_str) * digit_width; // less space as number grows
label_y = 30; // give the description more space
if (list->active_pos == i)
description_color = theme()->title.color; // make the selected item's description pop
}

if (item->icon_ptr != NULL) {
SDL_Surface *icon = (SDL_Surface *)item->icon_ptr;
Expand Down Expand Up @@ -152,7 +176,7 @@ void theme_renderList(SDL_Surface *screen, List *list)

if (!list_small && strlen(item->description)) {
theme_renderListLabel(
screen, item->description, theme()->grid.color, offset_x,
screen, item->description, description_color, offset_x,
item_bg_rect.y + 62, list->active_pos == i, label_end, show_disabled);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/common/utils/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ char *extractPath(const char *absolutePath)

void file_cleanName(char *name_out, const char *file_name)
{
char *name_without_ext = file_removeExtension(strdup(file_name));
char *_dup = strdup(file_name);
char *name_without_ext = file_removeExtension(_dup);
free(_dup);
char *no_underscores = str_replace(name_without_ext, "_", " ");
char *dot_ptr = strstr(no_underscores, ".");
if (dot_ptr != NULL) {
Expand Down
43 changes: 43 additions & 0 deletions src/common/utils/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef TIMER_H__
#define TIMER_H__

#include <stdio.h>
#include <sys/time.h>

#ifdef LOG_DEBUG

#define START_TIMER(struct_name) \
struct timeval struct_name##_before, struct_name##_after, struct_name##_result; \
gettimeofday(&struct_name##_before, NULL);

#define END_TIMER(struct_name) \
gettimeofday(&struct_name##_after, NULL); \
timersub(&struct_name##_after, &struct_name##_before, &struct_name##_result); \
long struct_name##_milliseconds = struct_name##_result.tv_sec * 1000 + struct_name##_result.tv_usec / 1000; \
printf("\033[1;33m%s: %ld milliseconds\033[0m\n", #struct_name, struct_name##_milliseconds);

#else

#define START_TIMER(struct_name)
#define END_TIMER(struct_name)

#endif

#endif

/*
* Usage:
*
* #include "timer.h"
*
* int main() {
* START_TIMER(loading);
* some_loading_function();
* END_TIMER(loading);
* return 0;
* }
*
* Output:
*
* loading: 123 milliseconds
*/
69 changes: 54 additions & 15 deletions src/playActivity/playActivityDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void play_activity_db_open(void)
if (!play_activity_db_created) {
sqlite3_exec(play_activity_db,
"DROP TABLE IF EXISTS rom;"
"CREATE TABLE rom(id INTEGER PRIMARY KEY, type TEXT, name TEXT, file_path TEXT, image_path TEXT, created_at INTEGER DEFAULT (strftime('%s', 'now')), updated_at INTEGER);"
"CREATE TABLE rom(id INTEGER PRIMARY KEY, type TEXT, name TEXT, file_path TEXT, image_path TEXT, created_at INTEGER DEFAULT (strftime('%s', 'now')), updated_at INTEGER, deletion_id INTEGER DEFAULT 0);"
"CREATE UNIQUE INDEX rom_id_index ON rom(id);",
NULL, NULL, NULL);
sqlite3_exec(play_activity_db,
Expand Down Expand Up @@ -135,21 +135,33 @@ int play_activity_get_total_play_time(void)
return total_play_time;
}

PlayActivities *play_activity_find_all(void)
PlayActivities *play_activity_find_all(bool include_hidden)
{
PlayActivities *play_activities = NULL;
char *sql =
"SELECT * FROM ("
" SELECT rom.id, rom.type, rom.name, rom.file_path, rom.image_path, "
" COUNT(play_activity.ROWID) AS play_count_total, "
" SUM(play_activity.play_time) AS play_time_total, "
" SUM(play_activity.play_time)/COUNT(play_activity.ROWID) AS play_time_average, "
" datetime(MIN(play_activity.created_at), 'unixepoch') AS first_played_at, "
" datetime(MAX(play_activity.created_at), 'unixepoch') AS last_played_at "
" FROM rom LEFT JOIN play_activity ON rom.id = play_activity.rom_id "
" GROUP BY rom.id) "
"WHERE play_time_total > 60 "
"ORDER BY play_time_total DESC;";
char *sql = include_hidden
? "SELECT * FROM ("
" SELECT rom.id, rom.type, rom.name, rom.file_path, rom.image_path, "
" COUNT(play_activity.ROWID) AS play_count_total, "
" SUM(play_activity.play_time) AS play_time_total, "
" SUM(play_activity.play_time)/COUNT(play_activity.ROWID) AS play_time_average, "
" datetime(MIN(play_activity.created_at), 'unixepoch') AS first_played_at, "
" datetime(MAX(play_activity.created_at), 'unixepoch') AS last_played_at "
" FROM rom LEFT JOIN play_activity ON rom.id = play_activity.rom_id "
" GROUP BY rom.id) "
"WHERE play_time_total > 60 "
"ORDER BY play_time_total DESC;"
: "SELECT * FROM ("
" SELECT rom.id, rom.type, rom.name, rom.file_path, rom.image_path, "
" COUNT(play_activity.ROWID) AS play_count_total, "
" SUM(play_activity.play_time) AS play_time_total, "
" SUM(play_activity.play_time)/COUNT(play_activity.ROWID) AS play_time_average, "
" datetime(MIN(play_activity.created_at), 'unixepoch') AS first_played_at, "
" datetime(MAX(play_activity.created_at), 'unixepoch') AS last_played_at "
" FROM rom LEFT JOIN play_activity ON rom.id = play_activity.rom_id "
" WHERE (rom.deletion_id IS NULL OR play_activity.rowid > rom.deletion_id)"
" GROUP BY rom.id) "
"WHERE play_time_total > 60 "
"ORDER BY play_time_total DESC;";
sqlite3_stmt *stmt;

play_activity_db_open();
Expand Down Expand Up @@ -206,7 +218,13 @@ PlayActivities *play_activity_find_all(void)
void free_play_activities(PlayActivities *pa_ptr)
{
for (int i = 0; i < pa_ptr->count; i++) {
free(pa_ptr->play_activity[i]->rom->image_path);
free(pa_ptr->play_activity[i]->rom->name);
free(pa_ptr->play_activity[i]->rom->type);
free(pa_ptr->play_activity[i]->rom->file_path);
free(pa_ptr->play_activity[i]->rom);
free(pa_ptr->play_activity[i]->first_played_at);
free(pa_ptr->play_activity[i]->last_played_at);
free(pa_ptr->play_activity[i]);
}
free(pa_ptr->play_activity);
Expand Down Expand Up @@ -516,7 +534,7 @@ void play_activity_list_all(void)
{
print_debug("\n:: play_activity_list_all()");
int total_play_time = play_activity_get_total_play_time();
PlayActivities *pas = play_activity_find_all();
PlayActivities *pas = play_activity_find_all(true);

printf("\n");

Expand All @@ -537,4 +555,25 @@ void play_activity_list_all(void)
free_play_activities(pas);
}

void play_activity_hide(int rom_id)
{
print_debug("\n:: play_activity_hide()");
sqlite3_stmt *stmt;
int deletion_id = -1;

// get highest play_activity.rowid for given rom_id
char *sql = sqlite3_mprintf("SELECT MAX(ROWID) FROM play_activity WHERE rom_id = %d", rom_id);

play_activity_db_open();
stmt = play_activity_db_prepare(sql);

if (sqlite3_step(stmt) == SQLITE_ROW)
deletion_id = sqlite3_column_int(stmt, 0);

sqlite3_finalize(stmt);
play_activity_db_close();

// update rom deletion_id
play_activity_db_execute(sqlite3_mprintf("UPDATE rom SET deletion_id = %d WHERE id = %d;", deletion_id, rom_id));
}
#endif // PLAY_ACTIVITY_DB_H
3 changes: 2 additions & 1 deletion src/playActivityUI/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
INCLUDE_CJSON=1
include ../common/config.mk

TARGET = playActivityUI
LDFLAGS := $(LDFLAGS) -lSDL -lSDL_image -lSDL_ttf -lsqlite3
LDFLAGS := $(LDFLAGS) -lSDL -lSDL_ttf -lSDL_image -lSDL_mixer -lSDL_rotozoom -lsqlite3

include ../common/commands.mk
include ../common/recipes.mk
Loading
Loading