URI: 
       image_widget.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
       ---
       image_widget.c (3242B)
       ---
            1 /*
            2  * Copyright (c) 2023-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 "image_widget.h"
           20 #include "graphics.h"
           21 #include "memory.h"
           22 #include "rect.h"
           23 #include "util.h"
           24 #include "widget.h"
           25 
           26 /* FIXME: add padding, etc. */
           27 
           28 static void ltk_image_widget_draw(
           29     ltk_widget *self, ltk_surface *draw_surf, int x, int y, ltk_rect clip
           30 );
           31 static void ltk_image_widget_destroy(ltk_widget *self, int shallow);
           32 
           33 static struct ltk_widget_vtable vtable = {
           34         .draw = &ltk_image_widget_draw,
           35         .destroy = &ltk_image_widget_destroy,
           36         .hide = NULL,
           37         .resize = NULL,
           38         .change_state = NULL,
           39         .child_size_change = NULL,
           40         .remove_child = NULL,
           41         .get_child_at_pos = NULL,
           42         .key_press = NULL,
           43         .key_release = NULL,
           44         .mouse_press = NULL,
           45         .mouse_release = NULL,
           46         .motion_notify = NULL,
           47         .mouse_leave = NULL,
           48         .mouse_enter = NULL,
           49         .type = LTK_WIDGET_IMAGE,
           50         /* FIXME: need to show that it is activated somehow in special mode */
           51         .flags = LTK_NEEDS_REDRAW | LTK_ACTIVATABLE_SPECIAL,
           52 };
           53 
           54 static void
           55 ltk_image_widget_draw(ltk_widget *self, ltk_surface *draw_surf, int x, int y, ltk_rect clip) {
           56         ltk_image_widget *img = LTK_CAST_IMAGE_WIDGET(self);
           57         ltk_rect lrect = self->lrect;
           58         ltk_rect clip_final = ltk_rect_intersect(clip, (ltk_rect){0, 0, lrect.w, lrect.h});
           59         if (clip_final.w <= 0 || clip_final.h <= 0)
           60                 return;
           61         /* FIXME: maybe replace with integer operations */
           62         double scalex = self->ideal_w / (double)lrect.w;
           63         double scaley = self->ideal_h / (double)lrect.h;
           64         int src_x = (int)(clip_final.x * scalex);
           65         int src_y = (int)(clip_final.y * scaley);
           66         int src_w = (int)(clip_final.w * scalex);
           67         int src_h = (int)(clip_final.h * scaley);
           68         ltk_image_draw_cropped_scaled(
           69             img->img, draw_surf, src_x, src_y, src_w, src_h,
           70             x + clip_final.x, y + clip_final.y, clip_final.w, clip_final.h
           71         );
           72 }
           73 
           74 ltk_image_widget *
           75 ltk_image_widget_create(ltk_window *window, ltk_image *img) {
           76         ltk_image_widget *imw = ltk_malloc(sizeof(ltk_image_widget));
           77         imw->img = img;
           78         int w = ltk_image_get_width(imw->img);
           79         int h = ltk_image_get_height(imw->img);
           80         ltk_fill_widget_defaults(&imw->widget, window, &vtable, w, h);
           81         imw->widget.ideal_w = w;
           82         imw->widget.ideal_h = h;
           83 
           84         return imw;
           85 }
           86 
           87 static void
           88 ltk_image_widget_destroy(ltk_widget *self, int shallow) {
           89         (void)shallow;
           90         ltk_image_widget *img = LTK_CAST_IMAGE_WIDGET(self);
           91         /* FIXME: make warnings like this consistent across widgets */
           92         if (!img) {
           93                 ltk_warn("Tried to destroy NULL image widget.\n");
           94                 return;
           95         }
           96         ltk_image_destroy(img->img);
           97         ltk_free(img);
           98 }