+++ /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 "bcpan.h"
-#include "bcpixmap.h"
-#include "bcpopup.h"
-#include "bcresources.h"
-#include "clip.h"
-#include "colors.h"
-#include "fonts.h"
-#include "rotateframe.h"
-#include "units.h"
-#include "vframe.h"
-
-#include <math.h>
-#include <string.h>
-
-BC_Pan::BC_Pan(int x,
- int y,
- int virtual_r,
- float maxvalue,
- int total_values,
- int *value_positions,
- int stick_x,
- int stick_y,
- float *values)
- : BC_SubWindow(x, y, -1, -1, -1)
-{
- this->virtual_r = virtual_r;
- this->maxvalue = maxvalue;
- this->total_values = total_values;
- this->values = new float[total_values];
- memcpy(this->values, values, sizeof(float) * total_values);
- this->value_positions = new int[total_values];
- memcpy(this->value_positions, value_positions, sizeof(int) * total_values);
- this->value_x = new int[total_values];
- this->value_y = new int[total_values];
- this->stick_x = stick_x;
- this->stick_y = stick_y;
- get_channel_positions(value_x,
- value_y,
- value_positions,
- virtual_r,
- total_values);
- if(stick_x < 0 || stick_y < 0)
- calculate_stick_position(total_values,
- value_positions,
- values,
- maxvalue,
- virtual_r,
- this->stick_x,
- this->stick_y);
- highlighted = 0;
- popup = 0;
- active = 0;
- memset(images, 0, sizeof(BC_Pixmap*) * PAN_IMAGES);
-}
-
-BC_Pan::~BC_Pan()
-{
-//printf("BC_Pan::~BC_Pan 1\n");
- delete [] values;
-//printf("BC_Pan::~BC_Pan 1\n");
- delete [] value_positions;
-//printf("BC_Pan::~BC_Pan 1\n");
- delete [] value_x;
-//printf("BC_Pan::~BC_Pan 1\n");
- delete [] value_y;
-//printf("BC_Pan::~BC_Pan 1\n");
- if(popup) delete popup;
-//printf("BC_Pan::~BC_Pan 1\n");
- delete temp_channel;
-//printf("BC_Pan::~BC_Pan 1\n");
- delete rotater;
- for(int i = 0; i < PAN_IMAGES; i++)
- if(images[i]) delete images[i];
-//printf("BC_Pan::~BC_Pan 2\n");
-}
-
-int BC_Pan::initialize()
-{
- set_images(get_resources()->pan_data);
-
- BC_SubWindow::initialize();
- temp_channel = new VFrame;
- temp_channel->set_use_shm(0);
- temp_channel->reallocate(0,
- -1,
- 0,
- 0,
- 0,
- get_resources()->pan_data[PAN_CHANNEL]->get_w(),
- get_resources()->pan_data[PAN_CHANNEL]->get_h(),
- get_resources()->pan_data[PAN_CHANNEL]->get_color_model(),
- -1);
- rotater = new RotateFrame(1,
- get_resources()->pan_data[PAN_CHANNEL]->get_w(),
- get_resources()->pan_data[PAN_CHANNEL]->get_h());
- draw(1, 0);
- return 0;
-}
-
-void BC_Pan::set_images(VFrame **data)
-{
- for(int i = 0; i < PAN_IMAGES; i++)
- {
- if(images[i]) delete images[i];
- images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
- }
- w = images[PAN_UP]->get_w();
- h = images[PAN_UP]->get_h();
-}
-
-int BC_Pan::button_press_event()
-{
- // there are two modes of operation...
- if (popup)
- { if (popup->is_event_win() && get_button_down() && get_buttonpress() == 1)
- {
- active = 1;
- x_origin = popup->get_cursor_x();
- y_origin = popup->get_cursor_y();
- stick_x_origin = stick_x;
- stick_y_origin = stick_y;
- return 1;
- } else
- {
- deactivate();
- return 0;
- }
- }
- if(is_event_win() && get_button_down() && get_buttonpress() == 1)
- {
- hide_tooltip();
- activate();
- active = 1;
- x_origin = get_cursor_x();
- y_origin = get_cursor_y();
- stick_x_origin = stick_x;
- stick_y_origin = stick_y;
- draw_popup();
- return 1;
- }
- return 0;
-}
-
-int BC_Pan::cursor_motion_event()
-{
- if(popup && get_button_down() && get_buttonpress() == 1)
- {
- stick_x = stick_x_origin + get_cursor_x() - x_origin;
- stick_y = stick_y_origin + get_cursor_y() - y_origin;
- CLAMP(stick_x, 0, virtual_r * 2);
- CLAMP(stick_y, 0, virtual_r * 2);
- stick_to_values();
- draw_popup();
- handle_event();
- return 1;
- }
- return 0;
-}
-
-int BC_Pan::button_release_event()
-{
- if(popup)
- {
- hide_tooltip();
- deactivate();
- draw(1, 1);
- return 1;
- }
- return 0;
-}
-
-int BC_Pan::repeat_event(int64_t duration)
-{
- if( highlighted && !active && !tooltip_done &&
- tooltip_text && tooltip_text[0] != 0 &&
- duration == top_level->get_resources()->tooltip_delay )
- {
- show_tooltip();
- tooltip_done = 1;
- return 1;
- }
- return 0;
-}
-
-int BC_Pan::cursor_enter_event()
-{
- if(is_event_win() && !highlighted)
- {
- tooltip_done = 0;
- highlighted = 1;
- draw(1, 1);
- }
- return 0;
-}
-
-int BC_Pan::cursor_leave_event()
-{
- if(highlighted)
- {
- highlighted = 0;
- hide_tooltip();
- draw(1, 1);
- }
- return 0;
-}
-
-
-
-int BC_Pan::deactivate()
-{
- if(popup) delete popup;
- popup = 0;
- active = 0;
- return 0;
-}
-
-int BC_Pan::activate(int popup_x, int popup_y)
-{
- int x, y;
- Window tempwin;
-
- active = 0;
- if (popup_x < 0 || popup_y < 0)
- {
- XTranslateCoordinates(top_level->display,
- win,
- top_level->rootwin,
- 0,
- 0,
- &x,
- &y,
- &tempwin);
-
- x -= (images[PAN_POPUP]->get_w() - get_w()) / 2;
- y -= (images[PAN_POPUP]->get_h() - get_h()) / 2;
- if (x < 0) x = 0;
- }
- else {
- XTranslateCoordinates(top_level->display,
- top_level->win, top_level->rootwin,
- popup_x, popup_y, &x, &y, &tempwin);
- x -= images[PAN_POPUP]->get_w() / 2;
- y -= images[PAN_POPUP]->get_h() / 2;
- if (x < 0) x = 0;
- }
-
- delete popup;
- popup = new BC_Popup(this, x, y,
- images[PAN_POPUP]->get_w(),
- images[PAN_POPUP]->get_h(),
- 0, 0, images[PAN_POPUP]);
- draw_popup();
- flush();
- return 0;
-}
-
-int BC_Pan::update(int x, int y)
-{
- if(x != stick_x || y != stick_y)
- {
- stick_x = x;
- stick_y = y;
- stick_to_values();
- draw(1, 1);
- }
- return 0;
-}
-
-void BC_Pan::draw_popup()
-{
- popup->draw_background(0, 0, popup->get_w(), popup->get_h());
-
- int x1, y1;
- float rotate_angle;
- float scale = (float)(popup->get_w() -
- get_resources()->pan_data[PAN_CHANNEL]->get_w()) /
- (virtual_r * 2);
- set_color(get_resources()->pan_text_color);
- set_font(SMALLFONT);
-
- for(int i = 0; i < total_values; i++)
- {
- x1 = (int)(value_x[i] * scale);
- y1 = (int)(value_y[i] * scale);
- rotate_angle = value_positions[i];
- rotate_angle = -rotate_angle;
- while(rotate_angle < 0) rotate_angle += 360;
- rotater->rotate(temp_channel,
- get_resources()->pan_data[PAN_CHANNEL],
- rotate_angle,
- 0);
- BC_Pixmap *temp_pixmap = new BC_Pixmap(popup,
- temp_channel,
- PIXMAP_ALPHA);
- popup->draw_pixmap(temp_pixmap, x1, y1);
- delete temp_pixmap;
-
- char string[BCTEXTLEN];
- float value = values[i] + 0.005;
- sprintf(string, "%.1f", value);
- popup->draw_text(x1, y1 + get_text_height(SMALLFONT), string);
- }
-
- x1 = (int)(stick_x * scale);
- y1 = (int)(stick_y * scale);
- popup->draw_pixmap(images[PAN_STICK], x1, y1);
- popup->flash();
-}
-
-#define PICON_W 6
-#define PICON_H 6
-
-void BC_Pan::draw(int flash, int flush)
-{
- draw_top_background(parent_window, 0, 0, w, h);
-
- draw_pixmap(images[highlighted ? PAN_HI : PAN_UP]);
- get_channel_positions(value_x,
- value_y,
- value_positions,
- virtual_r,
- total_values);
-
-// draw channels
- int x1, y1;
- float scale = (float)(get_w() - PICON_W) / (virtual_r * 2);
- set_color(RED);
-
- for(int i = 0; i < total_values; i++)
- {
-// printf("BC_Pan::draw 1 %d %d %d %d\n",
-// i,
-// value_positions[i],
-// value_x[i],
-// value_y[i]);
- x1 = (int)(value_x[i] * scale);
- y1 = (int)(value_y[i] * scale);
-//printf("BC_Pan::draw 2 %d %d\n", x1, y1);
- CLAMP(x1, 0, get_w() - PICON_W);
- CLAMP(y1, 0, get_h() - PICON_H);
- draw_pixmap(images[PAN_CHANNEL_SMALL], x1, y1);
-// draw_box(x1, y1, PICON_W, PICON_H);
- }
-
-// draw stick
- set_color(GREEN);
- x1 = (int)(stick_x * scale);
- y1 = (int)(stick_y * scale);
-
-//printf("BC_Pan::draw 2 %d %d\n", x1, y1);
- CLAMP(x1, 0, get_w() - PICON_W);
- CLAMP(y1, 0, get_h() - PICON_H);
-
- draw_pixmap(images[PAN_STICK_SMALL], x1, y1);
-// x2 = x1 + PICON_W;
-// y2 = y1 + PICON_H;
-// draw_line(x1, y1, x2, y2);
-// draw_line(x2, y1, x1, y2);
-
- if(flash) this->flash(0);
- if(flush) this->flush();
-}
-
-int BC_Pan::stick_to_values()
-{
- return stick_to_values(values,
- total_values,
- value_positions,
- stick_x,
- stick_y,
- virtual_r,
- maxvalue);
-}
-
-int BC_Pan::stick_to_values(float *values,
- int total_values,
- int *value_positions,
- int stick_x,
- int stick_y,
- int virtual_r,
- float maxvalue)
-{
-// find shortest distance to a channel
- float shortest = 2 * virtual_r, test_distance;
- int i;
- int *value_x = new int[total_values];
- int *value_y = new int[total_values];
-
- get_channel_positions(value_x, value_y, value_positions, virtual_r, total_values);
- for(i = 0; i < total_values; i++)
- {
- if((test_distance = distance(stick_x,
- value_x[i],
- stick_y,
- value_y[i])) < shortest)
- shortest = test_distance;
- }
-
-// get values for channels
- if(shortest == 0)
- {
- for(i = 0; i < total_values; i++)
- {
- if(distance(stick_x, value_x[i], stick_y, value_y[i]) == shortest)
- values[i] = maxvalue;
- else
- values[i] = 0;
- }
- }
- else
- {
- for(i = 0; i < total_values; i++)
- {
- values[i] = shortest;
- values[i] -= (float)(distance(stick_x,
- value_x[i],
- stick_y,
- value_y[i]) - shortest);
- if(values[i] < 0) values[i] = 0;
- values[i] = values[i] / shortest * maxvalue;
- }
- }
-
- for(i = 0; i < total_values; i++)
- {
- values[i] = Units::quantize10(values[i]);
- }
-
- delete [] value_x;
- delete [] value_y;
- return 0;
-}
-
-
-float BC_Pan::distance(int x1, int x2, int y1, int y2)
-{
- return hypot(x2 - x1, y2 - y1);
-}
-
-int BC_Pan::change_channels(int new_channels, int *value_positions)
-{
- delete values;
- delete this->value_positions;
- delete value_x;
- delete value_y;
-
- values = new float[new_channels];
- this->value_positions = new int[new_channels];
- value_x = new int[new_channels];
- value_y = new int[new_channels];
- total_values = new_channels;
- for(int i = 0; i < new_channels; i++)
- {
- this->value_positions[i] = value_positions[i];
- }
- get_channel_positions(value_x,
- value_y,
- value_positions,
- virtual_r,
- total_values);
- stick_to_values();
- draw(1, 1);
- return 0;
-}
-
-int BC_Pan::get_channel_positions(int *value_x,
- int *value_y,
- int *value_positions,
- int virtual_r,
- int total_values)
-{
- for(int i = 0; i < total_values; i++)
- {
- rdtoxy(value_x[i], value_y[i], value_positions[i], virtual_r);
- }
- return 0;
-}
-
-int BC_Pan::get_total_values()
-{
- return total_values;
-}
-
-float BC_Pan::get_value(int channel)
-{
- return values[channel];
-}
-
-int BC_Pan::get_stick_x()
-{
- return stick_x;
-}
-
-int BC_Pan::get_stick_y()
-{
- return stick_y;
-}
-
-float* BC_Pan::get_values()
-{
- return values;
-}
-
-int BC_Pan::rdtoxy(int &x, int &y, int a, int virtual_r)
-{
- float radians = (float)a / 360 * 2 * M_PI;
-
- y = (int)(sin(radians) * virtual_r);
- x = (int)(cos(radians) * virtual_r);
- x += virtual_r;
- y = virtual_r - y;
- return 0;
-}
-
-void BC_Pan::calculate_stick_position(int total_values,
- int *value_positions,
- float *values,
- float maxvalue,
- int virtual_r,
- int &stick_x,
- int &stick_y)
-{
-// If 2 channels have positive values, use weighted average
- int channel1 = -1;
- int channel2 = -1;
-
- for(int i = 0; i < total_values; i++)
- {
- if(values[i] > 0.001)
- {
- if(channel1 < 0) channel1 = i;
- else
- if(channel2 < 0) channel2 = i;
- else
- break;
- }
- }
-
- if(channel1 >= 0 && channel2 >= 0)
- {
- int x1, y1, x2, y2;
- rdtoxy(x1, y1, value_positions[channel1], virtual_r);
- rdtoxy(x2, y2, value_positions[channel2], virtual_r);
- stick_x = (x1 + x2) / 2;
- stick_y = (y1 + y2) / 2;
- }
- else
- {
-
-// use highest value as location of stick
- float highest_value = 0;
- int angle = 0;
-
- for(int i = 0; i < total_values; i++)
- {
- if(values[i] > highest_value)
- {
- highest_value = values[i];
- angle = value_positions[i];
- }
- }
- rdtoxy(stick_x, stick_y, angle, virtual_r);
- }
-
-}
-