URI:
       grid.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/git/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
       ---
       grid.c (5767B)
       ---
            1 /*
            2  * Copyright (c) 2016-2026 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 "ltkd.h"
           18 #include "widget.h"
           19 #include "cmd.h"
           20 
           21 #include <ltk/ltk.h>
           22 #include <ltk/grid.h>
           23 
           24 /* grid <grid id> add <widget id> <row> <column> <row_span> <column_span> [sticky] */
           25 static int
           26 ltkd_grid_cmd_add(
           27     ltk_widget_id windowid,
           28     ltkd_widget *widget,
           29     ltkd_cmd_token *tokens,
           30     size_t num_tokens,
           31     ltkd_error *err) {
           32         (void)windowid;
           33         ltk_widget *gridw = ltk_get_widget_from_id(widget->ltkid);
           34         ltk_grid *grid = LTK_CAST_GRID(gridw);
           35         ltkd_cmdarg_parseinfo cmd[] = {
           36                 {.type = CMDARG_WIDGET, .widget_type = LTK_WIDGET_UNKNOWN, .optional = 0},
           37                 {.type = CMDARG_INT, .min = 0, .max = grid->rows - 1, .optional = 0},
           38                 {.type = CMDARG_INT, .min = 0, .max = grid->columns - 1, .optional = 0},
           39                 {.type = CMDARG_INT, .min = 0, .max = grid->rows, .optional = 0},
           40                 {.type = CMDARG_INT, .min = 0, .max = grid->columns, .optional = 0},
           41                 {.type = CMDARG_STICKY, .optional = 1},
           42         };
           43         if (ltkd_parse_cmd(tokens, num_tokens, cmd, LENGTH(cmd), err))
           44                 return 1;
           45         int row = cmd[1].val.i, col = cmd[2].val.i;
           46         int rowspan = cmd[3].val.i, colspan = cmd[4].val.i;
           47         if (row + rowspan > grid->rows) {
           48                 err->type = ERR_GRID_INVALID_POSITION;
           49                 err->arg = 1;
           50         }
           51         if (col + colspan > grid->columns) {
           52                 err->type = ERR_GRID_INVALID_POSITION;
           53                 err->arg = 2;
           54         }
           55         /* FIXME: better error reporting for invalid grid position */
           56         /* FIXME: check if recalculation deals properly with rowspan/columnspan
           57            that goes over the edge of the grid */
           58         if (ltk_grid_add(
           59             widget->ltkid, cmd[0].val.widget->ltkid,
           60             row, col, rowspan, colspan,
           61             cmd[5].initialized ? cmd[5].val.sticky : 0)) {
           62                 err->type = ERR_WIDGET_IN_CONTAINER;
           63                 err->arg = 0;
           64                 return 1;
           65         }
           66         return 0;
           67 }
           68 
           69 /* grid <grid id> remove <widget id> */
           70 static int
           71 ltkd_grid_cmd_ungrid(
           72     ltk_widget_id windowid,
           73     ltkd_widget *widget,
           74     ltkd_cmd_token *tokens,
           75     size_t num_tokens,
           76     ltkd_error *err) {
           77         (void)windowid;
           78         ltkd_cmdarg_parseinfo cmd[] = {
           79                 {.type = CMDARG_WIDGET, .widget_type = LTK_WIDGET_UNKNOWN, .optional = 0}
           80         };
           81         if (ltkd_parse_cmd(tokens, num_tokens, cmd, LENGTH(cmd), err))
           82                 return 1;
           83         if (ltk_grid_remove(widget->ltkid, cmd[0].val.widget->ltkid)) {
           84                 err->type = ERR_WIDGET_NOT_IN_CONTAINER;
           85                 err->arg = 0;
           86                 return 1;
           87         }
           88         return 0;
           89 }
           90 
           91 /* FIXME: max size of 64 is completely arbitrary! */
           92 /* grid <grid id> create <rows> <columns> */
           93 static int
           94 ltkd_grid_cmd_create(
           95     ltk_widget_id windowid,
           96     ltkd_widget *widget_unneeded,
           97     ltkd_cmd_token *tokens,
           98     size_t num_tokens,
           99     ltkd_error *err) {
          100         (void)widget_unneeded;
          101         ltkd_cmdarg_parseinfo cmd[] = {
          102                 {.type = CMDARG_IGNORE, .optional = 0},
          103                 {.type = CMDARG_STRING, .optional = 0},
          104                 {.type = CMDARG_IGNORE, .optional = 0},
          105                 {.type = CMDARG_INT, .min = 0, .max = 64, .optional = 0},
          106                 {.type = CMDARG_INT, .min = 0, .max = 64, .optional = 0},
          107         };
          108         if (ltkd_parse_cmd(tokens, num_tokens, cmd, LENGTH(cmd), err))
          109                 return 1;
          110         ltk_widget_id grid = ltk_grid_create(windowid, cmd[3].val.i, cmd[4].val.i);
          111         if (!ltkd_widget_create(grid, cmd[1].val.str, NULL, 0, err)) {
          112                 ltk_widget_id_destroy(grid, 1);
          113                 err->arg = 1;
          114                 return 1;
          115         }
          116 
          117         return 0;
          118 }
          119 
          120 /* FIXME: 64 is completely arbitrary */
          121 /* grid <grid id> set-row-weight <row> <weight> */
          122 static int
          123 ltkd_grid_cmd_set_row_weight(
          124     ltk_widget_id windowid,
          125     ltkd_widget *widget,
          126     ltkd_cmd_token *tokens,
          127     size_t num_tokens,
          128     ltkd_error *err) {
          129         (void)windowid;
          130         ltk_widget *gridw = ltk_get_widget_from_id(widget->ltkid);
          131         ltk_grid *grid = LTK_CAST_GRID(gridw);
          132         ltkd_cmdarg_parseinfo cmd[] = {
          133                 {.type = CMDARG_INT, .min = 0, .max = grid->rows - 1, .optional = 0},
          134                 {.type = CMDARG_INT, .min = 0, .max = 64, .optional = 0},
          135         };
          136         if (ltkd_parse_cmd(tokens, num_tokens, cmd, LENGTH(cmd), err))
          137                 return 1;
          138         ltk_grid_set_row_weight(widget->ltkid, cmd[0].val.i, cmd[1].val.i);
          139 
          140         return 0;
          141 }
          142 
          143 
          144 /* FIXME: 64 is completely arbitrary */
          145 /* FIXME: check for overflows in various grid calculations (at least when larger values are allowed) */
          146 /* grid <grid id> set-column-weight <column> <weight> */
          147 static int
          148 ltkd_grid_cmd_set_column_weight(
          149     ltk_widget_id windowid,
          150     ltkd_widget *widget,
          151     ltkd_cmd_token *tokens,
          152     size_t num_tokens,
          153     ltkd_error *err) {
          154         (void)windowid;
          155         ltk_widget *gridw = ltk_get_widget_from_id(widget->ltkid);
          156         ltk_grid *grid = LTK_CAST_GRID(gridw);
          157         ltkd_cmdarg_parseinfo cmd[] = {
          158                 {.type = CMDARG_INT, .min = 0, .max = grid->columns - 1, .optional = 0},
          159                 {.type = CMDARG_INT, .min = 0, .max = 64, .optional = 0},
          160         };
          161         if (ltkd_parse_cmd(tokens, num_tokens, cmd, LENGTH(cmd), err))
          162                 return 1;
          163         ltk_grid_set_column_weight(widget->ltkid, cmd[0].val.i, cmd[1].val.i);
          164 
          165         return 0;
          166 }
          167 
          168 static ltkd_cmd_info grid_cmds[] = {
          169         {"add", &ltkd_grid_cmd_add, 0},
          170         {"create", &ltkd_grid_cmd_create, 1},
          171         {"remove", &ltkd_grid_cmd_ungrid, 0},
          172         {"set-column-weight", &ltkd_grid_cmd_set_column_weight, 0},
          173         {"set-row-weight", &ltkd_grid_cmd_set_row_weight, 0},
          174 };
          175 
          176 GEN_CMD_HELPERS(ltkd_grid_cmd, LTK_WIDGET_GRID, grid_cmds)