From 3e25ed94fc09e9942986a181dd2c93cb17071ef2 Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Wed, 17 Apr 2024 17:40:56 -0500 Subject: [PATCH] start getting the slack api setup --- flake.nix | 1 + justfile | 10 +++--- src/compile_flags.txt | 1 + src/main.c | 71 ++++++++++++++++++++++++++++++-------- src/slack_api.h | 79 +++++++++++++++++++++++++++++++++++++++++++ src/ui.h | 56 +++++++++++++++++++++++++----- 6 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 src/slack_api.h diff --git a/flake.nix b/flake.nix index 226bfac..7a28ac2 100755 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,7 @@ buildInputs = with pkgs; (if pkgs.system == "aarch64-darwin" || pkgs.system == "x86_64-darwin" then [ pkg-config binutils + curlMinimal clang bear naga-cli diff --git a/justfile b/justfile index 0200dfa..b763d78 100644 --- a/justfile +++ b/justfile @@ -3,13 +3,13 @@ alias r := run build: transpile_shaders_metal mkdir -p bin - cc -Ivendor/ -O0 -g -Wall -Wextra -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC src/*.c -o bin/an_editor - # cc -Ivendor/ -g -Wall -Wextra src/*.c -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor - # cc bin/*.o -o bin/an_editor -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor + cc -Ivendor/ -O0 -g -Wall -Wextra $(curl-config --libs) -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC src/*.c -o bin/chat_client + # cc -Ivendor/ -g -Wall -Wextra src/*.c -o bin/chat_client -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor + # cc bin/*.o -o bin/chat_client -lEGL -lGLESv2 -lGL -lm -lX11 -lXi -lXcursor run: build - # nixGLIntel ./bin/an_editor - ./bin/an_editor + # nixGLIntel ./bin/chat_client + ./bin/chat_client transpile_shaders_metal: mkdir -p bin/transpiled_shaders diff --git a/src/compile_flags.txt b/src/compile_flags.txt index b77fb74..b22c704 100644 --- a/src/compile_flags.txt +++ b/src/compile_flags.txt @@ -4,5 +4,6 @@ -DED_GFX_IMPLEMENTATION -DED_BUFFER_IMPLEMENTATION -DED_FILE_IO_IMPLEMENTATION +-DCHAT_SLACK_IMPLEMENTATION -I../vendor/ -ObjC diff --git a/src/main.c b/src/main.c index c0bf883..c773044 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -13,10 +14,12 @@ #define ED_UI_IMPLEMENTATION #define ED_BUFFER_IMPLEMENTATION #define ED_FILE_IO_IMPLEMENTATION +#define CHAT_SLACK_IMPLEMENTATION #include "ed_array.h" #include "file_io.h" #include "gfx.h" #include "ht.h" +#include "slack_api.h" #include "string.h" #include "ui.h" @@ -33,6 +36,8 @@ void *context_alloc(size_t size) { static struct { bool should_exit; + bool show_thing; + ui_context ui_cx; gfx_context_t *gfx_cx; } state; @@ -133,8 +138,12 @@ void ed_frame(int mouse_x, int mouse_y, bool mouse_left_down, snprintf(buffer, 256, "Mouse X: %d, Mouse Y: %d, Mouse %s", mouse_x, mouse_y, mouse_left_down ? "Down" : "Up"); - render_ui_rect((float[2]){mouse_x, mouse_y}, (float[2]){32, 32}, - (float[4]){1, 1, 1, 1}); + ui_update_input(&state.ui_cx, (ui_context_input){ + .mouse_x = mouse_x, + .mouse_y = mouse_y, + .mouse_left_down = mouse_left_down, + .mouse_right_down = mouse_right_down, + }); ui_element(&state.ui_cx, _String("channel sidebar"), UI_AXIS_VERTICAL, ui_make_size(ui_children_sum, ui_fill), UI_FLAG_DRAW_BACKGROUND); @@ -144,12 +153,43 @@ void ed_frame(int mouse_x, int mouse_y, bool mouse_left_down, ui_make_size(ui_fit_text, ui_fit_text), UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_TEXT); - ui_element(&state.ui_cx, _String("#dev-general"), UI_AXIS_HORIZONTAL, - ui_make_size(ui_fit_text, ui_fit_text), - UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_TEXT); - ui_element(&state.ui_cx, _String("#dev-help"), UI_AXIS_HORIZONTAL, - ui_make_size(ui_fit_text, ui_fit_text), - UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_TEXT); + if (ui_button(&state.ui_cx, _String("#dev-general")).clicked) { + printf("you clicked the dev-general button\n"); + state.show_thing = !state.show_thing; + } + if (ui_button(&state.ui_cx, _String("#dev-help")).clicked) { + printf("you clicked the dev-help button\n"); + } + + if (state.show_thing) { + ui_interaction interaction = _ui_test_interaction( + &state.ui_cx, + ui_element(&state.ui_cx, _String("thread list"), + UI_AXIS_VERTICAL, + ui_make_size(ui_children_sum, ui_children_sum), + UI_FLAG_DRAW_BACKGROUND)); + + ui_push_parent(&state.ui_cx); + ui_element(&state.ui_cx, _String("List of Threads"), + UI_AXIS_VERTICAL, ui_make_size(ui_fit_text, ui_fit_text), + UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_TEXT | + UI_FLAG_HOVERABLE); + if (interaction.hovering) { + if (ui_button(&state.ui_cx, _String("Thread 1")).clicked) { + printf("thread 1\n"); + } + if (ui_button(&state.ui_cx, _String("Thread 2")).clicked) { + printf("thread 2\n"); + } + if (ui_button(&state.ui_cx, _String("Thread 3")).clicked) { + printf("thread 3\n"); + } + if (ui_button(&state.ui_cx, _String("Thread 4")).clicked) { + printf("thread 4\n"); + } + } + ui_pop_parent(&state.ui_cx); + } } ui_pop_parent(&state.ui_cx); @@ -158,16 +198,17 @@ void ed_frame(int mouse_x, int mouse_y, bool mouse_left_down, ui_update_cache(&state.ui_cx, 0); ui_prune(&state.ui_cx); - - ui_update_input(&state.ui_cx, (ui_context_input){ - .mouse_x = mouse_x, - .mouse_y = mouse_y, - .mouse_left_down = false, - .mouse_right_down = false, - }); } int main(int argc, char *argv[]) { + curl_global_init(CURL_GLOBAL_ALL); + + slack_client client = slack_init_client(); + _slack_debug_print_auth_test(&client); + + curl_global_cleanup(); + return 0; + ed_init(ed_frame); while (keep_running) { diff --git a/src/slack_api.h b/src/slack_api.h new file mode 100644 index 0000000..a0a32d9 --- /dev/null +++ b/src/slack_api.h @@ -0,0 +1,79 @@ +// Slack API Interface + +#ifndef CHAT_SLACK_INCLUDED +#define CHAT_SLACK_INCLUDED +#include + +#include "ed_array.h" +#include "string.h" + +typedef struct { + CURL *curl; +} slack_client; + +void _slack_debug_print_auth_test(slack_client *client); + +slack_client slack_init_client(); + +#ifdef CHAT_SLACK_IMPLEMENTATION + +static size_t write_memory_callback(void *contents, size_t size, size_t nmemb, + void *userp) { + size_t real_size = size * nmemb; + pushArrayMulti(uint8_t, userp, contents, real_size); + return real_size; +} + +void _slack_debug_print_auth_test(slack_client *client, string token, + string cookie) { + if (client->curl) { + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json"); + // headers = curl_slist_append(headers, cookie); + + curl_easy_setopt(client->curl, CURLOPT_URL, + "https://slack.com/api/auth.test"); + + curl_easy_setopt(client->curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BEARER); + // curl_easy_setopt(client->curl, CURLOPT_XOAUTH2_BEARER, token); + curl_easy_setopt(client->curl, CURLOPT_USERAGENT, + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; " + "rv:76.0) Gecko/20100101 Firefox/76.0"); + curl_easy_setopt(client->curl, CURLOPT_HTTPHEADER, headers); + + curl_easy_setopt(client->curl, CURLOPT_POST, 1L); + curl_easy_setopt(client->curl, CURLOPT_POSTFIELDS, "{}"); + + curl_easy_setopt(client->curl, CURLOPT_FOLLOWLOCATION, 1L); + + array(uint8_t) chunk = newArray(uint8_t, 10000); + + curl_easy_setopt(client->curl, CURLOPT_WRITEFUNCTION, + write_memory_callback); + curl_easy_setopt(client->curl, CURLOPT_WRITEDATA, (void *)&chunk); + + /* Perform the request, res gets the return code */ + CURLcode res = curl_easy_perform(client->curl); + /* Check for errors */ + if (res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + + } else { + fprintf(stderr, "Got data\n%.*s\n", (int)chunk.size, chunk.data); + } + + free(chunk.data); + } +} + +slack_client slack_init_client(string token, string cookie) { + CURL *curl = curl_easy_init(); + + slack_client client = (slack_client){.curl = curl}; + + return client; +} + +#endif +#endif diff --git a/src/ui.h b/src/ui.h index b10df27..23d7a21 100644 --- a/src/ui.h +++ b/src/ui.h @@ -136,6 +136,9 @@ typedef struct { void ui_compute_layout(ui_context *cx, size_t element_index); +ui_interaction _ui_test_interaction(ui_context *cx, size_t element_index); +ui_interaction ui_button(ui_context *cx, string label); + #ifdef ED_UI_IMPLEMENTATION ui_context ui_init_context() { @@ -235,6 +238,35 @@ size_t ui_element(ui_context *cx, string label, ui_axis axis, return frame_data.index; } +ui_interaction _ui_test_interaction(ui_context *cx, size_t element_index) { + bool hovering = false; + bool mouse_is_clicked = + cx->last_input.mouse_left_down && !cx->input.mouse_left_down; + + ui_element_frame_data *elm = _elm(element_index); + + if ((cx->input.mouse_x >= elm->size.computed_pos[0] && + cx->input.mouse_x < + elm->size.computed_pos[0] + elm->size.computed_size[0]) && + cx->input.mouse_y >= elm->size.computed_pos[1] && + cx->input.mouse_y < + elm->size.computed_pos[1] + elm->size.computed_size[1]) { + hovering = true; + } + + return (ui_interaction){.hovering = hovering, + .clicked = hovering && mouse_is_clicked}; +} + +ui_interaction ui_button(ui_context *cx, string label) { + size_t id = ui_element(cx, label, UI_AXIS_HORIZONTAL, + ui_make_size(ui_fit_text, ui_fit_text), + UI_FLAG_DRAW_BACKGROUND | UI_FLAG_DRAW_TEXT | + UI_FLAG_HOVERABLE | UI_FLAG_CLICKABLE); + + return _ui_test_interaction(cx, id); +} + static uint32_t _ui_ancestor_size(ui_context *cx, size_t element_index, ui_axis axis) { if (element_index == SIZE_MAX || _parent(element_index) == SIZE_MAX) { @@ -292,10 +324,11 @@ static void _ui_compute_children_layout(ui_context *cx, ui_element_frame_data *elm) { uint32_t child_size[2] = {0, 0}; - // NOTE: the number of fills for the opposite axis of this box needs to be 1 - // because it will never get incremented in the loop below and cause a - // divide by zero and the number of fills for the axis of the box needs to - // start at zero or else it will be n+1 causing incorrect sizes + // NOTE: the number of fills for the opposite axis of this box needs to + // be 1 because it will never get incremented in the loop below and + // cause a divide by zero and the number of fills for the axis of the + // box needs to start at zero or else it will be n+1 causing incorrect + // sizes uint32_t num_fills[2] = {1, 1}; num_fills[elm->size.axis] = 0; @@ -476,11 +509,16 @@ void ui_render(ui_context *cx, _ui_render_text_func text_func, } if (_flags(i, UI_FLAG_DRAW_BACKGROUND)) { + float c = _ui_test_interaction(cx, i).hovering && + _flags(i, UI_FLAG_HOVERABLE) + ? 0.8 + : 0.2; + rect_func((float[]){(float)elm->size.computed_pos[0], (float)elm->size.computed_pos[1]}, (float[]){(float)elm->size.computed_size[0], (float)elm->size.computed_size[1]}, - (float[]){1, 1, 1, 0.2}); + (float[]){c, c, c, 1.0}); } } } @@ -490,13 +528,13 @@ void ui_prune(ui_context *cx) { if (cx->cached_elements.key_slots[i].key.data != NULL) { string key = cx->cached_elements.key_slots[i].key; - // if this element hasn't been created in the past 5 frames, remove - // it + // if this element hasn't been created in the past 5 frames, + // remove it ui_element_cache_data *cached = ht_get(&cx->cached_elements, key); if (cached && cached->last_instantiated_index < cx->frame_index - 5) { - // fprintf(stderr, "removing %.*s from cache, cache index: %zu, - // frame index: %zu\n", (int)key.len, key.data, + // fprintf(stderr, "removing %.*s from cache, cache index: + // %zu, frame index: %zu\n", (int)key.len, key.data, // cached->last_instantiated_index, cx->frame_index); ht_remove(&cx->cached_elements, key);