libxputty 0.1
Loading...
Searching...
No Matches
xknob_private.c
Go to the documentation of this file.
1/*
2 * 0BSD
3 *
4 * BSD Zero Clause License
5 *
6 * Copyright (c) 2019 Hermann Meyer
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted.
10
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21
22#include "xknob_private.h"
23
24static void _show_label(Widget_t *w, int width, int height) {
26 cairo_text_extents_t extents;
28 cairo_set_font_size (w->crb, w->app->normal_font/w->scale.ascale);
29 cairo_text_extents(w->crb,w->label , &extents);
30 cairo_move_to (w->crb, (width*0.5)-(extents.width/2), height-(extents.height/4));
31 cairo_show_text(w->crb, w->label);
32 cairo_new_path (w->crb);
33}
34
35void _draw_image_knob(Widget_t *w, int width_t, int height_t) {
36 int width, height;
37 os_get_surface_size(w->image, &width, &height);
38 double x = (double)width_t/(double)height;
39 double y = (double)height/(double)width_t;
40 double knobstate = adj_get_state(w->adj_y);
41 int findex = (int)(((width/height)-1) * knobstate);
42 int posx = 0;
43 int posy = (height_t/2 - ((height*x)/2));
44 if (width_t > height_t) {
45 x = (double)height_t/(double)height;
46 y = (double)height/(double)height_t;
47 posx = (width_t/2 -((height*x)/2));
48 posy = 0;
49 }
50 cairo_save(w->crb);
51 cairo_scale(w->crb, x,x);
52 cairo_translate(w->crb, posx * ((1-x)/x), posy * ((1-x)/x));
53 cairo_set_source_surface (w->crb, w->image, -height*findex + posx, posy);
54 cairo_rectangle(w->crb, posx, posy, height, height);
55 cairo_fill(w->crb);
56 cairo_scale(w->crb, y,y);
57 cairo_restore(w->crb);
58}
59
60void _draw_knob_image(void *w_, void* user_data) {
61 Widget_t *w = (Widget_t*)w_;
62 _draw_image_knob(w, w->width, w->height);
63 _show_label(w, w->width-2, w->height-2);
64}
65
66void _draw_knob(void *w_, void* user_data) {
67 Widget_t *w = (Widget_t*)w_;
68 Metrics_t metrics;
69 os_get_window_metrics(w, &metrics);
70 int width = metrics.width-2;
71 int height = metrics.height-2;
72 if (!metrics.visible) return;
73
74 const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs
75 int arc_offset = 0;
76 int knob_x = 0;
77 int knob_y = 0;
78
79 int grow = (width > height) ? height:width;
80 knob_x = grow-1;
81 knob_y = grow-1;
84 int knobx = (width - knob_x) * 0.5;
85 int knobx1 = width* 0.5;
86
87 int knoby = (height - knob_y) * 0.5;
88 int knoby1 = height * 0.5;
89 if (w->image) {
90 _draw_image_knob(w, width, height);
91 } else {
92
93 double knobstate = adj_get_state(w->adj_y);
94 double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero);
95
96 double pointer_off =knob_x/6;
97 double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2;
98 double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle);
99 double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle);
100 double radius_x = (knobx+radius+pointer_off/2) - radius/ 1.24 * sin(angle);
101 double radius_y = (knoby+radius+pointer_off/2) + radius/ 1.24 * cos(angle);
102
103 cairo_arc(w->crb,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI );
104
106 cairo_fill (w->crb);
107 cairo_new_path (w->crb);
108
110 cairo_arc(w->crb,knobx1+arc_offset, knoby1+arc_offset, knob_x/3.1, 0, 2 * M_PI );
111 cairo_fill_preserve(w->crb);
113 cairo_set_line_width(w->crb, min(3.0, knobx1/15));
114 cairo_stroke(w->crb);
115 cairo_new_path (w->crb);
116
118 cairo_set_line_cap(w->crb, CAIRO_LINE_CAP_ROUND);
119 cairo_set_line_join(w->crb, CAIRO_LINE_JOIN_BEVEL);
120 cairo_move_to(w->crb, radius_x, radius_y);
121 cairo_line_to(w->crb,lengh_x,lengh_y);
122 cairo_set_line_width(w->crb,min(6.0, knobx1/7));
124 cairo_stroke(w->crb);
125 cairo_new_path (w->crb);
126 }
128 cairo_text_extents_t extents;
130 if (w->state) {
131 char s[64];
132 const char* format[] = {"%.1f", "%.2f", "%.3f"};
133 float value = adj_get_value(w->adj);
134 if (fabs(w->adj->step)>0.99) {
135 snprintf(s, 63,"%d", (int) value);
136 } else if (fabs(w->adj->step)>0.09) {
137 snprintf(s, 63, format[1-1], value);
138 } else {
139 snprintf(s, 63, format[2-1], value);
140 }
141 cairo_set_font_size (w->crb, w->app->small_font/w->scale.ascale);
142 cairo_text_extents(w->crb, s, &extents);
143 cairo_move_to (w->crb, knobx1-extents.width/2, knoby1+extents.height/2);
144 cairo_show_text(w->crb, s);
145 cairo_new_path (w->crb);
146 }
147
148 _show_label(w, width, height);
149}
150
151void _knob_released(void *w_, void* button_, void* user_data) {
152 Widget_t *w = (Widget_t*)w_;
153 if (w->flags & HAS_POINTER) w->state= 1;
154 expose_widget(w);
155}
Metrics_t - struct to receive window size, position & visibility Pass this struct to os_get_window_...
float ascale
Definition xwidget.h:369
Widget_t - struct to hold the basic Widget_t info.
Definition xwidget.h:457
Resize_t scale
Definition xwidget.h:525
Adjustment_t * adj_y
Definition xwidget.h:495
int width
Definition xwidget.h:521
cairo_surface_t * image
Definition xwidget.h:491
Adjustment_t * adj
Definition xwidget.h:497
cairo_t * crb
Definition xwidget.h:489
int state
Definition xwidget.h:511
long long flags
Definition xwidget.h:461
const char * label
Definition xwidget.h:463
int height
Definition xwidget.h:523
Xputty * app
Definition xwidget.h:465
int normal_font
Definition xputty.h:248
int small_font
Definition xputty.h:246
float adj_get_value(Adjustment_t *adj)
adj_get_value - get the current value of the Adjustment_t
float adj_get_state(Adjustment_t *adj)
adj_get_state - get the current state of the Adjustment_t
Color_state get_color_state(Widget_t *wid)
get_color_state - get the Color_state to use in relation to the Widget_t state
Definition xcolor.c:222
void use_text_color_scheme(Widget_t *w, Color_state st)
use_text_color_scheme - use text Colors to paint on Widget_t
Definition xcolor.c:266
void use_bg_color_scheme(Widget_t *w, Color_state st)
use_bg_color_scheme - use background Colors to paint on Widget_t
Definition xcolor.c:252
void use_fg_color_scheme(Widget_t *w, Color_state st)
use_fg_color_scheme - use forground Colors to paint on Widget_t
Definition xcolor.c:245
void use_shadow_color_scheme(Widget_t *w, Color_state st)
use_shadow_color_scheme - use shadow Colors to paint on Widget_t
Definition xcolor.c:273
@ NORMAL_
Definition xcolor.h:44
void _draw_knob_image(void *w_, void *user_data)
_draw_knob_image - internal draw the knob to the buffer
void _draw_knob(void *w_, void *user_data)
_draw_knob - internal draw the knob to the buffer
void _knob_released(void *w_, void *button_, void *user_data)
_knob_released - redraw the slider when buttob released
void _draw_image_knob(Widget_t *w, int width_t, int height_t)
_draw_image_knob - internal draw the knob from image to the buffer
void os_get_window_metrics(Widget_t *w, Metrics_t *metrics)
os_get_window_metrics - Get the Merics_t struct related to a Widget_t
void os_get_surface_size(cairo_surface_t *surface, int *width, int *height)
os_get_surface_size - get the size of the cairo surface
void expose_widget(Widget_t *w)
expose_widgets - send a expose event (EXPOSE) to a Widget_t
Definition xwidget.c:445
@ HAS_POINTER
Definition xwidget.h:402