1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 27 июл. 2017 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #include <ui/ctl/ctl.h> 23 24 namespace lsp 25 { 26 namespace ctl 27 { 28 const ctl_class_t CtlAxis::metadata = { "CtlAxis", &CtlWidget::metadata }; 29 CtlAxis(CtlRegistry * src,LSPAxis * axis)30 CtlAxis::CtlAxis(CtlRegistry *src, LSPAxis *axis): CtlWidget(src, axis) 31 { 32 pClass = &metadata; 33 nFlags = 0; 34 pPort = NULL; 35 } 36 ~CtlAxis()37 CtlAxis::~CtlAxis() 38 { 39 } 40 slot_graph_resize(LSPWidget * sender,void * ptr,void * data)41 status_t CtlAxis::slot_graph_resize(LSPWidget *sender, void *ptr, void *data) 42 { 43 CtlAxis *_this = static_cast<CtlAxis *>(ptr); 44 if (_this != NULL) 45 _this->trigger_expr(); 46 return STATUS_OK; 47 } 48 init()49 void CtlAxis::init() 50 { 51 CtlWidget::init(); 52 sMin.init(pRegistry, this); 53 sMax.init(pRegistry, this); 54 sAngle.init(pRegistry, this); 55 sLength.init(pRegistry, this); 56 sDX.init(pRegistry, this); 57 sDY.init(pRegistry, this); 58 59 LSPAxis *axis = widget_cast<LSPAxis>(pWidget); 60 if (axis == NULL) 61 return; 62 63 // Initialize color controllers 64 sColor.init_hsl(pRegistry, axis, axis->color(), A_COLOR, A_HUE_ID, A_SAT_ID, A_LIGHT_ID); 65 66 axis->slots()->bind(LSPSLOT_RESIZE_PARENT, slot_graph_resize, this); 67 } 68 set(widget_attribute_t att,const char * value)69 void CtlAxis::set(widget_attribute_t att, const char *value) 70 { 71 LSPAxis *axis = widget_cast<LSPAxis>(pWidget); 72 73 switch (att) 74 { 75 case A_ID: 76 BIND_PORT(pRegistry, pPort, value); 77 break; 78 case A_ANGLE: 79 BIND_EXPR(sAngle, value); 80 break; 81 case A_DX: 82 BIND_EXPR(sDX, value); 83 break; 84 case A_DY: 85 BIND_EXPR(sDY, value); 86 break; 87 case A_LENGTH: 88 BIND_EXPR(sLength, value); 89 break; 90 case A_MIN: 91 BIND_EXPR(sMin, value); 92 nFlags |= F_MIN_SET; 93 break; 94 case A_MAX: 95 BIND_EXPR(sMax, value); 96 nFlags |= F_MAX_SET; 97 break; 98 case A_CENTER: 99 if (axis != NULL) 100 PARSE_INT(value, axis->set_center_id(__)); 101 break; 102 case A_BASIS: 103 if (axis != NULL) 104 PARSE_BOOL(value, axis->set_basis(__)); 105 break; 106 case A_LOGARITHMIC: 107 PARSE_BOOL(value, { 108 nFlags |= F_LOG_SET; 109 if (__) 110 nFlags |= F_LOG; 111 else 112 nFlags &= ~F_LOG; 113 }); 114 break; 115 case A_WIDTH: 116 if (axis != NULL) 117 PARSE_INT(value, axis->set_line_width(__)); 118 break; 119 120 default: 121 { 122 bool set = sColor.set(att, value); 123 if (!set) 124 CtlWidget::set(att, value); 125 break; 126 } 127 } 128 } 129 end()130 void CtlAxis::end() 131 { 132 CtlWidget::end(); 133 update_axis(); 134 trigger_expr(); 135 } 136 eval_expr(CtlExpression * expr)137 float CtlAxis::eval_expr(CtlExpression *expr) 138 { 139 LSPAxis *axis = widget_cast<LSPAxis>(pWidget); 140 if (axis == NULL) 141 return 0.0f; 142 143 LSPGraph *g = axis->graph(); 144 if (g == NULL) 145 return 0.0f; 146 147 expr->params()->clear(); 148 expr->params()->set_int("_g_width", g->width()); 149 expr->params()->set_int("_g_height", g->height()); 150 expr->params()->set_int("_a_width", g->area_width()); 151 expr->params()->set_int("_a_height", g->area_height()); 152 153 return expr->evaluate(); 154 } 155 trigger_expr()156 void CtlAxis::trigger_expr() 157 { 158 LSPAxis *axis = widget_cast<LSPAxis>(pWidget); 159 if (axis == NULL) 160 return; 161 162 if (sAngle.valid()) 163 { 164 float angle = eval_expr(&sAngle); 165 axis->set_angle(angle * M_PI); 166 } 167 168 if (sLength.valid()) 169 { 170 float length = eval_expr(&sLength); 171 axis->set_length(length); 172 } 173 174 if (sDX.valid()) 175 { 176 float dx = eval_expr(&sDX); 177 if (sDY.valid()) 178 { 179 float dy = eval_expr(&sDY); 180 axis->set_direction(dx, dy); 181 } 182 else 183 axis->set_dir_x(dx); 184 } 185 else if (sDY.valid()) 186 { 187 float dy = eval_expr(&sDY); 188 axis->set_dir_y(dy); 189 } 190 } 191 update_axis()192 void CtlAxis::update_axis() 193 { 194 LSPAxis *axis = widget_cast<LSPAxis>(pWidget); 195 if (axis == NULL) 196 return; 197 198 float amin = (sMin.valid()) ? sMin.evaluate() : 0.0f; 199 float amax = (sMax.valid()) ? sMax.evaluate() : 0.0f; 200 201 const port_t *mdata = (pPort != NULL) ? pPort->metadata() : NULL; 202 if (mdata == NULL) 203 { 204 if (nFlags & F_MIN_SET) 205 axis->set_min_value(amin); 206 if (nFlags & F_MAX_SET) 207 axis->set_max_value(amax); 208 if (nFlags & F_LOG_SET) 209 axis->set_log_scale(nFlags & F_LOG); 210 return; 211 } 212 213 axis->set_min_value((nFlags & F_MIN_SET) ? pPort->get_value() * amin : mdata->min); 214 axis->set_max_value((nFlags & F_MAX_SET) ? pPort->get_value() * amax : mdata->max); 215 if (nFlags & F_LOG_SET) 216 axis->set_log_scale(nFlags & F_LOG); 217 else 218 axis->set_log_scale(((is_decibel_unit(mdata->unit)) || (mdata->flags & F_LOG))); 219 } 220 notify(CtlPort * port)221 void CtlAxis::notify(CtlPort *port) 222 { 223 CtlWidget::notify(port); 224 225 update_axis(); 226 trigger_expr(); 227 } 228 229 } /* namespace ctl */ 230 } /* namespace lsp */ 231