mirror of
https://github.com/zebrajr/SamRewritten.git
synced 2025-12-06 00:19:47 +01:00
Going through some GTK troubles
This commit is contained in:
parent
f396acadd0
commit
8860f59a7e
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
|
@ -8,7 +8,7 @@
|
|||
"name": "(gdb) Launch launcher",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/a.out",
|
||||
"program": "${workspaceFolder}/bin/samrewritten",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
|
|
|||
56
SAM.Picker/MainPickerWindow.cpp
Normal file
56
SAM.Picker/MainPickerWindow.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "MainPickerWindow.h"
|
||||
|
||||
MainPickerWindow::MainPickerWindow()
|
||||
:
|
||||
m_main_window(nullptr),
|
||||
m_game_list(nullptr),
|
||||
m_loading_game_list_box(nullptr)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GtkBuilder *builder = gtk_builder_new();
|
||||
const char ui_file[] = "glade/main_window.glade";
|
||||
gtk_builder_add_from_file (builder, ui_file, &error);
|
||||
|
||||
if(error != NULL) {
|
||||
std::cerr << "An error occurred opening the main window.. Make sure " << ui_file << " exists and is a valid file." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
gtk_builder_connect_signals(builder, NULL);
|
||||
|
||||
m_game_list = GTK_BOX(gtk_builder_get_object(builder, "game_list"));
|
||||
m_main_window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));
|
||||
m_loading_game_list_box = GTK_BOX(gtk_builder_get_object(builder, "loading_game_box"));
|
||||
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
// See https://stackoverflow.com/questions/9192223/remove-gtk-container-children-repopulate-it-then-refresh
|
||||
void MainPickerWindow::reset_game_list() {
|
||||
GList *children, *iter;
|
||||
|
||||
children = gtk_container_get_children(GTK_CONTAINER(m_game_list));
|
||||
|
||||
for(iter = children; iter != NULL; iter = g_list_next(iter))
|
||||
gtk_container_remove(GTK_CONTAINER(m_game_list), GTK_WIDGET(iter->data));
|
||||
|
||||
g_list_free(children);
|
||||
|
||||
//List is cleared, let's readd the spinner
|
||||
|
||||
if(gtk_box_get_center_widget(m_game_list) == NULL) {
|
||||
gtk_box_set_center_widget(GTK_BOX(m_game_list), GTK_WIDGET(m_loading_game_list_box));
|
||||
}
|
||||
else {
|
||||
std::cerr << "There already is a center widget. Cannot add a new one" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void MainPickerWindow::add_to_game_list(const char app_name[]) {
|
||||
GtkWidget *entry = gtk_button_new_with_label(app_name);
|
||||
gtk_box_pack_start(GTK_BOX(m_game_list), entry, FALSE, TRUE, 0);
|
||||
|
||||
//TODO continue here, get the list to display onr item
|
||||
//TODO remove the central widget if there is one
|
||||
g_object_ref(m_loading_game_list_box);
|
||||
}
|
||||
17
SAM.Picker/MainPickerWindow.h
Normal file
17
SAM.Picker/MainPickerWindow.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <iostream>
|
||||
|
||||
class MainPickerWindow {
|
||||
public:
|
||||
MainPickerWindow();
|
||||
void reset_game_list();
|
||||
void add_to_game_list(const char app_name[]);
|
||||
GtkWidget* get_main_window() { return m_main_window; };
|
||||
|
||||
private:
|
||||
GtkWidget *m_main_window;
|
||||
GtkBox *m_game_list;
|
||||
GtkBox *m_loading_game_list_box;
|
||||
};
|
||||
|
|
@ -7,13 +7,12 @@
|
|||
#include "MySteam.h"
|
||||
|
||||
MySteam::MySteam() : m_child_pid(-1) {
|
||||
get_all_owned_games();
|
||||
//Not necessary, going to call it only when neededs
|
||||
//refresh_owned_apps();
|
||||
}
|
||||
|
||||
MySteam::~MySteam() {
|
||||
#ifdef DEBUG
|
||||
puts("MySteam deleted");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
MySteam* MySteam::get_instance() {
|
||||
|
|
@ -69,29 +68,35 @@ bool MySteam::quit_game() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void MySteam::get_all_owned_games() {
|
||||
ISteamApps* steamapps = SteamApps();
|
||||
ISteamAppList* list = SteamAppList();
|
||||
//ISteamUserStats* stats = SteamUserStats();
|
||||
|
||||
AppId_t appid;
|
||||
char name[256];
|
||||
Game_t app;
|
||||
int name_length;
|
||||
/**
|
||||
* This does NOT retrieves all owned games.
|
||||
* It does retrieve all owned games WITH STATS or ACHIEVEMENTS
|
||||
* Stores the owned games in m_all_subscribed_apps
|
||||
* We assume the user didn't put any garbage in his steam folder as well.
|
||||
*/
|
||||
void MySteam::refresh_owned_apps() {
|
||||
const std::string path_to_cache_dir(MySteam::get_steam_install_path() + "/appcache/stats/");
|
||||
DIR* dirp = opendir(path_to_cache_dir.c_str());
|
||||
struct dirent * dp;
|
||||
std::string filename;
|
||||
const std::string prefix("UserGameStats_" + MySteam::get_user_steamId3() + "_");
|
||||
const std::string input_scheme_c(prefix + "%lu.bin");
|
||||
Game_t game;
|
||||
unsigned long app_id;
|
||||
|
||||
m_all_subscribed_apps.clear();
|
||||
for(unsigned long i = 10; i < 10000; i++) {
|
||||
appid = i;
|
||||
if(steamapps->BIsSubscribedApp(appid)) {
|
||||
name_length = list->GetAppName(i, name, 256);
|
||||
if(name_length > 0) {
|
||||
app.app_name = std::string(name);
|
||||
app.app_id = i;
|
||||
app.number_achievements = 1; // TODO put a real value here
|
||||
m_all_subscribed_apps.push_back(app);
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
filename = dp->d_name;
|
||||
if(filename.rfind(prefix, 0) == 0) {
|
||||
if(sscanf(dp->d_name, input_scheme_c.c_str(), &app_id) == 1) {
|
||||
game.app_id = app_id;
|
||||
game.app_name = "To retrieve";
|
||||
m_all_subscribed_apps.push_back(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -101,7 +106,7 @@ void MySteam::get_all_owned_games() {
|
|||
* Returns empty string on error
|
||||
*/
|
||||
std::string MySteam::get_user_steamId3() {
|
||||
static const std::string file_path(std::string(getenv("HOME")) + "/.local/share/Steam/logs/parental_log.txt");
|
||||
static const std::string file_path(MySteam::get_steam_install_path() + "/logs/parental_log.txt");
|
||||
std::ifstream input(file_path, std::ios::in);
|
||||
std::string word;
|
||||
|
||||
|
|
@ -130,13 +135,27 @@ std::string MySteam::get_user_steamId3() {
|
|||
|
||||
input.close();
|
||||
|
||||
std::cerr << "User ID is " << latest_id << std::endl;
|
||||
|
||||
return latest_id;
|
||||
}
|
||||
|
||||
std::string MySteam::get_steam_install_path() {
|
||||
static const std::string home_path(getenv("HOME"));
|
||||
if(file_exists(home_path + "/.local/share/Steam/appcache/appinfo.vdf")) {
|
||||
return std::string(home_path + "/.local/share/Steam");
|
||||
}
|
||||
else if(file_exists(home_path + "/.steam/appcache/appinfo.vdf")) {
|
||||
return std::string(home_path + "/.steam");
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unable to locate the steam directory. TODO: implement a folder picker here" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void MySteam::print_all_owned_games() const {
|
||||
std::cerr << "Summary of owned apps with stats or achievements" << std::endl << "========================" << std::endl;
|
||||
|
||||
for(Game_t i : m_all_subscribed_apps) {
|
||||
std::cerr << "App owned: " << i.app_name << std::endl;
|
||||
std::cerr << i.app_id << " -> " << i.app_name << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <csignal>
|
||||
#include <dirent.h>
|
||||
#include "../common/c_processes.h"
|
||||
#include "Game.h"
|
||||
#include "../steam/steam_api.h"
|
||||
|
|
@ -19,8 +20,10 @@ public:
|
|||
// Below are the most useful methods
|
||||
bool launch_game(std::string appId);
|
||||
bool quit_game();
|
||||
std::string get_user_steamId3();
|
||||
static std::string get_user_steamId3();
|
||||
static std::string get_steam_install_path();
|
||||
void print_all_owned_games() const;
|
||||
void refresh_owned_apps();
|
||||
|
||||
MySteam(MySteam const&) = delete;
|
||||
void operator=(MySteam const&) = delete;
|
||||
|
|
@ -28,8 +31,6 @@ public:
|
|||
private:
|
||||
MySteam();
|
||||
~MySteam();
|
||||
|
||||
void get_all_owned_games();
|
||||
|
||||
pid_t m_child_pid;
|
||||
std::vector<Game_t> m_all_subscribed_apps;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#define DEBUG
|
||||
/**
|
||||
* Please read the license before modifying or distributing any of the code from
|
||||
* this project. Thank you.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -6,10 +9,18 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <gmodule.h>
|
||||
#include "MySteam.h"
|
||||
#include "MainPickerWindow.h"
|
||||
|
||||
int launcher_main();
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
//Globals
|
||||
//Reason for the globals is that it's easier to access
|
||||
//in GTK callbacks
|
||||
MySteam *g_steam = nullptr; // The Model
|
||||
MainPickerWindow *g_main_gui = nullptr; // The view
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if(!g_module_supported()) {
|
||||
std::cerr << "Sorry, but gmodules are not supported on your platform :(. Try installing as many gnome libs as you can maybe.." << std::endl;
|
||||
|
|
@ -17,50 +28,21 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
setenv("SteamAppId", "480", 1);
|
||||
if(!SteamAPI_Init()){
|
||||
std::cerr << std::endl << "Make sure you have launched steam and that you are logged in." << std::endl;
|
||||
|
||||
GError *error = NULL;
|
||||
GtkBuilder *builder = gtk_builder_new();
|
||||
const char ui_file[] = "glade/error_initialize.glade";
|
||||
gtk_builder_add_from_file (builder, ui_file, &error);
|
||||
if(error != NULL) {
|
||||
std::cerr << "You won't believe it, but an error occurred opening the error message's window.. Make sure " << ui_file << " exists and is a valid file." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Will connect "on_close_button_clicked"
|
||||
gtk_builder_connect_signals(builder, NULL);
|
||||
|
||||
GtkWidget *close_button;
|
||||
GtkWidget *popup_window;
|
||||
|
||||
popup_window = GTK_WIDGET(gtk_builder_get_object(builder, "dialog_window"));
|
||||
close_button = GTK_WIDGET(gtk_builder_get_object(builder, "button_close"));
|
||||
|
||||
g_object_unref(builder);
|
||||
|
||||
gtk_widget_show(popup_window);
|
||||
gtk_main();
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
launcher_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int launcher_main() {
|
||||
int
|
||||
launcher_main() {
|
||||
|
||||
MySteam *steam = MySteam::get_instance();
|
||||
steam->print_all_owned_games();
|
||||
g_main_gui = new MainPickerWindow();
|
||||
|
||||
gtk_widget_show(g_main_gui->get_main_window());
|
||||
gtk_main();
|
||||
|
||||
//steam->launch_game("368230");
|
||||
|
||||
//std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
|
||||
//steam->quit_game();
|
||||
|
||||
|
||||
|
|
@ -69,10 +51,34 @@ int launcher_main() {
|
|||
}
|
||||
|
||||
//Gtk Callbacks
|
||||
//Controller
|
||||
extern "C"
|
||||
{
|
||||
// When you click on the close button if steam is not running
|
||||
void on_close_button_clicked () {
|
||||
void
|
||||
on_close_button_clicked() {
|
||||
gtk_main_quit();
|
||||
std::cerr << "Gtk did main quit" << std::endl;
|
||||
delete g_main_gui;
|
||||
g_main_gui = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
on_ask_game_refresh() {
|
||||
std::cerr << "Game refresh started." << std::endl;
|
||||
g_main_gui->reset_game_list();
|
||||
|
||||
//Only call that here so that the constructor is executed when the
|
||||
//window is already showing.
|
||||
g_steam = MySteam::get_instance();
|
||||
g_steam->refresh_owned_apps();
|
||||
|
||||
g_main_gui->add_to_game_list("My Game name");
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
on_main_window_show() {
|
||||
on_ask_game_refresh();
|
||||
}
|
||||
}
|
||||
159
glade/main_window.glade
Normal file
159
glade/main_window.glade
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkPopoverMenu" id="popovermenu">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">About</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Refresh Games</property>
|
||||
<signal name="clicked" handler="on_ask_game_refresh" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">main</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="main_window">
|
||||
<property name="width_request">800</property>
|
||||
<property name="height_request">500</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">face-wink</property>
|
||||
<signal name="action-removed" handler="on_close_button_clicked" swapped="no"/>
|
||||
<signal name="delete-event" handler="on_close_button_clicked" swapped="no"/>
|
||||
<signal name="show" handler="on_main_window_show" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkStack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="game_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkBox" id="loading_game_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSpinner">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="active">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Loading your game library...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page0</property>
|
||||
<property name="title" translatable="yes">page0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="achievements_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="yes">page1</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title">SamRewritten</property>
|
||||
<property name="subtitle">Steam Achievements Manager</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="popover">popovermenu</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">open-menu-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -1,17 +1,7 @@
|
|||
|
||||
|
||||
this._IconDownloader.DownloadDataAsync(
|
||||
new Uri(string.Format("http://media.steamcommunity.com/steamcommunity/public/images/apps/{0}/{1}",
|
||||
this._GameId,
|
||||
info.IsAchieved == true ? info.IconNormal : info.IconLocked)),
|
||||
info);
|
||||
|
||||
|
||||
https://github.com/jshackles/idle_master/blob/master/steam-idle%20Source/steam-idle/Program.cs
|
||||
|
||||
|
||||
Most recent logged in user (useless) from cache:
|
||||
/home/paul/.local/share/Steam/config/loginusers.vdf
|
||||
|
||||
All owned games from cache (WRONG):
|
||||
/home/paul/.local/share/Steam/userdata/<steamid3>/config/localconfig.vdf
|
||||
|
||||
SEE if I cannot get all owned games with stats from /appcache.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user