2007-09-23 20:13:58 +00:00
|
|
|
/* Jinete - a GUI library
|
2008-01-03 23:22:04 +00:00
|
|
|
* Copyright (C) 2003, 2004, 2005, 2007, 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>
|
|
|
|
|
2007-12-05 01:30:50 +00:00
|
|
|
#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;
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
static bool slider_msg_proc(JWidget widget, JMessage msg);
|
|
|
|
static void slider_request_size(JWidget widget, int *w, int *h);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
JWidget jslider_new(int min, int max, int value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-01-07 15:10:17 +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;
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(min, value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +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;
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jslider_set_range(JWidget widget, int min, int max)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-01-07 15:10:17 +00:00
|
|
|
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
slider->min = min;
|
|
|
|
slider->max = max;
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(min, slider->value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jslider_set_value(JWidget widget, int value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-01-07 15:10:17 +00:00
|
|
|
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
|
2007-09-18 23:57:02 +00:00
|
|
|
int old_value = slider->value;
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(slider->min, value, slider->max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (slider->value != old_value)
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
/* it DOES NOT emit CHANGE signal! to avoid recursive calls */
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
int jslider_get_value(JWidget widget)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-01-07 15:10:17 +00:00
|
|
|
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
return slider->value;
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jtheme_slider_info(JWidget widget, int *min, int *max, int *value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-01-07 15:10:17 +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;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
static bool slider_msg_proc(JWidget widget, JMessage msg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
|
|
|
static int slider_press_x;
|
|
|
|
static int slider_press_value;
|
|
|
|
static int slider_press_left;
|
2007-11-28 14:19:36 +00:00
|
|
|
Slider *slider = jwidget_get_data(widget, JI_SLIDER);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_DESTROY:
|
2007-11-28 14:19:36 +00:00
|
|
|
jfree(slider);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_REQSIZE:
|
2007-11-28 14:19:36 +00:00
|
|
|
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:
|
2007-11-28 14:19:36 +00:00
|
|
|
if (jwidget_is_enabled(widget))
|
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONPRESSED:
|
2007-11-28 14:19:36 +00:00
|
|
|
if (jwidget_is_disabled(widget))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
jwidget_select(widget);
|
|
|
|
jwidget_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;
|
2007-11-28 14:19:36 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
if (slider_press_left)
|
2007-09-26 19:34:06 +00:00
|
|
|
jmouse_set_cursor(JI_CURSOR_HAND);
|
2007-09-18 23:57:02 +00:00
|
|
|
else
|
2007-09-26 19:34:06 +00:00
|
|
|
jmouse_set_cursor(JI_CURSOR_MOVE);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
/* continue to JM_MOTION */
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
case JM_MOTION:
|
2007-11-28 14:19:36 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
range = slider->max - slider->min + 1;
|
|
|
|
|
|
|
|
/* with left click */
|
|
|
|
if (slider_press_left) {
|
|
|
|
value = slider->min +
|
|
|
|
range * (msg->mouse.x - widget->rc->x1) / jrect_w(widget->rc);
|
|
|
|
}
|
|
|
|
/* with right click */
|
|
|
|
else {
|
2007-11-28 14:19:36 +00:00
|
|
|
accuracy = MID(1,
|
|
|
|
jrect_w(widget->rc) / range,
|
|
|
|
jrect_w(widget->rc));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
value = slider_press_value +
|
|
|
|
(msg->mouse.x - slider_press_x) / accuracy;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
value = MID(slider->min, value, slider->max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (slider->value != value) {
|
2007-11-28 14:19:36 +00:00
|
|
|
jslider_set_value(widget, value);
|
|
|
|
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* for right click */
|
|
|
|
if ((!slider_press_left) &&
|
2007-09-26 19:34:06 +00:00
|
|
|
(jmouse_control_infinite_scroll(rect))) {
|
|
|
|
slider_press_x = jmouse_x(0);
|
2007-09-18 23:57:02 +00:00
|
|
|
slider_press_value = slider->value;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
jrect_free(rect);
|
2007-09-18 23:57:02 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONRELEASED:
|
2007-11-28 14:19:36 +00:00
|
|
|
if (jwidget_has_capture(widget)) {
|
|
|
|
jwidget_deselect(widget);
|
|
|
|
jwidget_release_mouse(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-09-26 19:34:06 +00:00
|
|
|
jmouse_set_cursor(JI_CURSOR_NORMAL);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_MOUSEENTER:
|
|
|
|
case JM_MOUSELEAVE:
|
2007-11-28 14:19:36 +00:00
|
|
|
/* if (jwidget_is_enabled(widget) && */
|
|
|
|
/* jwidget_has_capture(widget)) { */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* /\* swap the select status *\/ */
|
2007-11-28 14:19:36 +00:00
|
|
|
/* if (jwidget_is_selected(widget)) */
|
|
|
|
/* jwidget_deselect(widget); */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* else */
|
2007-11-28 14:19:36 +00:00
|
|
|
/* 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
|
|
|
/* } */
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
/* TODO theme stuff */
|
|
|
|
if (jwidget_is_enabled(widget))
|
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_CHAR:
|
|
|
|
if (jwidget_has_focus (widget)) {
|
|
|
|
int min = slider->min;
|
|
|
|
int max = slider->max;
|
|
|
|
int value = slider->value;
|
|
|
|
|
|
|
|
switch (msg->key.scancode) {
|
2007-11-28 14:19:36 +00:00
|
|
|
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) {
|
2007-11-28 14:19:36 +00:00
|
|
|
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)) {
|
2007-09-26 19:34:06 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
static void slider_request_size(JWidget widget, int *w, int *h)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2007-11-28 14:19:36 +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];
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
usprintf(buf, "%d", slider->min);
|
|
|
|
min_w = ji_font_text_len(widget->text_font, buf);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-28 14:19:36 +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
|
|
|
|
2007-11-28 14:19:36 +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;
|
|
|
|
}
|