X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fcolor3way%2Fcolor3waywindow.C;fp=cinelerra-5.1%2Fplugins%2Fcolor3way%2Fcolor3waywindow.C;h=8827b4e5c97d764fa834c66815be2f3d51d7839d;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/color3way/color3waywindow.C b/cinelerra-5.1/plugins/color3way/color3waywindow.C new file mode 100644 index 00000000..8827b4e5 --- /dev/null +++ b/cinelerra-5.1/plugins/color3way/color3waywindow.C @@ -0,0 +1,775 @@ + +/* + * CINELERRA + * Copyright (C) 1997-2011 Adam Williams + * + * 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 "bcsignals.h" +#include "color3waywindow.h" +#include "keys.h" +#include "language.h" +#include "theme.h" +#include "units.h" +#include + + + + + + + + + + +Color3WayWindow::Color3WayWindow(Color3WayMain *plugin) + : PluginClientWindow(plugin, + plugin->w, + plugin->h, + 500, + 370, + 1) +{ + this->plugin = plugin; +} + +Color3WayWindow::~Color3WayWindow() +{ +} + +void Color3WayWindow::create_objects() +{ + int margin = plugin->get_theme()->widget_border; + int x = plugin->get_theme()->widget_border; + int y = plugin->get_theme()->widget_border; + + for(int i = 0; i < SECTIONS; i++) + { + sections[i] = new Color3WaySection(plugin, + this, + x, + y, + (get_w() - margin * 4) / 3, + get_h() - margin * 2, + i); + sections[i]->create_objects(); + x += sections[i]->w + margin; + } + + + + flash(0); + show_window(); +} + +int Color3WayWindow::resize_event(int w, int h) +{ + int margin = plugin->get_theme()->widget_border; + int x = sections[0]->x; + int y = sections[0]->y; + + for(int i = 0; i < SECTIONS; i++) + { + sections[i]->reposition_window(x, + y, + (w - margin * 4) / 3, + w - margin * 2); + x += sections[i]->w + margin; + } + + plugin->w = w; + plugin->h = h; + flush(); + return 1; +} + + +void Color3WayWindow::update() +{ + for(int i = 0; i < SECTIONS; i++) + { + sections[i]->update(); + } +} + + + +Color3WaySection::Color3WaySection(Color3WayMain *plugin, + Color3WayWindow *gui, + int x, + int y, + int w, + int h, + int section) +{ + this->plugin = plugin; + this->gui = gui; + this->section = section; + this->x = x; + this->y = y; + this->w = w; + this->h = h; + +} + +void Color3WaySection::create_objects() +{ + int margin = plugin->get_theme()->widget_border; + int x = this->x; + int y = this->y; + const char *titles[] = + { + _("Shadows"), + _("Midtones"), + _("Highlights") + }; + + + gui->add_tool(title = new BC_Title(x + w / 2 - + gui->get_text_width(MEDIUMFONT, titles[section]) / 2, + y, + titles[section])); + y += title->get_h() + margin; + gui->add_tool(point = new Color3WayPoint(plugin, + gui, + &plugin->config.hue_x[section], + &plugin->config.hue_y[section], + x, + y, + w / 2, + section)); + y += point->get_h() + margin; + + gui->add_tool(value_title = new BC_Title(x, y, _("Value:"))); + y += value_title->get_h() + margin; + gui->add_tool(value = new Color3WaySlider(plugin, + gui, + &plugin->config.value[section], + x, + y, + w, + section)); + y += value->get_h() + margin; + + gui->add_tool(sat_title = new BC_Title(x, y, _("Saturation:"))); + y += sat_title->get_h() + margin; + gui->add_tool(saturation = new Color3WaySlider(plugin, + gui, + &plugin->config.saturation[section], + x, + y, + w, + section)); + y += saturation->get_h() + margin; + + gui->add_tool(reset = new Color3WayResetSection(plugin, + gui, + x, + y, + section)); + + y += reset->get_h() + margin; + gui->add_tool(balance = new Color3WayBalanceSection(plugin, + gui, + x, + y, + section)); + + y += balance->get_h() + margin; + gui->add_tool(copy = new Color3WayCopySection(plugin, + gui, + x, + y, + section)); +} + +int Color3WaySection::reposition_window(int x, int y, int w, int h) +{ + int margin = plugin->get_theme()->widget_border; + this->x = x; + this->y = y; + this->w = w; + this->h = h; + + title->reposition_window(x + w / 2 - + title->get_w() / 2, + title->get_y()); + point->reposition_window(x, point->get_y(), w / 2); + y = point->get_y() + point->get_h() + margin; + value_title->reposition_window(x, y); + y += value_title->get_h() + margin; + value->reposition_window(x, y, w, value->get_h()); + value->set_pointer_motion_range(w); + y += value->get_h() + margin; + + sat_title->reposition_window(x, y); + y += sat_title->get_h() + margin; + saturation->reposition_window(x, y, w, saturation->get_h()); + saturation->set_pointer_motion_range(w); + y += saturation->get_h() + margin; + reset->reposition_window(x, y); + y += reset->get_h() + margin; + balance->reposition_window(x, y); + y += balance->get_h() + margin; + copy->reposition_window(x, y); + gui->flush(); + return 0; +} + +void Color3WaySection::update() +{ + point->update(); + value->update(plugin->config.value[section]); + saturation->update(plugin->config.saturation[section]); +} + + + + + +Color3WayPoint::Color3WayPoint(Color3WayMain *plugin, + Color3WayWindow *gui, + float *x_output, + float *y_output, + int x, + int y, + int radius, + int section) + : BC_SubWindow(x, + y, + radius * 2, + radius * 2) +{ + this->plugin = plugin; + this->x_output = x_output; + this->y_output = y_output; + this->radius = radius; + this->gui = gui; + drag_operation = 0; + status = COLOR_UP; + memset(fg_images, 0, sizeof(BC_Pixmap*) * COLOR_IMAGES); + bg_image = 0; + active = 0; + this->section = section; +} + +Color3WayPoint::~Color3WayPoint() +{ + for(int i = 0; i < COLOR_IMAGES; i++) + if(fg_images[i]) delete fg_images[i]; + + delete bg_image; +} + +int Color3WayPoint::initialize() +{ + BC_SubWindow::initialize(); + + + VFrame **data = plugin->get_theme()->get_image_set("color3way_point"); + for(int i = 0; i < COLOR_IMAGES; i++) + { + if(fg_images[i]) delete fg_images[i]; + fg_images[i] = new BC_Pixmap(gui, data[i], PIXMAP_ALPHA); + } + + + draw_face(1, 0); + + return 0; +} + +int Color3WayPoint::reposition_window(int x, int y, int radius) +{ + this->radius = radius; + BC_SubWindow::reposition_window(x, y, radius * 2, radius * 2); + + delete bg_image; + bg_image = 0; + draw_face(1, 0); + return 0; +} + +void Color3WayPoint::draw_face(int flash, int flush) +{ +// Draw the color wheel + if(!bg_image) + { + VFrame frame(0, -1, radius * 2, radius * 2, BC_RGB888, -1); + for(int i = 0; i < radius * 2; i++) + { + unsigned char *row = frame.get_rows()[i]; + for(int j = 0; j < radius * 2; j++) + { + float point_radius = sqrt(SQR(i - radius) + SQR(j - radius)); + int r, g, b; + + if(point_radius < radius - 1) + { + float r_f, g_f, b_f; + float angle = atan2((float)(j - radius) / radius, + (float)(i - radius) / radius) * + 360 / + 2 / + M_PI; + angle -= 180; + while(angle < 0) + angle += 360; + HSV::hsv_to_rgb(r_f, g_f, b_f, angle, point_radius / radius, 1.0); + r = (int)(r_f * 0xff); + g = (int)(g_f * 0xff); + b = (int)(b_f * 0xff); + } + else + if(point_radius < radius) + { + if(radius * 2 - i < j) + { + r = MEGREY >> 16; + g = (MEGREY >> 8) & 0xff; + b = MEGREY & 0xff; + } + else + { + r = 0; + g = 0; + b = 0; + } + } + else + { + r = (gui->get_bg_color() & 0xff0000) >> 16; + g = (gui->get_bg_color() & 0xff00) >> 8; + b = (gui->get_bg_color() & 0xff); + } + + *row++ = r; + *row++ = g; + *row++ = b; + } + } + + bg_image = new BC_Pixmap(get_parent(), &frame, PIXMAP_ALPHA); + } + + draw_pixmap(bg_image); + +// set_color(BLACK); +// draw_arc(0, 0, radius * 2, radius * 2, 45, 180); +// +// set_color(MEGREY); +// draw_arc(0, 0, radius * 2, radius * 2, 45, -180); + + + fg_x = (int)(*x_output * (radius - fg_images[0]->get_w() / 2) + radius) - + fg_images[0]->get_w() / 2; + fg_y = (int)(*y_output * (radius - fg_images[0]->get_h() / 2) + radius) - + fg_images[0]->get_h() / 2; + + draw_pixmap(fg_images[status], fg_x, fg_y); + +// Text + if(active) + { + int margin = plugin->get_theme()->widget_border; + set_color(BLACK); + set_font(MEDIUMFONT); + char string[BCTEXTLEN]; + + sprintf(string, "%.3f", *y_output); + draw_text(radius - get_text_width(MEDIUMFONT, string) / 2, + get_text_ascent(MEDIUMFONT) + margin, + string); + + sprintf(string, "%.3f", *x_output); + draw_text(margin, + radius + get_text_ascent(MEDIUMFONT) / 2, + string); + + +// float r_factor; +// float g_factor; +// float b_factor; +// plugin->calculate_factors(&r_factor, &g_factor, &b_factor, section); +// +// sprintf(string, "%.3f", r_factor); +// draw_text(radius - get_text_width(MEDIUMFONT, string) / 2, +// get_text_ascent(MEDIUMFONT) + margin, +// string); +// +// sprintf(string, "%.3f", g_factor); +// draw_text(margin + radius - radius * 1.0 / ROOT_2, +// radius + radius * 1.0 / ROOT_2 - margin, +// string); +// +// sprintf(string, "%.3f", b_factor); +// draw_text(radius + radius * 1.0 / ROOT_2 - margin - get_text_width(MEDIUMFONT, string), +// radius + radius * 1.0 / ROOT_2 - margin, +// string); + set_font(MEDIUMFONT); + } + + if(flash) this->flash(0); + if(flush) this->flush(); +} + +int Color3WayPoint::deactivate() +{ + if(active) + { + active = 0; + draw_face(1, 1); + } + return 1; +} + +int Color3WayPoint::activate() +{ + if(!active) + { + get_top_level()->set_active_subwindow(this); + active = 1; + } + return 1; +} + +void Color3WayPoint::update() +{ + draw_face(1, 1); +} + +int Color3WayPoint::button_press_event() +{ + if(is_event_win()) + { + status = COLOR_DN; + get_top_level()->deactivate(); + activate(); + draw_face(1, 1); + + starting_x = fg_x; + starting_y = fg_y; + offset_x = gui->get_relative_cursor_x(); + offset_y = gui->get_relative_cursor_y(); + } + return 0; +} + +int Color3WayPoint::button_release_event() +{ + if(status == COLOR_DN) + { + status = COLOR_HI; + draw_face(1, 1); + return 1; + } + return 0; +} + +int Color3WayPoint::cursor_motion_event() +{ + int cursor_x = gui->get_relative_cursor_x(); + int cursor_y = gui->get_relative_cursor_y(); + +//printf("Color3WayPoint::cursor_motion_event %d %d\n", __LINE__, status); + if(status == COLOR_DN) + { +//printf("Color3WayPoint::cursor_motion_event %d %d %d\n", __LINE__, starting_x, offset_x); + int new_x = starting_x + cursor_x - offset_x; + int new_y = starting_y + cursor_y - offset_y; + + *x_output = (float)(new_x + fg_images[0]->get_w() / 2 - radius) / + (radius - fg_images[0]->get_w() / 2); + *y_output = (float)(new_y + fg_images[0]->get_h() / 2 - radius) / + (radius - fg_images[0]->get_h() / 2); + + plugin->config.boundaries(); + if(plugin->copy_to_all[section]) plugin->config.copy_to_all(section); + plugin->send_configure_change(); + + + gui->update(); + + + handle_event(); + + + return 1; + } + + return 0; +} + +int Color3WayPoint::handle_event() +{ + return 1; +} + + +int Color3WayPoint::cursor_enter_event() +{ + if(is_event_win() && status != COLOR_HI && status != COLOR_DN) + { + status = COLOR_HI; + draw_face(1, 1); + } + return 0; +} + +int Color3WayPoint::cursor_leave_event() +{ + if(status == COLOR_HI) + { + status = COLOR_UP; + draw_face(1, 1); + } + return 0; +} + +int Color3WayPoint::keypress_event() +{ + int result = 0; + if(!active) return 0; + if(ctrl_down() || shift_down()) return 0; + + switch(get_keypress()) + { + case UP: + *y_output -= 0.001; + result = 1; + break; + case DOWN: + *y_output += 0.001; + result = 1; + break; + case LEFT: + *x_output -= 0.001; + result = 1; + break; + case RIGHT: + *x_output += 0.001; + result = 1; + break; + } + + if(result) + { + plugin->config.boundaries(); + if(plugin->copy_to_all[section]) plugin->config.copy_to_all(section); + plugin->send_configure_change(); + gui->update(); + } + return result; +} + + + + + + + + +Color3WaySlider::Color3WaySlider(Color3WayMain *plugin, + Color3WayWindow *gui, + float *output, + int x, + int y, + int w, + int section) + : BC_FSlider(x, + y, + 0, + w, + w, + -1.0, + 1.0, + *output) +{ + this->gui = gui; + this->plugin = plugin; + this->output = output; + this->section = section; + old_value = *output; + set_precision(0.001); +} + +Color3WaySlider::~Color3WaySlider() +{ +} + +int Color3WaySlider::handle_event() +{ + *output = get_value(); + if(plugin->copy_to_all[section]) plugin->config.copy_to_all(section); + plugin->send_configure_change(); + gui->update(); + return 1; +} + +char* Color3WaySlider::get_caption() +{ + sprintf(string, "%0.3f", *output); + return string; +} + + + + + +Color3WayResetSection::Color3WayResetSection(Color3WayMain *plugin, + Color3WayWindow *gui, + int x, + int y, + int section) + : BC_GenericButton(x, y, _("Reset")) +{ + this->plugin = plugin; + this->gui = gui; + this->section = section; +} + +int Color3WayResetSection::handle_event() +{ + plugin->config.hue_x[section] = 0; + plugin->config.hue_y[section] = 0; + plugin->config.value[section] = 0; + plugin->config.saturation[section] = 0; + if(plugin->copy_to_all[section]) plugin->config.copy_to_all(section); + plugin->send_configure_change(); + gui->update(); + return 1; +} + + + + + + +Color3WayCopySection::Color3WayCopySection(Color3WayMain *plugin, + Color3WayWindow *gui, + int x, + int y, + int section) + : BC_CheckBox(x, y, plugin->copy_to_all[section], _("Copy to all")) +{ + this->plugin = plugin; + this->gui = gui; + this->section = section; +} + +int Color3WayCopySection::handle_event() +{ + if(get_value()) plugin->config.copy_to_all(section); + plugin->copy_to_all[section] = get_value(); + gui->update(); + plugin->send_configure_change(); + return 1; +} + + + + + +Color3WayBalanceSection::Color3WayBalanceSection(Color3WayMain *plugin, + Color3WayWindow *gui, + int x, + int y, + int section) + : BC_GenericButton(x, y, _("White balance")) +{ + this->plugin = plugin; + this->gui = gui; + this->section = section; +} + +int Color3WayBalanceSection::handle_event() +{ +// Get colorpicker value + float r = plugin->get_red(); + float g = plugin->get_green(); + float b = plugin->get_blue(); + +// Since the transfers aren't linear, use brute force search + float step = 0.1; + float center_x = 0; + float center_y = 0; + float range = 1; + float best_diff = 255; + float new_x = 0; + float new_y = 0; + + while(step >= 0.001) + { + for(float x = center_x - range; x < center_x + range; x += step) + { + for(float y = center_y - range; y < center_y + range; y += step) + { + float new_r; + float new_g; + float new_b; + plugin->process_pixel(&new_r, + &new_g, + &new_b, + r, + g, + b, + x, + y); + float min = MIN(new_r, new_g); + min = MIN(min, new_b); + float max = MAX(new_r, new_g); + max = MAX(max, new_b); + float diff = max - min; + + if(diff < best_diff) + { + best_diff = diff; + new_x = x; + new_y = y; + } + } + } + + step /= 2; + range /= 2; + center_x = new_x; + center_y = new_y; + } + + new_x = Units::quantize(new_x, 0.001); + new_y = Units::quantize(new_y, 0.001); + + plugin->config.hue_x[section] = new_x; + plugin->config.hue_y[section] = new_y; + plugin->config.boundaries(); + if(plugin->copy_to_all[section]) plugin->config.copy_to_all(section); + plugin->send_configure_change(); + + + gui->update(); + + return 1; +} + + + + + + + + +