--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcpixmap.h"
+#include "bcresources.h"
+#include "bcsignals.h"
+#include "bctoggle.h"
+#include "clip.h"
+#include "colors.h"
+#include "cursors.h"
+#include "fonts.h"
+#include "vframe.h"
+
+#include <string.h>
+
+BC_Toggle::BC_Toggle(int x, int y,
+ VFrame **data,
+ int value,
+ const char *caption,
+ int bottom_justify,
+ int font,
+ int color)
+ : BC_SubWindow(x, y, 0, 0, -1)
+{
+ this->data = data;
+ for(int i = 0; i < TOGGLE_IMAGES; i++)
+ images[i] = 0;
+ bg_image = 0;
+ status = value ? BC_Toggle::TOGGLE_CHECKED : BC_Toggle::TOGGLE_UP;
+ this->value = value;
+ strcpy(this->caption, caption);
+ this->bottom_justify = bottom_justify;
+ this->font = font;
+ if(color >= 0)
+ this->color = color;
+ else
+ this->color = get_resources()->default_text_color;
+ select_drag = 0;
+ enabled = 1;
+ underline = -1;
+ is_radial = 0;
+}
+
+
+BC_Toggle::~BC_Toggle()
+{
+ for(int i = 0; i < TOGGLE_IMAGES; i++) if(images[i]) delete images[i];
+ delete bg_image;
+}
+
+
+int BC_Toggle::initialize()
+{
+// Get the image
+ set_images(data);
+ calculate_extents(this,
+ data,
+ bottom_justify,
+ &text_line,
+ &w,
+ &h,
+ &toggle_x,
+ &toggle_y,
+ &text_x,
+ &text_y,
+ &text_w,
+ &text_h,
+ has_caption() ? caption : 0,
+ font);
+
+// Create the subwindow
+ BC_SubWindow::initialize();
+ set_cursor(UPRIGHT_ARROW_CURSOR, 0, 0);
+// Display the bitmap
+ draw_face(1, 0);
+ show_window(0);
+ return 0;
+}
+
+
+void BC_Toggle::calculate_extents(BC_WindowBase *gui,
+ VFrame **images,
+ int bottom_justify,
+ int *text_line,
+ int *w,
+ int *h,
+ int *toggle_x,
+ int *toggle_y,
+ int *text_x,
+ int *text_y,
+ int *text_w,
+ int *text_h,
+ const char *caption,
+ int font)
+{
+ BC_Resources *resources = get_resources();
+ VFrame *frame = images[0];
+ *w = frame->get_w();
+ *h = frame->get_h();
+ *toggle_x = 0;
+ *toggle_y = 0;
+ *text_x = *w + 5;
+ *text_y = 0;
+ *text_w = 0;
+ *text_h = 0;
+
+ if(caption)
+ {
+ *text_w = gui->get_text_width(font, caption);
+ *text_h = gui->get_text_height(font);
+
+ if(resources->toggle_highlight_bg)
+ {
+ *text_w += resources->toggle_text_margin * 2;
+ *text_h = MAX(*text_h, resources->toggle_highlight_bg->get_h());
+ }
+
+ if(*text_h > *h)
+ {
+ *toggle_y = (*text_h - *h) >> 1;
+ *h = *text_h;
+ }
+ else
+ *text_y = (*h - *text_h) >> 1;
+
+ if(bottom_justify)
+ {
+ *text_y = *h - *text_h;
+ *text_line = *h - gui->get_text_descent(font);
+ }
+ else
+ *text_line = *text_y + gui->get_text_ascent(font);
+
+ *w = *text_x + *text_w;
+ }
+
+
+}
+
+void BC_Toggle::set_radial(int value)
+{
+ is_radial = value;
+}
+
+int BC_Toggle::set_images(VFrame **data)
+{
+ delete bg_image;
+ bg_image = 0;
+ for(int i = 0; i < TOGGLE_IMAGES; i++)
+ {
+ if(images[i]) delete images[i];
+ images[i] = new BC_Pixmap(top_level, data[i], PIXMAP_ALPHA);
+ }
+ BC_Resources *resources = get_resources();
+ if(resources->toggle_highlight_bg)
+ {
+ bg_image = new BC_Pixmap(top_level,
+ resources->toggle_highlight_bg,
+ PIXMAP_ALPHA);
+ }
+ return 0;
+}
+
+void BC_Toggle::set_underline(int number)
+{
+ this->underline = number;
+}
+
+
+void BC_Toggle::set_select_drag(int value)
+{
+ this->select_drag = value;
+}
+
+int BC_Toggle::draw_face(int flash, int flush)
+{
+ BC_Resources *resources = get_resources();
+ draw_top_background(parent_window, 0, 0, get_w(), get_h());
+ if(has_caption())
+ {
+ if(enabled &&
+ (status == BC_Toggle::TOGGLE_UPHI ||
+ status == BC_Toggle::TOGGLE_DOWN ||
+ status == BC_Toggle::TOGGLE_CHECKEDHI))
+ {
+// Draw highlight image
+ if(bg_image)
+ {
+ int x = text_x;
+ int y = text_line - get_text_ascent(font) / 2 -
+ bg_image->get_h() / 2;
+ y = MAX(y, 0);
+ int w = text_w;
+ draw_3segmenth(x,
+ y,
+ w,
+ bg_image);
+ }
+ else
+// Draw a plain box
+ {
+ set_color(LTGREY);
+ draw_box(text_x,
+ text_line - get_text_ascent(font),
+ get_w() - text_x,
+ get_text_height(font));
+ }
+ }
+
+ set_opaque();
+ if(enabled)
+ set_color(color);
+ else
+ set_color(get_resources()->disabled_text_color);
+ set_font(font);
+ draw_text(text_x + resources->toggle_text_margin,
+ text_line,
+ caption);
+
+// Draw underline
+ if(underline >= 0)
+ {
+ int x = text_x + resources->toggle_text_margin;
+ int y = text_line + 1;
+ int x1 = get_text_width(current_font, caption, underline) + x;
+ int x2 = get_text_width(current_font, caption, underline + 1) + x;
+ draw_line(x1, y, x2, y);
+ draw_line(x1, y + 1, (x2 + x1) / 2, y + 1);
+ }
+ }
+
+ draw_pixmap(images[status]);
+ if(flash) this->flash(0);
+ if(flush) this->flush();
+ return 0;
+}
+
+void BC_Toggle::enable()
+{
+ enabled = 1;
+ if(parent_window) draw_face(1, 1);
+}
+
+void BC_Toggle::disable()
+{
+ enabled = 0;
+ if(parent_window) draw_face(1, 1);
+}
+
+void BC_Toggle::set_status(int value)
+{
+ this->status = value;
+}
+
+
+int BC_Toggle::repeat_event(int64_t duration)
+{
+ if(tooltip_text && tooltip_text[0] != 0 && !tooltip_done &&
+ duration == top_level->get_resources()->tooltip_delay &&
+ (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI))
+ {
+ show_tooltip();
+ tooltip_done = 1;
+ return 1;
+ }
+ return 0;
+}
+
+int BC_Toggle::cursor_enter_event()
+{
+ if(top_level->event_win == win && enabled)
+ {
+ tooltip_done = 0;
+ if(top_level->button_down)
+ status = BC_Toggle::TOGGLE_DOWN;
+ else
+ status = value ? BC_Toggle::TOGGLE_CHECKEDHI : BC_Toggle::TOGGLE_UPHI;
+ draw_face(1, 1);
+ }
+ return 0;
+}
+
+int BC_Toggle::cursor_leave_event()
+{
+ hide_tooltip();
+ if(!value && status == BC_Toggle::TOGGLE_UPHI)
+ {
+ status = BC_Toggle::TOGGLE_UP;
+ draw_face(1, 1);
+ }
+ else
+ if(status == BC_Toggle::TOGGLE_CHECKEDHI)
+ {
+ status = BC_Toggle::TOGGLE_CHECKED;
+ draw_face(1, 1);
+ }
+ return 0;
+}
+
+int BC_Toggle::button_press_event()
+{
+ hide_tooltip();
+ if(top_level->event_win == win && get_buttonpress() == 1 && enabled)
+ {
+ status = BC_Toggle::TOGGLE_DOWN;
+
+// Change value now for select drag mode.
+// Radial always goes to 1
+ if(select_drag)
+ {
+ if(!is_radial)
+ value = !value;
+ else
+ value = 1;
+ top_level->toggle_drag = 1;
+ top_level->toggle_value = value;
+ handle_event();
+ }
+
+ draw_face(1, 1);
+ return 1;
+ }
+ return 0;
+}
+
+int BC_Toggle::button_release_event()
+{
+ int result = 0;
+ hide_tooltip();
+
+ if(top_level->event_win == win)
+ {
+// Keep value regardless of status if drag mode.
+ if(select_drag)
+ {
+ if(value)
+ status = BC_Toggle::TOGGLE_CHECKEDHI;
+ else
+ status = BC_Toggle::TOGGLE_UPHI;
+ top_level->toggle_drag = 0;
+ }
+ else
+// Change value only if button down for default mode.
+ if(status == BC_Toggle::TOGGLE_DOWN)
+ {
+// Radial always goes to 1.
+ if(!value || is_radial)
+ {
+ status = BC_Toggle::TOGGLE_CHECKEDHI;
+ value = 1;
+ }
+ else
+ {
+ status = BC_Toggle::TOGGLE_UPHI;
+ value = 0;
+ }
+ result = handle_event();
+ }
+ draw_face(1, 1);
+ return result;
+ }
+ return 0;
+}
+
+int BC_Toggle::cursor_motion_event()
+{
+ if(top_level->button_down &&
+ top_level->event_win == win &&
+ !cursor_inside())
+ {
+ if(status == BC_Toggle::TOGGLE_DOWN)
+ {
+ if(value)
+ status = BC_Toggle::TOGGLE_CHECKED;
+ else
+ status = BC_Toggle::TOGGLE_UP;
+ draw_face(1, 1);
+ }
+ else
+ if(status == BC_Toggle::TOGGLE_UPHI)
+ {
+ status = BC_Toggle::TOGGLE_CHECKEDHI;
+ draw_face(1, 1);
+ }
+ }
+ return 0;
+}
+
+int BC_Toggle::get_value()
+{
+ return value;
+}
+
+int BC_Toggle::set_value(int value, int draw)
+{
+ if(value != this->value)
+ {
+ this->value = value;
+ if(value)
+ {
+ switch(status)
+ {
+ case BC_Toggle::TOGGLE_UP:
+ status = BC_Toggle::TOGGLE_CHECKED;
+ break;
+ case BC_Toggle::TOGGLE_UPHI:
+ status = BC_Toggle::TOGGLE_CHECKEDHI;
+ break;
+ }
+ }
+ else
+ switch(status)
+ {
+ case BC_Toggle::TOGGLE_CHECKED:
+ status = BC_Toggle::TOGGLE_UP;
+ break;
+ case BC_Toggle::TOGGLE_CHECKEDHI:
+ status = BC_Toggle::TOGGLE_UPHI;
+ break;
+ }
+ if(draw) draw_face(1, 1);
+ }
+ return 0;
+}
+
+int BC_Toggle::update(int value, int draw)
+{
+ return set_value(value, draw);
+}
+
+void BC_Toggle::reposition_window(int x, int y)
+{
+ BC_WindowBase::reposition_window(x, y);
+ draw_face(1, 0);
+}
+
+
+int BC_Toggle::has_caption()
+{
+ return (caption != 0 && caption[0] != 0);
+}
+
+BC_Radial::BC_Radial(int x,
+ int y,
+ int value,
+ const char *caption,
+ int font,
+ int color)
+ : BC_Toggle(x,
+ y,
+ BC_WindowBase::get_resources()->radial_images,
+ value,
+ caption,
+ 0,
+ font,
+ color)
+{
+ is_radial = 1;
+}
+
+BC_CheckBox::BC_CheckBox(int x,
+ int y,
+ int value,
+ const char *caption,
+ int font,
+ int color)
+ : BC_Toggle(x,
+ y,
+ BC_WindowBase::get_resources()->checkbox_images,
+ value,
+ caption,
+ 0,
+ font,
+ color)
+{
+ this->value = 0;
+}
+
+BC_CheckBox::BC_CheckBox(int x,
+ int y,
+ int *value,
+ const char *caption,
+ int font,
+ int color)
+ : BC_Toggle(x,
+ y,
+ BC_WindowBase::get_resources()->checkbox_images,
+ *value,
+ caption,
+ 1,
+ font,
+ color)
+{
+ this->value = value;
+}
+
+void BC_CheckBox::calculate_extents(BC_WindowBase *gui, int *w, int *h,
+ const char *caption, int font)
+{
+ int text_line, toggle_x, toggle_y;
+ int text_x, text_y, text_w, text_h;
+
+ BC_Toggle::calculate_extents(gui,
+ BC_WindowBase::get_resources()->checkbox_images,
+ 1, &text_line, w, h, &toggle_x, &toggle_y,
+ &text_x, &text_y, &text_w, &text_h, caption, font);
+}
+
+int BC_CheckBox::handle_event()
+{
+ if( value )
+ *value = get_value();
+ return 1;
+}
+
+
+
+BC_Label::BC_Label(int x,
+ int y,
+ int value,
+ int font,
+ int color)
+ : BC_Toggle(x,
+ y,
+ BC_WindowBase::get_resources()->label_images,
+ value,
+ "",
+ 0,
+ font,
+ color)
+{
+}