aseprite/src/jinete/jslider.c

306 lines
7.9 KiB
C
Raw Normal View History

2007-09-23 20:13:58 +00:00
/* Jinete - a GUI library
2008-02-10 12:52:15 +00:00
* Copyright (C) 2003-2008 David A. Capello.
2007-09-23 20:13:58 +00:00
* All rights reserved.
2007-09-18 23:57:02 +00:00
*
2007-09-23 20:13:58 +00:00
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the Jinete nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2007-09-18 23:57:02 +00:00
*/
#include <allegro.h>
#include "jinete/jfont.h"
#include "jinete/jmanager.h"
#include "jinete/jmessage.h"
#include "jinete/jrect.h"
#include "jinete/jsystem.h"
#include "jinete/jtheme.h"
#include "jinete/jwidget.h"
2007-09-18 23:57:02 +00:00
typedef struct Slider
{
int min;
int max;
int value;
} Slider;
static int slider_press_x;
static int slider_press_value;
static int slider_press_left;
static bool slider_msg_proc(JWidget widget, JMessage msg);
static void slider_request_size(JWidget widget, int *w, int *h);
static void slider_setcursor(JWidget widget);
2007-09-18 23:57:02 +00:00
JWidget jslider_new(int min, int max, int value)
2007-09-18 23:57:02 +00:00
{
JWidget widget = jwidget_new(JI_SLIDER);
Slider *slider = jnew(Slider, 1);
2007-09-18 23:57:02 +00:00
slider->min = min;
slider->max = max;
slider->value = MID(min, value, max);
2007-09-18 23:57:02 +00:00
jwidget_add_hook(widget, JI_SLIDER, slider_msg_proc, slider);
jwidget_focusrest(widget, TRUE);
jwidget_init_theme(widget);
2007-09-18 23:57:02 +00:00
return widget;
}
void jslider_set_range(JWidget widget, int min, int max)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
slider->min = min;
slider->max = max;
slider->value = MID(min, slider->value, max);
2007-09-18 23:57:02 +00:00
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
}
void jslider_set_value(JWidget widget, int value)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
int old_value = slider->value;
slider->value = MID(slider->min, value, slider->max);
2007-09-18 23:57:02 +00:00
if (slider->value != old_value)
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
/* it DOES NOT emit CHANGE signal! to avoid recursive calls */
}
int jslider_get_value(JWidget widget)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
return slider->value;
}
void jtheme_slider_info(JWidget widget, int *min, int *max, int *value)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
if (min) *min = slider->min;
if (max) *max = slider->max;
if (value) *value = slider->value;
}
static bool slider_msg_proc(JWidget widget, JMessage msg)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
switch (msg->type) {
case JM_DESTROY:
jfree(slider);
2007-09-18 23:57:02 +00:00
break;
case JM_REQSIZE:
slider_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
2007-09-18 23:57:02 +00:00
return TRUE;
case JM_FOCUSENTER:
case JM_FOCUSLEAVE:
if (jwidget_is_enabled(widget))
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
break;
case JM_BUTTONPRESSED:
if (jwidget_is_disabled(widget))
return TRUE;
jwidget_select(widget);
jwidget_hard_capture_mouse(widget);
2007-09-18 23:57:02 +00:00
slider_press_x = msg->mouse.x;
slider_press_value = slider->value;
slider_press_left = msg->mouse.left;
slider_setcursor(widget);
2007-09-18 23:57:02 +00:00
/* continue to JM_MOTION */
2007-09-18 23:57:02 +00:00
case JM_MOTION:
if (jwidget_has_capture(widget)) {
JRect rect = jrect_new(0, 0, JI_SCREEN_W, JI_SCREEN_H);
2007-09-18 23:57:02 +00:00
int value, accuracy, range;
int xbeg = widget->rc->x1
+ widget->border_width.l;
int width = jrect_w(widget->rc)
- widget->border_width.l
- widget->border_width.r;
2007-09-18 23:57:02 +00:00
range = slider->max - slider->min + 1;
/* with left click */
if (slider_press_left) {
value = slider->min + range * (msg->mouse.x - xbeg) / width;
2007-09-18 23:57:02 +00:00
}
/* with right click */
else {
accuracy = MID(1, width / range, width);
2007-09-18 23:57:02 +00:00
value = slider_press_value +
(msg->mouse.x - slider_press_x) / accuracy;
}
value = MID(slider->min, value, slider->max);
2007-09-18 23:57:02 +00:00
if (slider->value != value) {
jslider_set_value(widget, value);
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
2007-09-18 23:57:02 +00:00
}
/* for left click */
if (slider_press_left) {
int x = jmouse_x(0);
if (x < widget->rc->x1 + widget->border_width.l)
x = widget->rc->x1 + widget->border_width.l;
else if (x > widget->rc->x2 - widget->border_width.r)
x = widget->rc->x2 - widget->border_width.r;
if (x != jmouse_x(0))
jmouse_set_position(x, jmouse_y(0));
}
2007-09-18 23:57:02 +00:00
/* for right click */
else if (jmouse_control_infinite_scroll(rect)) {
slider_press_x = jmouse_x(0);
2007-09-18 23:57:02 +00:00
slider_press_value = slider->value;
}
jrect_free(rect);
2007-09-18 23:57:02 +00:00
return TRUE;
}
break;
case JM_BUTTONRELEASED:
if (jwidget_has_capture(widget)) {
jwidget_deselect(widget);
jwidget_release_mouse(widget);
slider_setcursor(widget);
2007-09-18 23:57:02 +00:00
}
break;
case JM_MOUSEENTER:
case JM_MOUSELEAVE:
/* if (jwidget_is_enabled(widget) && */
/* jwidget_has_capture(widget)) { */
2007-09-18 23:57:02 +00:00
/* /\* swap the select status *\/ */
/* if (jwidget_is_selected(widget)) */
/* jwidget_deselect(widget); */
2007-09-18 23:57:02 +00:00
/* else */
/* jwidget_select(widget); */
2007-09-18 23:57:02 +00:00
2007-12-04 21:50:31 +00:00
/* /\* TODO switch slider signal *\/ */
2007-09-18 23:57:02 +00:00
/* } */
/* TODO theme stuff */
if (jwidget_is_enabled(widget))
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
break;
case JM_KEYPRESSED:
2007-09-18 23:57:02 +00:00
if (jwidget_has_focus (widget)) {
int min = slider->min;
int max = slider->max;
int value = slider->value;
switch (msg->key.scancode) {
case KEY_LEFT: value = MAX(value-1, min); break;
case KEY_RIGHT: value = MIN(value+1, max); break;
case KEY_PGDN: value = MAX(value-(max-min+1)/4, min); break;
case KEY_PGUP: value = MIN(value+(max-min+1)/4, max); break;
2007-09-18 23:57:02 +00:00
case KEY_HOME: value = min; break;
case KEY_END: value = max; break;
default:
return FALSE;
}
if (slider->value != value) {
jslider_set_value(widget, value);
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
2007-09-18 23:57:02 +00:00
}
return TRUE;
}
break;
case JM_WHEEL:
if (jwidget_is_enabled(widget)) {
int value = slider->value + jmouse_z(0) - jmouse_z(1);
2007-09-18 23:57:02 +00:00
value = MID(slider->min, value, slider->max);
if (slider->value != value) {
jslider_set_value(widget, value);
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
}
return TRUE;
}
break;
case JM_SETCURSOR:
slider_setcursor(widget);
return TRUE;
2007-09-18 23:57:02 +00:00
}
return FALSE;
}
static void slider_request_size(JWidget widget, int *w, int *h)
2007-09-18 23:57:02 +00:00
{
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
2007-09-18 23:57:02 +00:00
int min_w, max_w;
char buf[256];
usprintf(buf, "%d", slider->min);
min_w = ji_font_text_len(widget->text_font, buf);
2007-09-18 23:57:02 +00:00
usprintf(buf, "%d", slider->max);
max_w = ji_font_text_len(widget->text_font, buf);
2007-09-18 23:57:02 +00:00
*w = MAX(min_w, max_w);
*h = text_height(widget->text_font);
2007-09-18 23:57:02 +00:00
*w += widget->border_width.l + widget->border_width.r;
*h += widget->border_width.t + widget->border_width.b;
}
static void slider_setcursor(JWidget widget)
{
if (jwidget_has_capture(widget)) {
if (slider_press_left)
jmouse_set_cursor(JI_CURSOR_NORMAL);
else
jmouse_set_cursor(JI_CURSOR_SIZE_L);
}
else
jmouse_set_cursor(JI_CURSOR_NORMAL);
}