#include <gtk/gtk.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define MAX_TODO 100
typedef struct Todo{
char text[200];
int completed;
} Todo;
extern Todo todos[MAX_TODO];
extern int todoCount;
static GtkWidget *time_label;
static GtkWidget *cpu_label;
static GtkWidget *weather_label;
static GtkWidget *memo_view;
static GtkWidget *todo_entry;
static GtkWidget *todo_list;
static GtkWidget *status_label;
static void update_time(void);
static gboolean update_cpu(gpointer data);
static void update_todo_list(void);
static void show_status(const char *message);
static void on_add_todo(GtkButton *button, gpointer data);
static void on_complete_todo(GtkButton *button, gpointer data);
static void on_save_memo(GtkButton *button, gpointer data);
static void on_load_memo(GtkButton *button, gpointer data);
static gboolean update_time_timer(gpointerdata){
(void)data;
update_time();
return G_SOURCE_CONTINUE;
}
static void show_status(const char *message){
gtk_label_set_text(GTK_LABEL(status_label), message);
}
static void update_time(void){
time_t now = time(NULL);
struct tm *local = localtime(&now);
char buffer[128];
if(local == NULL){
gtk_label_set_text(
GTK_LABEL(time_label),
"시간을 가져올 수 없습니다."
);
return;
}
snprintf(
buffer, sizeof(buffer),
"%04d-%02d-%02d %02d:%02d:%02d",
local->tm_year + 1900,
local->tm_mon + 1,
local->tm_mday,
local->tm_hour,
local->tm_min,
local->tm_sec
);
gtk_label_set_text(GTK_LABAL(time_label), buffer);
}
static void update_todo_list(void){
Gtk_widget *child;
while((child = gtk_widget_get_first_child(todo_list)) !=
NULL) {
gtk_list_box_remove(GTK_LIST_BOX(todo_list), child);
}
for(int i=0; i<todoCOUNT; i++){
char text[300];
snprintf(
text, sizeof(text),
"%s %s",
todos[i].completed ? "[완료]" : "[미완료]",
todos[i].text
);
GtkWidget *label = gtk_label_new(text);
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
gtk_Widget_set_margin_start(label, 8);
gtk_Widget_set_margin_end(label, 8);
gtk_Widget_set_margin_top(label, 6);
gtk_Widget_set_margin_bottom(label, 6);
gtk_list_box_append(GTK_LIST_BOX(todo_list), label);
}
}
static void on_add_todo(GtkButton *button, gpointer data){
const char *text;
(void)button;
(void)data;
text = gtk_editable_get_text(
GTK_EDITABLE(todo_entry)
);
if(text[0] == '\0'){
show_status("할 일을 입력해 주세요.");
return;
}
if(todoCount >= MAX_TODO){
show_status("Todo 목록이 가득 찼습니다.");
return;
}
snprintf(
todos[todoCount].text,
sizeof(todos[todoCount].text),
"%s", text
);
todos[todoCount].completed = 0;
todoCount++;
gtk_editable_set_text(
GTK_EDITABLE(todo_entry), ""
);
update_todo_list();
show_status("Todo를 추가했습니다.");
}
static void on_complete_todo(
GtkButton *button,
gpointer data
){
GtkListBoxRow *row;
int index;
(void)button;
(void)data;
row = gtk_list_box_get_selected_row(
GTK_LIST_BOX(todo_list)
);
if(row == NULL){
show_status("완료할 Todo를 먼저 선택하세요.");
return;
}
index = gtk_list_box_row_get_index(row);
if(index < 0 || index >= todoCount) {
show_status("잘못된 Todo입니다.");
return;
}
todos[index].completed = 1;
update_todo_list();
show_status("Todo를 완료했습니다.");
}
static void on_save_memo(
GtkButton *button,
gpointer data
){
GtkTextBuffer *buffer;
GtkTextIter start, end;
char *text;
FILE *fp;
(void)button;
(void)data;
buffer = gtk_text_view_get_butter(
GTK_TEXT_VIEW(memo_view)
);
gtk_text_buffer_get_bounds(buffer, &start, &end);
text = gtk_text_buffer_get_text(
buffer, &start, &end, FALSE
);
fp = fopen("memo.text", "w");
if(fp == NULL){
show_status("메모 파일을 저장할 수 없습니다.");
g_free(text);
return;
}
if(fputs(text, fp) == EOF){
fclose(fp);
show_status("메모 저장에 실패했습니다.");
g_free(text);
return;
}
fclose(fp);
g_free(text);
show_status("메모를 저장했습니다.");
}
static void on_load_memo(
GtkButton *button,
gpointer data
){
FILE *fp;
char buffer[1024];
GtkTextBuffer *text_buffer;
(void)button;
(void)data;
fp = fopen("memo.txt", "r");
if(fp == NULL){
show_status("저장된 메모가 없습니다.");
retunr;
}
text_buffer = gtk_text_view_gtkget_buffer(
GTK_TEXT_VIEW(memo_view)
);
gtk_text_buffer_set_text(text_buffer "", 0);
while(fgets(buffer, sizeof(buffer), fp) != NULL){
GtkTextIter end;
gtk_text_buffer_get_end_iter(text_buffer, &end);
gtk_text_buffer_insert(
text_buffer, &end,
buffer, -1
);
}
fclose(fp);
show_status("메모를 불러왔습니다.");
}
static GtkWidget *create_section_title(const char *text){
GtkWidget *label = gtk_label_new(text);
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
gtk_widget_add_css_class(label, "heading");
return label;
}
static void activate(
GtkApplication *app,
gpointer user_data
){
GtkWidget *window;
GtkWidget *root;
GtkWidget *grid;
GtkWidget *time_box;
GtkWidget *system_box;
GtkWidget *todo_box;
GtkWidget *memo_box;
GtkWidget *todo_buttons;
GtkWidget *memo_buttons;
GtkWidget *scrolled;
GtkWidget *button;
(void)user_data;
window = gtk_application_window_new(app);
gtk_window_set_title(
GTK_WINDOW(window), "PC Dashboard"
);
gtk_window_set_default_size(
GRK_WINDOW(window), 850, 600
);
root = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_margin_top(root, 18);
gtk_widget_set_margin_bottom(root, 18);
gtk_widget_set_margin_start(root, 18);
gtk_widget_set_margin_end(root, 18);
gtk_widget_set_child(GTK_WINDOW(window), root);
GtkWidget *title = gtk_label_new("PC Dashboard");
gtk_widget_add_css_class(title, "title-1");
gtk_label_set_xalign(GTK_LABEL(title), 0.0f);
gtk_box_append(GTK_BOX(root), title);
grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 8);
gtk_grid_set_column_spacing(GTK_GRID(grid), 24);
gtk_box_append(GTK_BOX(root), grid);
time_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
system = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_grid_attach(GTK_GRID(grid), time_box, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), system_box, 1, 0, 1, 1);
gtk_box_append(
GTK_BOX(time_box),
create_section_title("현재 시간")
);
time_label = gtk_label_new("");
gtk_label_set_xalign(GTK_LABEL(time_label), 0.0f);
gtk_box_append(GTK_BOX(time_box), time_label);
gtk_box_append(
GTK_BOX(system_box),
create_section_title("CPU 사용률")
);
cpu_label = gtk_label_new("측정중...");
gtk_label_set_xalign(GTK_LABEL(cpu_label), 0.0f);
gtk_box_append(GTK_BOX(system_box), cpu_label);
weather_label = gtk_label_new(
"서울ㆍ맑음ㆍ22℃습도 45%\n"
"테스트 데이터"
);
gtk_label_set_xalign(GTK_LABEL(weather_label), 0.0f);
gtk_box_append(
GTK_BOX(system_box), weather_label
);
grid = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(grid), 16);
gtk_grid_set_column_spacing(GTK_GRID(grid), 20);
gtk_widget_set_vexpand(grid, TRUE);
gtk_box_append(GTK_BOX(root), grid);
todo_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
gtk_widget_set_hexpand(todo_box, TRUE);
gtk_widget_set_vexpand(todo_box, TRUE);
gtk_grid_attach(GTK_GRID(grid), todo_box, 0, 0, 1, 1);
gtk_box_append(
GTK_BOX(todo_box),
create_section_title("Todo List")
);
todo_entry = gtk_entry_new();
gtk_entry_set_placeholder_text(
GTK_ENTRY(todo_entry), "할 일을 입력하세요"
);
gtk_box_append(GTK_BOX(todo_box), todo_entry);
button = gtk_button_new_with_label("Todo 추가");
g_signal_connect(
button, "clicked",
G_CALLBACK(on_add_todo), NULL
);
gtk_box_append(GTK_BOX(todo_box), button);
scrolled = gtk_scrolled_window_new();
gtk_widget_set_vewpand(scrolled, TRUE);
todo_list = gtk_list_box_new();
gtk_list_box_set_selection_mode(
GTK_LIST_BOX(todo_list),
GTK_SELECTION_SINGLE
);
gtk_scrolled_window_set_child(
GTK_SCROLLED_WINDOW(scrolled), todo_list
);
gtk_box_append(GTK_BOX(todo_box), scrolled);
button = gtk_button_new_with_label("선택한 Todo완료");
g_signal_connect(
button, "clicked",
G_CALLBACK(on_complete_todo), NULL
);
gtk_box_append(GTK_BOX(todo_box), button);
memo_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
gtk_widget_set_hexpand(memo_box, TRUE);
gtk_widget_set_vexpand(memo_box, TRUE);
gtk_grid_attach(GTK_GRID(grid), memo_box, 1, 0, 1, 1);
scrolled = gtk_scrolled_window_new();//
gtk_widget_set_vexpand(scrolled, TRUE);
memo_view = gtk_text_view_new();
gtk_text_view_set_wrap_mode(
GTK_TEXT_VIEW(memo_view),
GTK_WRAP_WORD_CHAR
);
gtk_scrolled_window_set_child(
GTK_SCROLLED_WINDOW(scrolled), memo_view
);
gtk_box_append(GTK_BOX(memo_box), scrolled);
memo_buttons = gtk_box_new(GTK_ORIENTATION_HRIZONTAL, 8);
gtk_box_append(GTK_BOX(memo_box), memo_buttons);
button = gtk_button_new_with_label("메모 저장");
g_signal_connect(
button, "clicked",
G_CALLBACK(on_save_memo), NULL
);
gtk_box_append(GTK_BOX(memo_buttons), button);
button = gtk_button_new_with_label("메모 불러오기");
g_signal_conect(
button, "clicked",
G_CALLBACK(on_load_memo), NULL
);
gtk_box_append(GTK_BOX(memo_buttons), button);
status_label = gtk_label_new("준비되었습니다.");
gtk_label_set_xalign(GTK_LABEL(status_label), 0.0f);
gtk_box_append(GTK_BOX(root), status_label);
update_time();
update_todo_list();
g_timeout_add_seconds(1, update_timer, NULL);
//g_timeout_add_seconds(1, update_cpu, NULL);
gtk_window_present(GTK_WINDOW(window));
}
int main(int argc, char**argv){
GTKApplication *app;
int status;
app = gtk_application_new(
"com.example.pcdashboard",
G_APPLICATION_DEFAULT_FLAGC
);
g_signal_connect(
app, "activate",
G_CALLBACK(activate), NULL
);
status = g_application_run(
G_APPLICATION(app), argc, argv
);
g_object_unref(app);
return status;
}
To embed this project on your website, copy the following code and paste it into your website's HTML: