summaryrefslogtreecommitdiff
path: root/src/main.c
blob: e9d22f10778ef663698a9dbd25a76c5c96d3df1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <curl/curl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTEX_BUFFER 512 * 1024
#define MAX_ELEMENT_BUFFER 128 * 1024
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_IMPLEMENTATION
#define NK_GLFW_GL3_IMPLEMENTATION
#define NK_KEYSTATE_BASED_INPUT
#include "nuklear.h"
#include "nuklear_glfw_gl3.h"

#include "constants.h"
#include "logger.h"
#include "main.h"
#include "process_url.h"
#include "style.h"
#include "ui.h"
#include "unifont.h"

extern int win_width, win_height;
extern void load_ui(struct ui_struct *);
static void error_callback(int e, const char *d) {
  printf("Error %d: %s\n", e, d);
}

int main(void) {
  struct ui_struct ui;

  /* Set locale*/
  setlocale(LC_ALL, ".UTF-8");

  /* Curl */
  curl_init();

  /* GLFW */
  struct nk_glfw glfw = {0};
  static GLFWwindow *win;
  glfwSetErrorCallback(error_callback);
  if (!glfwInit()) {
    fprintf(stdout, "[GFLW] failed to init!\n");
    exit(EXIT_FAILURE);
  }
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

  win = glfwCreateWindow(win_width, win_height, APP_NAME, NULL, NULL);

  if (!win) {
    // Window creation failed
    fprintf(stdout, "[GLFW] failed to create window. Does this platform "
                    "support OpenGL 3.3+?\n");
    printf("GL_VERSION_3_3: %s",
           glewIsSupported("GL_VERSION_3_3") ? "yes" : "no");
    exit(EXIT_FAILURE);
  }

  glfwMakeContextCurrent(win);

  /* Glew */
  glewExperimental = GL_TRUE;
  GLenum err;
  if ((err = glewInit()) != GLEW_OK) {
    /* Problem: glewInit failed, something is seriously wrong. */
    fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    exit(EXIT_FAILURE);
  }

  /* Logger setup */
  struct logger *logger = setup_logger();
  // Put it in ui_struct
  ui.logger = logger;

  /* UI stat */
  status_t stat = {0};
  stat.is_done = true;
  ui.stat = &stat;

  /* create context */
  ui.ctx = nk_glfw3_init(&glfw, win, NK_GLFW3_INSTALL_CALLBACKS);

  /* Font */
  ui.logger->font_height = 24;
  {
    struct nk_font_atlas *atlas;
    struct nk_font_config cfg = nk_font_config(0);
    /* NOTICE: Some CJK fonts may have incorrect glyph indexes.
      https://github.com/Immediate-Mode-UI/Nuklear/issues/399
      https://github.com/Immediate-Mode-UI/Nuklear/issues/542
      FIX: https://github.com/Immediate-Mode-UI/Nuklear/pull/531
     */
    cfg.range = nk_font_chinese_glyph_ranges();
    // const nk_rune ranges[] = {0x4E00, 0x9FAF, 0x0020, 0x00FF, 0x3000,
    //                           0x30FF, 0x31F0, 0x31FF, 0xFF00, 0xFFEF,
    //
    //                           0};
    // cfg.range = ranges;
    cfg.oversample_h = 1;
    cfg.oversample_v = 1;
    nk_glfw3_font_stash_begin(&glfw, &atlas);
    atlas->default_font = nk_font_atlas_add_compressed_base85(
        atlas, unifont_compressed_data_base85, ui.logger->font_height, &cfg);
    nk_glfw3_font_stash_end(&glfw);
  }

  /* TextEdit */
  struct nk_text_edit text_edit;
  nk_textedit_init_default(&text_edit);

  logger->text_edit = &text_edit;

  /* Scrollbar */
  struct nk_scroll scrollbar = {0};
  logger->scrollbar = &scrollbar;

  /* Theming */
  set_style(ui.ctx, THEME_DARK);

  while (!glfwWindowShouldClose(win)) {
    /* Input */
    glfwPollEvents();
    nk_glfw3_new_frame(&glfw);

    /* Response to window resize */
    glfwGetWindowSize(win, &win_width, &win_height);
    nk_window_set_bounds(ui.ctx, APP_NAME,
                         nk_rect(0, 0, win_width, win_height));

    /* GUI */
    if (nk_begin(ui.ctx, APP_NAME, nk_rect(0, 0, win_width, win_height),
                 NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE)) {
      load_ui(&ui);
    }
    nk_end(ui.ctx);

    /* Draw */
    glfwGetWindowSize(win, &win_width, &win_height);
    glViewport(0, 0, win_width, win_height);
    glClear(GL_COLOR_BUFFER_BIT);
    nk_glfw3_render(&glfw, NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER,
                    MAX_ELEMENT_BUFFER);
    glfwSwapBuffers(win);
  }
  curl_cleanup(&stat);
  nk_glfw3_shutdown(&glfw);
  glfwTerminate();
  return 0;
}