/* * This file is part of RawTherapee. * * Copyright (c) 2004-2010 Gabor Horvath * * RawTherapee 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 3 of the License, or * (at your option) any later version. * * RawTherapee 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 RawTherapee. If not, see . */ #include "coloredbar.h" ColoredBar::ColoredBar (eRTOrientation orient) { orientation = orient; dirty = true; this->x = this->y = this->w = this->h = 0; } /* * Redraw the bar to a Cairo::ImageSurface */ void ColoredBar::expose(Cairo::RefPtr destSurface) { // look out if the Surface has to be redrawn if (!surfaceCreated() || !destSurface) { return; } draw(); copySurface(destSurface); } /* * Redraw the bar to a Gdk::Window */ void ColoredBar::expose(Glib::RefPtr destWindow) { // look out if the Surface has to be redrawn if (!surfaceCreated() || !destWindow) { return; } draw(); copySurface(destWindow); } /* * Redraw the bar to a Gdk::Window */ void ColoredBar::expose(BackBuffer *backBuffer) { // look out if the Surface has to be redrawn if (!surfaceCreated() || !backBuffer) { return; } draw(); copySurface(backBuffer); } void ColoredBar::draw() { if (isDirty()) { Cairo::RefPtr cr = getContext(); // the bar has to be drawn to the Surface first if (!bgGradient.empty()) { // a gradient has been set, we use it cr->set_line_width(0.); // gradient background Cairo::RefPtr< Cairo::LinearGradient > bggradient; switch (orientation) { case (RTO_Left2Right): bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.); break; case (RTO_Right2Left): bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.); break; case (RTO_Bottom2Top): bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.); break; case (RTO_Top2Bottom): default: bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h)); break; } for (std::vector::iterator i = bgGradient.begin(); i != bgGradient.end(); i++) { bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b); } cr->set_source (bggradient); cr->rectangle(0, 0, w, h); cr->fill(); } else { // ask the ColorProvider to provide colors :) for each pixels if (colorProvider) { cr->set_antialias(Cairo::ANTIALIAS_NONE); cr->set_line_width(1.); switch (orientation) { case (RTO_Left2Right): for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { double x_ = double( x); double y_ = double((h - 1) - y); double x01 = x_ / double(w - 1); double y01 = double(y) / double(h - 1); colorProvider->colorForValue (x01, y01, CCET_BACKGROUND, colorCallerId, this); cr->set_source_rgb(ccRed, ccGreen, ccBlue); cr->rectangle(x_, y_, 1., 1.); cr->fill(); } } break; case (RTO_Right2Left): for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { double x_ = double((w - 1) - x); double y_ = double((h - 1) - y); double x01 = double(x) / double(w - 1); double y01 = double(y) / double(h - 1); colorProvider->colorForValue (x01, y01, CCET_BACKGROUND, colorCallerId, this); cr->set_source_rgb(ccRed, ccGreen, ccBlue); cr->rectangle(x_, y_, 1., 1.); cr->fill(); } } break; case (RTO_Bottom2Top): for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { double x_ = double((w - 1) - x); double y_ = double((h - 1) - y); double x01 = double(x) / double(w - 1); double y01 = double(y) / double(h - 1); colorProvider->colorForValue (y01, x01, CCET_BACKGROUND, colorCallerId, this); cr->set_source_rgb(ccRed, ccGreen, ccBlue); cr->rectangle(x_, y_, 1., 1.); cr->fill(); } } break; case (RTO_Top2Bottom): default: for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { double x_ = double( x); double y_ = double( y); double x01 = x_ / double(w - 1); double y01 = y_ / double(h - 1); colorProvider->colorForValue (y01, x01, CCET_BACKGROUND, colorCallerId, this); cr->set_source_rgb(ccRed, ccGreen, ccBlue); cr->rectangle(x_, y_, 1., 1.); cr->fill(); } } break; } } } // has it been updated or not, we assume that the Surface has been correctly set (we don't handle allocation error) setDirty(false); } } void ColoredBar::setBgGradient (const std::vector &milestones) { bgGradient = milestones; setDirty(true); } void ColoredBar::clearBgGradient () { bgGradient.clear(); setDirty(true); } bool ColoredBar::canGetColors() { return colorProvider != NULL || bgGradient.size() > 0; }