xtc/src/gui/theme.hpp

70 lines
2.9 KiB
C++

#ifndef XTC_GUI_THEME_HPP
#define XTC_GUI_THEME_HPP
#include <cstdint>
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Tabs.H>
#include <FL/fl_draw.H>
/* Shared flat palette. No gradients, shadows, textures or external assets. */
namespace xtc_ui {
constexpr Fl_Boxtype flat = static_cast<Fl_Boxtype>(FL_FREE_BOXTYPE);
constexpr Fl_Boxtype pressed = static_cast<Fl_Boxtype>(FL_FREE_BOXTYPE+1);
inline Fl_Color background() { return fl_rgb_color(25,28,33); }
inline Fl_Color panel() { return fl_rgb_color(34,38,44); }
inline Fl_Color border() { return fl_rgb_color(58,64,73); }
inline Fl_Color text() { return fl_rgb_color(231,235,240); }
inline Fl_Color muted() { return fl_rgb_color(163,174,188); }
inline Fl_Color accent() { return fl_rgb_color(92,211,184); }
inline Fl_Color track(uint64_t id) {
static const unsigned char colors[][3] = {{74,155,184},{111,143,206},{160,123,191},
{74,163,139},{191,145,78},{183,113,139}};
const auto &c = colors[id % 6]; return fl_rgb_color(c[0],c[1],c[2]);
}
inline void flat_box(int x, int y, int w, int h, Fl_Color color) {
fl_color(color); fl_rectf(x,y,w,h);
fl_color(border()); fl_rect(x,y,w,h);
}
inline void pressed_box(int x, int y, int w, int h, Fl_Color color) {
flat_box(x,y,w,h,fl_darker(color));
}
inline void configure_boxes() {
Fl::set_boxtype(flat,flat_box,1,1,2,2);
Fl::set_boxtype(pressed,pressed_box,1,1,2,2);
Fl::set_boxtype(FL_UP_BOX,flat_box,1,1,2,2);
Fl::set_boxtype(FL_DOWN_BOX,pressed_box,1,1,2,2);
Fl::set_boxtype(FL_THIN_UP_BOX,flat_box,1,1,2,2);
Fl::set_boxtype(FL_THIN_DOWN_BOX,pressed_box,1,1,2,2);
Fl::set_boxtype(FL_ENGRAVED_BOX,flat_box,1,1,2,2);
Fl::set_boxtype(FL_BORDER_BOX,flat_box,1,1,2,2);
}
inline void initialize() {
static bool initialized = false;
if (initialized) return;
initialized = true;
Fl::background(34,38,44); Fl::background2(25,28,33); Fl::foreground(231,235,240);
Fl::set_color(FL_SELECTION_COLOR,53,116,111);
configure_boxes();
Fl::scrollbar_size(12);
}
inline void style(Fl_Widget *widget) {
widget->labelfont(FL_HELVETICA); widget->labelsize(12); widget->labelcolor(text());
widget->color(panel()); widget->selection_color(fl_rgb_color(53,116,111));
if (widget->box() != FL_NO_BOX && widget->box() != FL_FLAT_BOX) widget->box(flat);
if (auto *button = dynamic_cast<Fl_Button *>(widget)) {
button->box(flat); button->down_box(pressed);
button->color(fl_rgb_color(45,51,59));
}
if (auto *group = dynamic_cast<Fl_Group *>(widget)) {
for (int i = 0; i < group->children(); ++i) style(group->child(i));
if (auto *scroll = dynamic_cast<Fl_Scroll *>(group)) {
scroll->scrollbar.box(flat); scroll->hscrollbar.box(flat);
scroll->scrollbar.slider(FL_FLAT_BOX); scroll->hscrollbar.slider(FL_FLAT_BOX);
}
}
}
}
#endif