URI: 
       label.c - ltk - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/ltk.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltk.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       label.c (4690B)
       ---
            1 /*
            2  * Copyright (c) 2021-2024 lumidify <nobody@lumidify.org>
            3  *
            4  * Permission to use, copy, modify, and/or distribute this software for any
            5  * purpose with or without fee is hereby granted, provided that the above
            6  * copyright notice and this permission notice appear in all copies.
            7  *
            8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
            9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
           10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
           11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
           12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
           13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
           14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
           15  */
           16 
           17 #include <stddef.h>
           18 
           19 #include "config.h"
           20 #include "memory.h"
           21 #include "color.h"
           22 #include "rect.h"
           23 #include "widget.h"
           24 #include "ltk.h"
           25 #include "util.h"
           26 #include "text.h"
           27 #include "label.h"
           28 #include "graphics.h"
           29 
           30 #define MAX_LABEL_PADDING 50000
           31 
           32 static void ltk_label_draw(ltk_widget *self, ltk_surface *draw_surf, int x, int y, ltk_rect clip);
           33 static void ltk_label_destroy(ltk_widget *self, int shallow);
           34 static void ltk_label_recalc_ideal_size(ltk_widget *self);
           35 
           36 static struct ltk_widget_vtable vtable = {
           37         .draw = &ltk_label_draw,
           38         .destroy = &ltk_label_destroy,
           39         .hide = NULL,
           40         .resize = NULL,
           41         .change_state = NULL,
           42         .child_size_change = NULL,
           43         .remove_child = NULL,
           44         .get_child_at_pos = NULL,
           45         .key_press = NULL,
           46         .key_release = NULL,
           47         .mouse_press = NULL,
           48         .mouse_release = NULL,
           49         .motion_notify = NULL,
           50         .mouse_leave = NULL,
           51         .mouse_enter = NULL,
           52         .recalc_ideal_size = &ltk_label_recalc_ideal_size,
           53         .type = LTK_WIDGET_LABEL,
           54         .flags = LTK_NEEDS_REDRAW | LTK_ACTIVATABLE_SPECIAL,
           55         .invalid_signal = LTK_LABEL_SIGNAL_INVALID
           56 };
           57 
           58 static struct {
           59         ltk_color *text_color;
           60         ltk_color *bg_color;
           61         ltk_color *bg_color_active;
           62         char *font;
           63         ltk_size pad;
           64         ltk_size font_size;
           65 } theme;
           66 
           67 static ltk_theme_parseinfo parseinfo[] = {
           68         {"bg-color", THEME_COLOR, {.color = &theme.bg_color}, {.color = "#000000"}, 0, 0, 0},
           69         {"bg-color-active", THEME_COLOR, {.color = &theme.bg_color_active}, {.color = "#222222"}, 0, 0, 0},
           70         {"pad", THEME_SIZE, {.size = &theme.pad}, {.size = {.val = 100, .unit = LTK_UNIT_MM}}, 0, MAX_LABEL_PADDING, 0},
           71         {"text-color", THEME_COLOR, {.color = &theme.text_color}, {.color = "#FFFFFF"}, 0, 0, 0},
           72         {"font-size", THEME_SIZE, {.size = &theme.font_size}, {.size = {.val = 1200, .unit = LTK_UNIT_PT}}, 0, 20000, 0},
           73         {"font", THEME_STRING, {.str = &theme.font}, {.str = "Monospace"}, 0, 0, 0},
           74 };
           75 
           76 void
           77 ltk_label_get_theme_parseinfo(ltk_theme_parseinfo **p, size_t *len) {
           78         *p = parseinfo;
           79         *len = LENGTH(parseinfo);
           80 }
           81 
           82 static void
           83 ltk_label_draw(ltk_widget *self, ltk_surface *draw_surf, int x, int y, ltk_rect clip) {
           84         ltk_label *label = LTK_CAST_LABEL(self);
           85         ltk_rect lrect = self->lrect;
           86         ltk_rect clip_final = ltk_rect_intersect(clip, (ltk_rect){0, 0, lrect.w, lrect.h});
           87         if (clip_final.w <= 0 || clip_final.h <= 0)
           88                 return;
           89         ltk_rect draw_clip = {x + clip_final.x, y + clip_final.y, clip_final.w, clip_final.h};
           90         ltk_surface_fill_rect(draw_surf, (self->state & LTK_ACTIVE) ? theme.bg_color_active : theme.bg_color, draw_clip);
           91 
           92         int text_w, text_h;
           93         ltk_text_line_get_size(label->tl, &text_w, &text_h);
           94         int text_x = x + (lrect.w - text_w) / 2;
           95         int text_y = y + (lrect.h - text_h) / 2;
           96         ltk_text_line_draw_clipped(label->tl, draw_surf, theme.text_color, text_x, text_y, draw_clip);
           97 }
           98 
           99 static void
          100 recalc_ideal_size(ltk_label *label) {
          101         int text_w, text_h;
          102         ltk_text_line_get_size(label->tl, &text_w, &text_h);
          103         int pad = ltk_size_to_pixel(theme.pad, LTK_CAST_WIDGET(label)->last_dpi);
          104         label->widget.ideal_w = text_w + pad * 2;
          105         label->widget.ideal_h = text_h + pad * 2;
          106 }
          107 
          108 static void
          109 ltk_label_recalc_ideal_size(ltk_widget *self) {
          110         ltk_label *label = LTK_CAST_LABEL(self);
          111         int font_size = ltk_size_to_pixel(theme.font_size, self->last_dpi);
          112         ltk_text_line_set_font_size(label->tl, font_size);
          113         recalc_ideal_size(label);
          114 }
          115 
          116 ltk_label *
          117 ltk_label_create(ltk_window *window, const char *text) {
          118         ltk_label *label = ltk_malloc(sizeof(ltk_label));
          119 
          120         ltk_fill_widget_defaults(LTK_CAST_WIDGET(label), window, &vtable, 0, 0);
          121         label->tl = ltk_text_line_create_const_text_default(
          122                 theme.font, ltk_size_to_pixel(theme.font_size, label->widget.last_dpi), text, -1
          123         );
          124         recalc_ideal_size(label);
          125 
          126         return label;
          127 }
          128 
          129 static void
          130 ltk_label_destroy(ltk_widget *self, int shallow) {
          131         (void)shallow;
          132         ltk_label *label = LTK_CAST_LABEL(self);
          133         if (!label) {
          134                 ltk_warn("Tried to destroy NULL label.\n");
          135                 return;
          136         }
          137         ltk_text_line_destroy(label->tl);
          138         ltk_free(label);
          139 }