Remove unused sources & includes

This commit is contained in:
Robin Gareus 2017-07-17 00:00:11 +02:00
parent f6e182b937
commit b5e9451bc7
44 changed files with 5 additions and 3536 deletions

View File

@ -55,8 +55,6 @@
#include <gtkmm/adjustment.h>
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/stateful_button.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/visibility_tracker.h"

View File

@ -35,7 +35,6 @@
#include "pbd/basename.h"
#include "pbd/fastlog.h"
#include "gtkmm2ext/cairocell.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/window_title.h"

View File

@ -26,7 +26,6 @@
#include <gtkmm/style.h>
#include <sigc++/bind.h>
#include "gtkmm2ext/cairocell.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/rgb_macros.h"

View File

@ -32,8 +32,6 @@
#include "pbd/memento_command.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/selector.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/utils.h"
#include "widgets/ardour_button.h"

View File

@ -28,7 +28,6 @@
#include <gtkmm/radiomenuitem.h>
#include <gtkmm/checkmenuitem.h>
#include <gtkmm2ext/selector.h>
#include <list>
#include "ardour/types.h"

View File

@ -30,7 +30,6 @@
#include "pbd/i18n.h"
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/selector.h>
#include <gtkmm2ext/gtk_ui.h>
#include "ardour/selection.h"

View File

@ -58,9 +58,8 @@
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/eventboxext.h"
#include "gtkmm2ext/grouped_buttons.h"
#include "gtkmm2ext/gtk_ui.h"
#include <gtkmm2ext/keyboard.h>
#include "gtkmm2ext/keyboard.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/window_title.h"
#include "gtkmm2ext/choice.h"

View File

@ -37,8 +37,6 @@
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/dndtreeview.h"
#include "gtkmm2ext/pane.h"
#include "gtkmm2ext/selector.h"
#include "gtkmm2ext/stateful_button.h"
#include "pbd/stateful.h"
#include "pbd/signals.h"
@ -114,7 +112,6 @@ class EditorRoutes;
class EditorRouteGroups;
class EditorSnapshots;
class EditorSummary;
class GroupedButtons;
class GUIObjectState;
class ArdourMarker;
class MidiRegionView;

View File

@ -20,7 +20,6 @@
#ifndef __gtk_ardour_editor_route_groups_h__
#define __gtk_ardour_editor_route_groups_h__
#include "gtkmm2ext/stateful_button.h"
#include "editor_component.h"
class EditorRouteGroups : public EditorComponent, public ARDOUR::SessionHandlePtr

View File

@ -29,6 +29,7 @@
#include "gtkmm/button.h"
#include "gtkmm/radiobutton.h"
#include "gtkmm/label.h"
#include "gtkmm2ext/stateful_button.h"
#include "ardour/types.h"

View File

@ -35,8 +35,6 @@
#include "pbd/stateful_diff_command.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/selector.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/utils.h"
#include "widgets/tooltips.h"

View File

@ -29,8 +29,6 @@
#include <gtkmm/radiomenuitem.h>
#include <gtkmm/checkmenuitem.h>
#include "gtkmm2ext/selector.h"
#include "ardour/types.h"
#include "ardour/region.h"

View File

@ -32,7 +32,6 @@
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/choice.h"
#include "gtkmm2ext/doi.h"
#include "gtkmm2ext/bindable_button.h"
#include "widgets/tooltips.h"

View File

@ -34,9 +34,6 @@
#include <gtkmm/textview.h>
#include <gtkmm/adjustment.h>
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/stateful_button.h"
#include "pbd/stateful.h"
#include "ardour/types.h"

View File

@ -23,7 +23,6 @@
#include "pbd/error.h"
#include "pbd/replace_all.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/tearoff.h"
#include "gtkmm2ext/actions.h"
#include "gtkmm2ext/utils.h"

View File

@ -21,7 +21,6 @@
#include <gtkmm/table.h>
#include <gtkmm/eventbox.h>
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/bindings.h"
#include "widgets/ardour_button.h"

View File

@ -26,7 +26,7 @@
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/button.h>
#include <gtkmm/treeview.h>
#include <gtkmm2ext/selector.h>
#include <gtkmm/treestore.h>
#include "ardour_dialog.h"
#include "ardour/session_handle.h"

View File

@ -24,7 +24,6 @@
#include <gtkmm/notebook.h>
#include <gtkmm/treeview.h>
#include "gtkmm2ext/dndtreeview.h"
#include <gtkmm2ext/selector.h>
#include "ardour/plugin.h"
#include "ardour/session_handle.h"

View File

@ -38,8 +38,6 @@
#include "gtkmm/menu.h"
#include "gtkmm/menuitem.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/selector.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/utils.h"
#include "widgets/ardour_button.h"

View File

@ -32,8 +32,6 @@
#include <gtkmm/checkmenuitem.h>
#include <gtkmm/adjustment.h>
#include <gtkmm2ext/selector.h>
#include "widgets/ardour_button.h"
#include "ardour/playlist.h"

View File

@ -23,7 +23,6 @@
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/choice.h"
#include "gtkmm2ext/doi.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/utils.h"
@ -1431,10 +1430,6 @@ RouteUI::build_solo_menu (void)
items.push_back (CheckMenuElem(*check));
solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
check->show_all();
//items.push_back (SeparatorElem());
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
}
void
@ -1471,9 +1466,6 @@ RouteUI::build_mute_menu(void)
items.push_back (CheckMenuElem(*main_mute_check));
main_mute_check->show_all();
//items.push_back (SeparatorElem());
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
_route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
}

View File

@ -29,7 +29,6 @@
#include "gtkmm2ext/keyboard.h"
#include "gtkmm2ext/gui_thread.h"
#include "gtkmm2ext/cairocell.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/rgb_macros.h"

View File

@ -31,7 +31,6 @@
#include <gtkmm2ext/doi.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/selector.h>
#include "canvas/canvas.h"
#include "canvas/rectangle.h"

View File

@ -20,10 +20,8 @@
#include <algorithm>
#include "pbd/compose.h"
#include "gtkmm2ext/cairocell.h"
#include "gtkmm2ext/gui_thread.h"
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/stateful_button.h"
#include "gtkmm2ext/actions.h"
#include "ardour/location.h"

View File

@ -26,11 +26,11 @@
#include <gtkmm/label.h>
#include <gtkmm/table.h>
#include "gtkmm2ext/cairo_packer.h"
#include "ardour/ardour.h"
#include "ardour/session_handle.h"
#include "gtkmm2ext/cairo_packer.h"
namespace ARDOUR {
class Session;
class Location;

View File

@ -1,60 +0,0 @@
/*
Copyright (C) 2004 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <string>
#include <iostream>
#include "pbd/controllable.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/gui_thread.h"
#include "pbd/i18n.h"
using namespace Gtkmm2ext;
using namespace std;
using namespace PBD;
void
BindableToggleButton::set_controllable (boost::shared_ptr<PBD::Controllable> c)
{
watch_connection.disconnect ();
binding_proxy.set_controllable (c);
}
void
BindableToggleButton::watch ()
{
boost::shared_ptr<Controllable> c (binding_proxy.get_controllable ());
if (!c) {
warning << _("button cannot watch state of non-existing Controllable\n") << endl;
return;
}
c->Changed.connect (watch_connection, invalidator(*this), boost::bind (&BindableToggleButton::controllable_changed, this), gui_context());
}
void
BindableToggleButton::controllable_changed ()
{
float val = binding_proxy.get_controllable()->get_value();
set_active (fabs (val) >= 0.5f);
}

View File

@ -1,114 +0,0 @@
/*
Copyright (C) 2015 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
#define OPTIONAL_CAIRO_IMAGE_SURFACE
#endif
#include "gtkmm2ext/cairo_icon.h"
#include "gtkmm2ext/gtk_ui.h"
using namespace Gtkmm2ext;
CairoIcon::CairoIcon (ArdourIcon::Icon t, uint32_t foreground_color)
: icon_type (t)
, fg (foreground_color)
{
add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
}
CairoIcon::~CairoIcon ()
{
}
void
CairoIcon::set_fg (uint32_t color)
{
fg = color;
queue_draw ();
}
void
CairoIcon::render (cairo_t* cr , cairo_rectangle_t* area)
{
int width = get_width();
int height = get_height ();
ArdourIcon::render (cr, icon_type, width, height, Off, fg);
}
bool
CairoIcon::on_expose_event (GdkEventExpose *ev)
{
#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
Cairo::RefPtr<Cairo::Context> cr;
if (getenv("ARDOUR_IMAGE_SURFACE")) {
if (!image_surface) {
image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
}
cr = Cairo::Context::create (image_surface);
} else {
cr = get_window()->create_cairo_context ();
}
#elif defined USE_CAIRO_IMAGE_SURFACE
if (!image_surface) {
image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
}
Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (image_surface);
#else
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
#endif
cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
cr->clip ();
cr->translate (ev->area.x, ev->area.y);
cairo_rectangle_t expose_area;
expose_area.x = ev->area.x;
expose_area.y = ev->area.y;
expose_area.width = ev->area.width;
expose_area.height = ev->area.height;
CairoIcon::render (cr->cobj(), &expose_area);
#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
if (getenv("ARDOUR_IMAGE_SURFACE")) {
#endif
#if defined USE_CAIRO_IMAGE_SURFACE || defined OPTIONAL_CAIRO_IMAGE_SURFACE
image_surface->flush();
/* now blit our private surface back to the GDK one */
Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
cairo_context->clip ();
cairo_context->set_source (image_surface, 0, 0);
cairo_context->set_operator (Cairo::OPERATOR_SOURCE);
cairo_context->paint ();
#endif
#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
}
#endif
return true;
}

View File

@ -1,499 +0,0 @@
/*
Copyright (C) 2011 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <algorithm>
#include <cmath>
#include <iostream>
#include "gtkmm2ext/cairocell.h"
#include "gtkmm2ext/utils.h"
using std::string;
using std::vector;
using std::map;
using std::max;
using std::cerr;
using std::endl;
using namespace Gtkmm2ext;
static const double cairo_font_fudge = 1.5;
CairoFontDescription::CairoFontDescription (Pango::FontDescription& fd)
{
_size = cairo_font_fudge * (fd.get_size() / PANGO_SCALE);
switch (fd.get_style()) {
case Pango::STYLE_NORMAL:
_slant = Cairo::FONT_SLANT_NORMAL;
break;
case Pango::STYLE_OBLIQUE:
_slant = Cairo::FONT_SLANT_OBLIQUE;
break;
case Pango::STYLE_ITALIC:
_slant = Cairo::FONT_SLANT_ITALIC;
break;
}
switch (fd.get_weight()) {
case Pango::WEIGHT_ULTRALIGHT:
_weight = Cairo::FONT_WEIGHT_NORMAL;
break;
case Pango::WEIGHT_LIGHT:
_weight = Cairo::FONT_WEIGHT_NORMAL;
break;
case Pango::WEIGHT_NORMAL:
_weight = Cairo::FONT_WEIGHT_NORMAL;
break;
case Pango::WEIGHT_SEMIBOLD:
_weight = Cairo::FONT_WEIGHT_BOLD;
break;
case Pango::WEIGHT_BOLD:
_weight = Cairo::FONT_WEIGHT_BOLD;
break;
case Pango::WEIGHT_ULTRABOLD:
_weight = Cairo::FONT_WEIGHT_BOLD;
break;
case Pango::WEIGHT_HEAVY:
_weight = Cairo::FONT_WEIGHT_BOLD;
break;
/* to silence warnings when compiling with newer pango versions. */
default:
_weight = Cairo::FONT_WEIGHT_NORMAL;
break;
}
face = fd.get_family();
}
CairoCell::CairoCell (int32_t id)
: _id (id)
, _visible (true)
, _xpad (0)
{
bbox.x = 0;
bbox.y = 0;
bbox.width = 0;
bbox.height = 0;
}
CairoTextCell::CairoTextCell (int32_t id, double wc, boost::shared_ptr<CairoFontDescription> font)
: CairoCell (id)
, _width_chars (wc)
, _font (font)
, y_offset (0)
, x_offset (0)
{
}
void
CairoTextCell::set_text (const std::string& txt)
{
_text = txt;
}
void
CairoTextCell::render (Cairo::RefPtr<Cairo::Context>& context)
{
if (!_visible || _width_chars == 0) {
return;
}
context->save ();
context->rectangle (bbox.x, bbox.y, bbox.width, bbox.height);
context->clip ();
_font->apply (context);
context->move_to (bbox.x, bbox.y + bbox.height + y_offset);
context->show_text (_text);
context->restore ();
}
void
CairoTextCell::set_size (Cairo::RefPtr<Cairo::Context>& context)
{
const uint32_t lim = (uint32_t) ceil (_width_chars);
vector<char> buf(lim+1);
uint32_t n;
double max_width = 0.0;
double max_height = 0.0;
Cairo::TextExtents ext;
double bsum = 0;
buf[lim] = '\0';
_font->apply (context);
for (int digit = 0; digit < 10; digit++) {
for (n = 0; n < lim; ++n) {
buf[n] = '0' + digit;
}
context->get_text_extents (&buf[0], ext);
max_width = max (ext.width + ext.x_bearing, max_width);
max_height = max (ext.height, max_height);
bsum += ext.x_bearing;
}
/* add the average x-bearing for all digits as right hand side padding */
bbox.width = max_width + (bsum/10.0);
/* some fonts and some digits get their extents computed "too small", so fudge this
by adding 2
*/
bbox.height = max_height;
}
CairoCharCell::CairoCharCell (int32_t id, char c)
: CairoTextCell (id, 1)
{
_text = c;
}
void
CairoCharCell::set_size (Cairo::RefPtr<Cairo::Context>& context)
{
Cairo::TextExtents ext;
_font->apply (context);
{
const char* buf = "8";
context->get_text_extents (buf, ext);
/* same height as an "8" */
bbox.height = ext.height;
}
{
const char* buf = ":";
context->get_text_extents (buf, ext);
bbox.width = ext.width + (2.0 * ext.x_bearing);
/* center vertically */
y_offset = (ext.height - bbox.height) / 2.0;
}
}
CairoEditableText::CairoEditableText (boost::shared_ptr<CairoFontDescription> font)
: editing_cell (0)
, _draw_bg (true)
, max_cell_width (0)
, max_cell_height (0)
, _corner_radius (9)
, _xpad (0)
, _ypad (0)
{
set_font (font);
add_events (Gdk::POINTER_MOTION_HINT_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK |
Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK);
set_flags (Gtk::CAN_FOCUS);
set_can_default (true);
}
CairoEditableText::~CairoEditableText ()
{
/* we don't own cells */
}
bool
CairoEditableText::on_scroll_event (GdkEventScroll* ev)
{
CairoCell* cell = find_cell (ev->x, ev->y);
if (cell) {
return scroll (ev, cell);
}
return false;
}
bool
CairoEditableText::on_focus_in_event (GdkEventFocus*)
{
return false;
}
bool
CairoEditableText::on_focus_out_event (GdkEventFocus*)
{
if (editing_cell) {
queue_draw_cell (editing_cell);
editing_cell = 0;
}
return false;
}
void
CairoEditableText::add_cell (CairoCell* cell)
{
cells.push_back (cell);
CairoTextCell* tc = dynamic_cast<CairoTextCell*>(cell);
if (tc) {
tc->set_font (_font);
}
queue_resize ();
}
void
CairoEditableText::clear_cells ()
{
cells.clear ();
queue_resize ();
}
void
CairoEditableText::set_width_chars (CairoTextCell* cell, uint32_t wc)
{
if (cell) {
cell->set_width_chars (wc);
queue_resize ();
}
}
void
CairoEditableText::set_text (CairoTextCell* cell, const string& text)
{
cell->set_text (text);
queue_draw_cell (cell);
}
bool
CairoEditableText::on_expose_event (GdkEventExpose* ev)
{
Glib::RefPtr<Gdk::Window> win = get_window ();
if (!win) {
std::cerr << "CET: no window to draw on\n";
return false;
}
Cairo::RefPtr<Cairo::Context> context = win->create_cairo_context();
if (cells.empty()) {
return true;
}
context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
context->clip ();
Gtk::Allocation alloc = get_allocation ();
double width = alloc.get_width();
double height = alloc.get_height ();
if (_draw_bg) {
context->set_source_rgba (bg_r, bg_g, bg_b, bg_a);
if (_corner_radius) {
rounded_rectangle (context, 0, 0, width, height, _corner_radius);
} else {
context->rectangle (0, 0, width, height);
}
context->fill ();
}
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
CairoCell* cell = (*i);
/* is cell inside the expose area?
*/
if (cell->intersects (ev->area)) {
if (cell == editing_cell) {
context->set_source_rgba (edit_r, edit_b, edit_g, edit_a);
} else {
context->set_source_rgba (r, g, b, a);
}
cell->render (context);
}
}
return true;
}
void
CairoEditableText::queue_draw_cell (CairoCell* cell)
{
Glib::RefPtr<Gdk::Window> win = get_window();
if (!win) {
return;
}
Gdk::Rectangle r;
r.set_x (cell->x());
r.set_y (cell->y());
r.set_width (cell->width());
r.set_height (cell->height());
Gdk::Region rg (r);
win->invalidate_region (rg, true);
}
CairoCell*
CairoEditableText::find_cell (uint32_t x, uint32_t y)
{
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
if ((*i)->covers (x, y)) {
return (*i);
}
}
return 0;
}
bool
CairoEditableText::on_button_press_event (GdkEventButton* ev)
{
CairoCell* cell = find_cell (ev->x, ev->y);
return button_press (ev, cell);
}
bool
CairoEditableText::on_button_release_event (GdkEventButton* ev)
{
CairoCell* cell = find_cell (ev->x, ev->y);
return button_release (ev, cell);
}
void
CairoEditableText::start_editing (CairoCell* cell)
{
stop_editing ();
if (cell) {
editing_cell = cell;
queue_draw_cell (cell);
grab_focus ();
}
}
void
CairoEditableText::stop_editing ()
{
if (editing_cell) {
queue_draw_cell (editing_cell);
editing_cell = 0;
}
}
void
CairoEditableText::set_cell_sizes ()
{
Glib::RefPtr<Gdk::Window> win = get_window();
if (!win) {
return;
}
Cairo::RefPtr<Cairo::Context> context = win->create_cairo_context();
if (!context) {
return;
}
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
(*i)->set_size (context);
}
}
void
CairoEditableText::on_size_request (GtkRequisition* req)
{
set_cell_sizes ();
max_cell_width = 0;
max_cell_height = 0;
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
max_cell_width += (*i)->width();
max_cell_height = std::max ((double) (*i)->height(), max_cell_height);
}
req->width = max_cell_width;
req->height = max_cell_height;
}
void
CairoEditableText::on_size_allocate (Gtk::Allocation& alloc)
{
Misc::on_size_allocate (alloc);
/* position each cell so that its centered in the allocated space
*/
double x = (alloc.get_width() - max_cell_width)/2.0;
double y = (alloc.get_height() - max_cell_height)/2.0;
CellMap::iterator i = cells.begin();
while (i != cells.end()) {
CairoCell* cell = (*i);
cell->set_position (x, y);
x += cell->width ();
if (++i != cells.end()) {
/* only add cell padding intra-cellularly */
x += cell->xpad();
} else {
break;
}
}
}
void
CairoEditableText::set_font (Pango::FontDescription& fd)
{
boost::shared_ptr<CairoFontDescription> cd (new CairoFontDescription (fd));
set_font (cd);
}
void
CairoEditableText::set_font (boost::shared_ptr<CairoFontDescription> fd)
{
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
CairoTextCell* tc = dynamic_cast<CairoTextCell*>(*i);
if (tc && (!tc->font() || tc->font() == _font)) {
tc->set_font (fd);
}
}
_font = fd;
queue_resize ();
queue_draw ();
}

View File

@ -1,449 +0,0 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: fastmeter.h 570 2006-06-07 21:21:21Z sampo $
*/
#include <iostream>
#include "pbd/stacktrace.h"
#include "gtkmm2ext/fader.h"
#include "gtkmm2ext/keyboard.h"
#include "gtkmm2ext/rgb_macros.h"
#include "gtkmm2ext/utils.h"
#include "pbd/failed_constructor.h"
#include "pbd/file_utils.h"
#include "ardour/filesystem_paths.h"
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace std;
#define CORNER_RADIUS 4
#define CORNER_SIZE 2
#define CORNER_OFFSET 1
#define FADER_RESERVE 5
static void get_closest_point_on_line(double xa, double ya, double xb, double yb, double xp, double yp, double& xl, double& yl )
{
// Storing vector A->B
double a_to_b_x = xb - xa;
double a_to_b_y = yb - ya;
// Storing vector A->P
double a_to_p_x = xp - xa;
double a_to_p_y = yp - ya;
// Basically finding the squared magnitude
// of a_to_b
double atb2 = a_to_b_x * a_to_b_x + a_to_b_y * a_to_b_y;
// The dot product of a_to_p and a_to_b
double atp_dot_atb = a_to_p_x * a_to_b_x + a_to_p_y * a_to_b_y;
// The normalized "distance" from a to
// your closest point
double t = atp_dot_atb / atb2;
// Add the distance to A, moving
// towards B
double x = xa + a_to_b_x * t;
double y = ya + a_to_b_y * t;
if ((xa != xb)) {
if ((x < xa) && (x < xb)) {
if (xa < xb) {
x = xa;
y = ya;
} else {
x = xb;
y = yb;
}
} else if ((x > xa) && (x > xb)) {
if (xb > xa) {
x = xb;
y = yb;
} else {
x = xa;
y = ya;
}
}
} else {
if ((y < ya) && (y < yb)) {
if (ya < yb) {
x = xa;
y = ya;
} else {
x = xb;
y = yb;
}
} else if ((y > ya) && (y > yb)) {
if (yb > ya) {
x = xb;
y = yb;
} else {
x = xa;
y = ya;
}
}
}
xl = x;
yl = y;
}
Fader::Fader (Gtk::Adjustment& adj,
const Glib::RefPtr<Gdk::Pixbuf>& face_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& active_face_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& underlay_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& handle_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& active_handle_pixbuf,
int min_pos_x,
int min_pos_y,
int max_pos_x,
int max_pos_y,
bool read_only)
: adjustment (adj)
, _face_pixbuf (face_pixbuf)
, _active_face_pixbuf (active_face_pixbuf)
, _underlay_pixbuf (underlay_pixbuf)
, _handle_pixbuf (handle_pixbuf)
, _active_handle_pixbuf (active_handle_pixbuf)
, _min_pos_x (min_pos_x)
, _min_pos_y (min_pos_y)
, _max_pos_x (max_pos_x)
, _max_pos_y (max_pos_y)
, _grab_window (0)
, _touch_cursor (0)
, _dragging (false)
, _default_value (adjustment.get_value())
, _read_only (read_only)
{
update_unity_position ();
if (!_read_only) {
add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK);
}
adjustment.signal_value_changed().connect (mem_fun (*this, &Fader::adjustment_changed));
adjustment.signal_changed().connect (mem_fun (*this, &Fader::adjustment_changed));
CairoWidget::set_size_request(_face_pixbuf->get_width(), _face_pixbuf->get_height());
}
Fader::~Fader ()
{
if (_touch_cursor) {
delete _touch_cursor;
}
}
void
Fader::get_image_scales (double &x_scale, double &y_scale)
{
int pbwidth = _face_pixbuf->get_width ();
int pbheight = _face_pixbuf->get_height ();
int width = get_width ();
int height = get_height ();
if ((width != pbwidth) || (height != pbheight)) {
x_scale = double (width) / double (pbwidth);
if (x_scale == 0.0) {
x_scale = 1.0;
}
y_scale = double (height) / double (pbheight);
if (y_scale == 0.0) {
y_scale = 1.0;
}
} else {
x_scale = y_scale = 1.0;
}
}
void
Fader::set_touch_cursor (const Glib::RefPtr<Gdk::Pixbuf>& touch_cursor)
{
_touch_cursor = new Gdk::Cursor (Gdk::Display::get_default(), touch_cursor, 12, 12);
}
void
Fader::render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t*)
{
cairo_t* cr = ctx->cobj();
double xscale = 1.0;
double yscale = 1.0;
get_image_scales (xscale, yscale);
cairo_matrix_t matrix;
cairo_get_matrix (cr, &matrix);
cairo_matrix_scale (&matrix, xscale, yscale);
cairo_set_matrix (cr, &matrix);
get_handle_position (_last_drawn_x, _last_drawn_y);
if (_underlay_pixbuf != 0) {
gdk_cairo_set_source_pixbuf (cr,
_underlay_pixbuf->gobj(),
(_last_drawn_x - (int)((_underlay_pixbuf->get_width() * xscale) / 2.0 + 0.5)) / xscale,
(_last_drawn_y - (int)((_underlay_pixbuf->get_height() * yscale) / 2.0 + 0.5)) / yscale);
cairo_paint (cr);
}
gdk_cairo_set_source_pixbuf (cr,
((get_state () == Gtk::STATE_ACTIVE) && (_active_face_pixbuf != 0)) ?
_active_face_pixbuf->gobj() :
_face_pixbuf->gobj(),
0,
0);
cairo_paint (cr);
const Glib::RefPtr<Gdk::Pixbuf> handle_pixbuf (_dragging ? _active_handle_pixbuf : _handle_pixbuf);
gdk_cairo_set_source_pixbuf (cr,
handle_pixbuf->gobj(),
(_last_drawn_x - (int)((handle_pixbuf->get_width() * xscale) / 2.0 + 0.5)) / xscale,
(_last_drawn_y - (int)((handle_pixbuf->get_height() * yscale) / 2.0 + 0.5)) / yscale);
cairo_paint (cr);
}
void
Fader::on_size_request (GtkRequisition* req)
{
req->width = _face_pixbuf->get_width();
req->height = _face_pixbuf->get_height();
}
void
Fader::on_size_allocate (Gtk::Allocation& alloc)
{
CairoWidget::on_size_allocate(alloc);
update_unity_position ();
}
bool
Fader::on_button_press_event (GdkEventButton* ev)
{
focus_handler(this);
if (_read_only) {
return false;
}
if (ev->type != GDK_BUTTON_PRESS) {
return false;
}
if (ev->button != 1 && ev->button != 2) {
return false;
}
if (_touch_cursor) {
get_window()->set_cursor (*_touch_cursor);
}
_grab_start_mouse_x = ev->x;
_grab_start_mouse_y = ev->y;
get_handle_position (_grab_start_handle_x, _grab_start_handle_y);
double xscale = 1.0;
double yscale = 1.0;
get_image_scales (xscale, yscale);
double hw = _handle_pixbuf->get_width() * xscale;
double hh = _handle_pixbuf->get_height() * yscale;
if ((ev->x < (_grab_start_handle_x - hw/2)) || (ev->x > (_grab_start_handle_x + hw/2)) || (ev->y < (_grab_start_handle_y - hh/2)) || (ev->y > (_grab_start_handle_y + hh/2))) {
return false;
}
double ev_pos_x;
double ev_pos_y;
get_closest_point_on_line(_min_pos_x, _min_pos_y,
_max_pos_x, _max_pos_y,
ev->x, ev->y,
ev_pos_x, ev_pos_y );
add_modal_grab ();
_grab_window = ev->window;
_dragging = true;
gdk_pointer_grab(ev->window,false,
GdkEventMask (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK),
NULL,
NULL,
ev->time);
queue_draw();
return true;
}
bool
Fader::on_button_release_event (GdkEventButton* ev)
{
if (_read_only) {
return false;
}
if (_touch_cursor) {
get_window()->set_cursor ();
}
if (_dragging) { //temp
remove_modal_grab();
_dragging = false;
gdk_pointer_ungrab (GDK_CURRENT_TIME);
queue_draw ();
}
return false;
}
bool
Fader::on_scroll_event (GdkEventScroll* ev)
{
if (_read_only) {
return false;
}
int step_factor = 1;
switch (ev->direction) {
case GDK_SCROLL_RIGHT:
case GDK_SCROLL_UP:
#ifdef __APPLE__
if ( ev->state & GDK_SHIFT_MASK ) {
step_factor = -1;
} else {
step_factor = 1;
}
#else
step_factor = 1;
#endif
break;
case GDK_SCROLL_LEFT:
case GDK_SCROLL_DOWN:
#ifdef __APPLE__
if ( ev->state & GDK_SHIFT_MASK ) {
step_factor = 1;
} else {
step_factor = -1;
}
#else
step_factor = -1;
#endif
break;
default:
return false;
}
adjustment.set_value (adjustment.get_value() + step_factor * (adjustment.get_step_increment() ));
return true;
}
bool
Fader::on_motion_notify_event (GdkEventMotion* ev)
{
if (_read_only) {
return false;
}
if (_dragging) {
double ev_pos_x;
double ev_pos_y;
if (ev->window != _grab_window) {
_grab_window = ev->window;
return true;
}
get_closest_point_on_line(_min_pos_x, _min_pos_y,
_max_pos_x, _max_pos_y,
_grab_start_handle_x + (ev->x - _grab_start_mouse_x), _grab_start_handle_y + (ev->y - _grab_start_mouse_y),
ev_pos_x, ev_pos_y );
double const fract = sqrt((ev_pos_x - _min_pos_x) * (ev_pos_x - _min_pos_x) +
(ev_pos_y - _min_pos_y) * (ev_pos_y - _min_pos_y)) /
sqrt((double)((_max_pos_x - _min_pos_x) * (_max_pos_x - _min_pos_x) +
(_max_pos_y - _min_pos_y) * (_max_pos_y - _min_pos_y)));
adjustment.set_value (adjustment.get_lower() + (adjustment.get_upper() - adjustment.get_lower()) * fract);
}
return true;
}
void
Fader::adjustment_changed ()
{
double handle_x;
double handle_y;
get_handle_position (handle_x, handle_y);
if ((handle_x != _last_drawn_x) || (handle_y != _last_drawn_y)) {
queue_draw ();
}
}
/** @return pixel offset of the current value from the right or bottom of the fader */
void
Fader::get_handle_position (double& x, double& y)
{
double fract = (adjustment.get_value () - adjustment.get_lower()) / ((adjustment.get_upper() - adjustment.get_lower()));
x = (int)(_min_pos_x + (_max_pos_x - _min_pos_x) * fract);
y = (int)(_min_pos_y + (_max_pos_y - _min_pos_y) * fract);
}
bool
Fader::on_enter_notify_event (GdkEventCrossing*)
{
_hovering = true;
Keyboard::magic_widget_grab_focus ();
queue_draw ();
return false;
}
bool
Fader::on_leave_notify_event (GdkEventCrossing*)
{
if (_read_only) {
return false;
}
if (!_dragging) {
_hovering = false;
Keyboard::magic_widget_drop_focus();
queue_draw ();
}
return false;
}
void
Fader::set_default_value (float d)
{
_default_value = d;
update_unity_position ();
}
void
Fader::update_unity_position ()
{
}

View File

@ -1,96 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <gtkmm.h>
#include <gtkmm2ext/grouped_buttons.h>
using namespace std;
GroupedButtons::GroupedButtons (vector<Gtk::ToggleButton *>& buttonset)
{
uint32_t n = 0;
buttons = buttonset;
for (vector<Gtk::ToggleButton *>::iterator i = buttons.begin(); i != buttons.end(); ++i, ++n) {
if ((*i)->get_active()) {
current_active = n;
}
(*i)->signal_clicked().connect (sigc::bind (mem_fun (*this, &GroupedButtons::one_clicked), n));
}
}
GroupedButtons::GroupedButtons (uint32_t nbuttons, uint32_t first_active)
{
buttons.reserve (nbuttons);
current_active = first_active;
for (uint32_t n = 0; n < nbuttons; ++n) {
Gtk::ToggleButton *button;
button = manage (new (Gtk::ToggleButton));
if (n == current_active) {
button->set_active (true);
}
button->signal_clicked().connect (sigc::bind (mem_fun (*this, &GroupedButtons::one_clicked), n));
buttons.push_back (button);
}
}
static gint
reactivate_button (void *arg)
{
Gtk::ToggleButton *b = (Gtk::ToggleButton *) arg;
b->set_active (true);
return FALSE;
}
void
GroupedButtons::one_clicked (uint32_t which)
{
if (buttons[which]->get_active()) {
if (which != current_active) {
uint32_t old = current_active;
current_active = which;
buttons[old]->set_active (false);
}
} else if (which == current_active) {
/* Someobody tried to unset the current active
button by clicking on it. This caused
set_active (false) to be called. We don't
allow that, so just reactivate it.
Don't try this right here, because of some
design glitches with GTK+ toggle buttons.
Setting the button back to active from
within the signal emission that marked
it as inactive causes a segfault ...
*/
g_idle_add (reactivate_button, buttons[which]);
}
}

View File

@ -1,87 +0,0 @@
/*
Copyright (C) 2004 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __bindable_button_h__
#define __bindable_button_h__
#include <string>
#include "pbd/signals.h"
#include "gtkmm2ext/visibility.h"
#include "gtkmm2ext/stateful_button.h"
#include "gtkmm2ext/binding_proxy.h"
namespace PBD {
class Controllable;
}
class LIBGTKMM2EXT_API BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
{
public:
BindableToggleButton (const std::string &label)
: Gtkmm2ext::StatefulToggleButton (label) {}
BindableToggleButton () {}
virtual ~BindableToggleButton() {}
bool on_button_press_event (GdkEventButton *ev) {
if (!binding_proxy.button_press_handler (ev)) {
StatefulToggleButton::on_button_press_event (ev);
return false;
} else {
return true;
}
}
boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
void set_controllable (boost::shared_ptr<PBD::Controllable> c);
void watch ();
protected:
void controllable_changed ();
PBD::ScopedConnection watch_connection;
private:
BindingProxy binding_proxy;
};
class LIBGTKMM2EXT_API BindableButton : public Gtkmm2ext::StatefulButton
{
public:
BindableButton (boost::shared_ptr<PBD::Controllable> c) : binding_proxy (c) {}
~BindableButton() {}
bool on_button_press_event (GdkEventButton *ev) {
if (!binding_proxy.button_press_handler (ev)) {
StatefulButton::on_button_press_event (ev);
return false;
} else {
return true;
}
}
boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
void set_controllable (boost::shared_ptr<PBD::Controllable> c) { binding_proxy.set_controllable (c); }
private:
BindingProxy binding_proxy;
};
#endif

View File

@ -1,53 +0,0 @@
/*
Copyright (C) 2015 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtk2_ardour_cairo_icon_h__
#define __gtk2_ardour_cairo_icon_h__
#include <gtkmm/bin.h>
#include "gtkmm2ext/visibility.h"
#include "gtkmm2ext/ardour_icon.h"
/** A parent class for icons that are rendered using Cairo but need to be
* widgets for event handling
*/
namespace Gtkmm2ext {
class LIBGTKMM2EXT_API CairoIcon : public Gtk::Bin
{
public:
CairoIcon (Gtkmm2ext::ArdourIcon::Icon, uint32_t fg = 0x000000ff);
virtual ~CairoIcon ();
void render (cairo_t *, cairo_rectangle_t*);
void set_fg (uint32_t fg);
bool on_expose_event (GdkEventExpose*);
private:
Cairo::RefPtr<Cairo::Surface> image_surface;
ArdourIcon::Icon icon_type;
uint32_t fg;
};
}
#endif /* __gtk2_ardour_cairo_icon_h__ */

View File

@ -1,250 +0,0 @@
/*
Copyright (C) 2011 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __libgtmm2ext_cairocell_h__
#define __libgtmm2ext_cairocell_h__
#include <map>
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <cairomm/cairomm.h>
#include <gtkmm/misc.h>
#include "gtkmm2ext/visibility.h"
class LIBGTKMM2EXT_API CairoCell
{
public:
CairoCell(int32_t id);
virtual ~CairoCell() {}
int32_t id() const { return _id; }
virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
double x() const { return bbox.x; }
double y() const { return bbox.y; }
double width() const { return bbox.width; }
double height() const { return bbox.height; }
void set_position (double x, double y) {
bbox.x = x;
bbox.y = y;
}
bool intersects (GdkRectangle& r) const {
return gdk_rectangle_intersect (&r, &bbox, 0);
}
bool covers (double x, double y) const {
return bbox.x <= x && bbox.x + bbox.width > x &&
bbox.y <= y && bbox.y + bbox.height > y;
}
double xpad() const { return _xpad; }
void set_xpad (double x) { _xpad = x; }
void set_visible (bool yn) { _visible = yn; }
bool visible() const { return _visible; }
virtual void set_size (Cairo::RefPtr<Cairo::Context>&) {}
protected:
int32_t _id;
GdkRectangle bbox;
bool _visible;
uint32_t _xpad;
};
class LIBGTKMM2EXT_API CairoFontDescription {
public:
CairoFontDescription (const std::string& f,
Cairo::FontSlant s,
Cairo::FontWeight w,
double sz)
: face (f)
, _slant (s)
, _weight (w)
, _size (sz)
{}
CairoFontDescription (Pango::FontDescription&);
void apply (Cairo::RefPtr<Cairo::Context> context) {
context->select_font_face (face, _slant, _weight);
context->set_font_size (_size);
}
void set_size (double sz) { _size = sz; }
double size() const { return _size; }
Cairo::FontSlant slant() const { return _slant; }
void set_slant (Cairo::FontSlant sl) { _slant = sl; }
Cairo::FontWeight weight() const { return _weight; }
void set_weight (Cairo::FontWeight w) { _weight = w; }
private:
std::string face;
Cairo::FontSlant _slant;
Cairo::FontWeight _weight;
double _size;
};
class LIBGTKMM2EXT_API CairoTextCell : public CairoCell
{
public:
CairoTextCell (int32_t id, double width_chars, boost::shared_ptr<CairoFontDescription> font = boost::shared_ptr<CairoFontDescription>());
~CairoTextCell() {}
virtual void set_size (Cairo::RefPtr<Cairo::Context>&);
boost::shared_ptr<CairoFontDescription> font() const { return _font; }
std::string get_text() const {
return _text;
}
double width_chars() const { return _width_chars; }
void render (Cairo::RefPtr<Cairo::Context>&);
protected:
friend class CairoEditableText;
void set_width_chars (double wc) { _width_chars = wc; }
void set_text (const std::string& txt);
void set_font (boost::shared_ptr<CairoFontDescription> font) {
_font = font;
}
protected:
double _width_chars;
std::string _text;
boost::shared_ptr<CairoFontDescription> _font;
double y_offset;
double x_offset;
};
class LIBGTKMM2EXT_API CairoCharCell : public CairoTextCell
{
public:
CairoCharCell(int32_t id, char c);
void set_size (Cairo::RefPtr<Cairo::Context>& context);
};
class LIBGTKMM2EXT_API CairoEditableText : public Gtk::Misc
{
public:
CairoEditableText (boost::shared_ptr<CairoFontDescription> font = boost::shared_ptr<CairoFontDescription>());
~CairoEditableText ();
void add_cell (CairoCell*);
void clear_cells ();
void start_editing (CairoCell*);
void stop_editing ();
void set_text (CairoTextCell* cell, const std::string&);
void set_width_chars (CairoTextCell* cell, uint32_t);
void set_draw_background (bool yn) { _draw_bg = yn; }
void set_colors (double cr, double cg, double cb, double ca) {
r = cr;
g = cg;
b = cb;
a = ca;
queue_draw ();
}
void set_edit_colors (double cr, double cg, double cb, double ca) {
edit_r = cr;
edit_g = cg;
edit_b = cb;
edit_a = ca;
queue_draw ();
}
void set_bg (double r, double g, double b, double a) {
bg_r = r;
bg_g = g;
bg_b = b;
bg_a = a;
queue_draw ();
}
double xpad() const { return _xpad; }
void set_xpad (double x) { _xpad = x; queue_resize(); }
double ypad() const { return _ypad; }
void set_ypad (double y) { _ypad = y; queue_resize(); }
double corner_radius() const { return _corner_radius; }
void set_corner_radius (double r) { _corner_radius = r; queue_draw (); }
boost::shared_ptr<CairoFontDescription> font() const { return _font; }
void set_font (boost::shared_ptr<CairoFontDescription> font);
void set_font (Pango::FontDescription& font);
sigc::signal<bool,GdkEventScroll*,CairoCell*> scroll;
sigc::signal<bool,GdkEventButton*,CairoCell*> button_press;
sigc::signal<bool,GdkEventButton*,CairoCell*> button_release;
protected:
bool on_expose_event (GdkEventExpose*);
bool on_button_press_event (GdkEventButton*);
bool on_button_release_event (GdkEventButton*);
void on_size_request (GtkRequisition*);
bool on_focus_in_event (GdkEventFocus*);
bool on_focus_out_event (GdkEventFocus*);
bool on_scroll_event (GdkEventScroll*);
void on_size_allocate (Gtk::Allocation&);
private:
typedef std::vector<CairoCell*> CellMap;
CellMap cells;
boost::shared_ptr<CairoFontDescription> _font;
CairoCell* editing_cell;
bool _draw_bg;
double max_cell_width;
double max_cell_height;
double _corner_radius;
double _xpad;
double _ypad;
double r;
double g;
double b;
double a;
double edit_r;
double edit_g;
double edit_b;
double edit_a;
double bg_r;
double bg_g;
double bg_b;
double bg_a;
CairoCell* find_cell (uint32_t x, uint32_t y);
void queue_draw_cell (CairoCell* target);
void position_cells_and_get_bbox (GdkRectangle&);
void set_cell_sizes ();
};
#endif /* __libgtmm2ext_cairocell_h__ */

View File

@ -1,111 +0,0 @@
/*
Copyright (C) 2006 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtkmm2ext_fader_h__
#define __gtkmm2ext_fader_h__
#include <cmath>
#include <stdint.h>
#include <gtkmm/adjustment.h>
#include <gdkmm.h>
#include <gtkmm2ext/binding_proxy.h>
#include "gtkmm2ext/cairo_widget.h"
#include <boost/shared_ptr.hpp>
#include "gtkmm2ext/visibility.h"
namespace Gtkmm2ext {
class LIBGTKMM2EXT_API Fader : public CairoWidget
{
public:
Fader (Gtk::Adjustment& adjustment,
const Glib::RefPtr<Gdk::Pixbuf>& face_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& active_face_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& underlay_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& handle_pixbuf,
const Glib::RefPtr<Gdk::Pixbuf>& active_handle_pixbuf,
int min_pos_x,
int min_pos_y,
int max_pos_x,
int max_pos_y,
bool read_only);
virtual ~Fader ();
void set_controllable (boost::shared_ptr<PBD::Controllable> c) { binding_proxy.set_controllable (c); }
void set_default_value (float);
void set_touch_cursor (const Glib::RefPtr<Gdk::Pixbuf>& touch_cursor);
void get_image_scales (double &x_scale, double &y_scale);
protected:
void get_handle_position (double& x, double& y);
void on_size_request (GtkRequisition*);
void on_size_allocate (Gtk::Allocation& alloc);
void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
bool on_button_press_event (GdkEventButton*);
bool on_button_release_event (GdkEventButton*);
bool on_motion_notify_event (GdkEventMotion*);
bool on_scroll_event (GdkEventScroll* ev);
bool on_enter_notify_event (GdkEventCrossing* ev);
bool on_leave_notify_event (GdkEventCrossing* ev);
protected:
Gtk::Adjustment& adjustment;
BindingProxy binding_proxy;
private:
const Glib::RefPtr<Gdk::Pixbuf> _face_pixbuf;
const Glib::RefPtr<Gdk::Pixbuf> _active_face_pixbuf;
const Glib::RefPtr<Gdk::Pixbuf> _underlay_pixbuf;
const Glib::RefPtr<Gdk::Pixbuf> _handle_pixbuf;
const Glib::RefPtr<Gdk::Pixbuf> _active_handle_pixbuf;
int _min_pos_x;
int _min_pos_y;
int _max_pos_x;
int _max_pos_y;
bool _hovering;
GdkWindow* _grab_window;
Gdk::Cursor *_touch_cursor;
double _grab_start_mouse_x;
double _grab_start_mouse_y;
double _grab_start_handle_x;
double _grab_start_handle_y;
double _last_drawn_x;
double _last_drawn_y;
bool _dragging;
float _default_value;
bool _read_only;
void adjustment_changed ();
void update_unity_position ();
};
} /* namespace */
#endif /* __gtkmm2ext_fader_h__ */

View File

@ -1,50 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtkmm2ext_grouped_buttons_h__
#define __gtkmm2ext_grouped_buttons_h__
#include <stdint.h>
#include <vector>
#include <sigc++/signal.h>
#include "gtkmm2ext/visibility.h"
namespace Gtk {
class ToggleButton;
};
class LIBGTKMM2EXT_API GroupedButtons : public sigc::trackable
{
public:
GroupedButtons (uint32_t nbuttons, uint32_t first_active);
GroupedButtons (std::vector<Gtk::ToggleButton *>&);
Gtk::ToggleButton& button (uint32_t which) {
return *buttons[which];
}
private:
std::vector<Gtk::ToggleButton *> buttons;
uint32_t current_active;
void one_clicked (uint32_t which);
};
#endif /* __gtkmm2ext_grouped_buttons_h__ */

View File

@ -1,49 +0,0 @@
/*
Copyright (C) 2000-2007 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtkmm2ext_idle_adjustment_h__
#define __gtkmm2ext_idle_adjustment_h__
#include <stdint.h>
#include <sys/time.h>
#include <gtkmm/adjustment.h>
#include "gtkmm2ext/visibility.h"
namespace Gtkmm2ext {
class LIBGTKMM2EXT_API IdleAdjustment : public sigc::trackable
{
public:
IdleAdjustment (Gtk::Adjustment& adj);
~IdleAdjustment ();
sigc::signal<void> value_changed;
private:
void underlying_adjustment_value_changed();
int64_t last_vc;
gint timeout_handler();
bool timeout_queued;
};
}
#endif /* __gtkmm2ext_idle_adjustment_h__ */

View File

@ -1,71 +0,0 @@
/*
Copyright (C) 2000-2007 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtkmm2ext_pixscroller_h__
#define __gtkmm2ext_pixscroller_h__
#include <gtkmm/drawingarea.h>
#include <gtkmm/adjustment.h>
#include <gdkmm.h>
#include "gtkmm2ext/visibility.h"
namespace Gtkmm2ext {
class LIBGTKMM2EXT_API PixScroller : public Gtk::DrawingArea
{
public:
PixScroller(Gtk::Adjustment& adjustment,
Glib::RefPtr<Gdk::Pixbuf> slider,
Glib::RefPtr<Gdk::Pixbuf> rail);
bool on_expose_event (GdkEventExpose*);
bool on_motion_notify_event (GdkEventMotion*);
bool on_button_press_event (GdkEventButton*);
bool on_button_release_event (GdkEventButton*);
bool on_scroll_event (GdkEventScroll*);
void on_size_request (GtkRequisition*);
protected:
Gtk::Adjustment& adj;
private:
Cairo::RefPtr< Cairo::Context > rail_context;
Cairo::RefPtr< Cairo::ImageSurface > rail_surface;
Glib::RefPtr<Gdk::Pixbuf> rail;
Cairo::RefPtr< Cairo::Context > slider_context;
Cairo::RefPtr< Cairo::ImageSurface > slider_surface;
Glib::RefPtr<Gdk::Pixbuf> slider;
Gdk::Rectangle sliderrect;
Gdk::Rectangle railrect;
GdkWindow* grab_window;
double grab_y;
double grab_start;
int overall_height;
bool dragging;
float default_value;
void adjustment_changed ();
};
} // namespace
#endif /* __gtkmm2ext_pixscroller_h__ */

View File

@ -1,114 +0,0 @@
/*
Copyright (C) 1999 Paul Barton-Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __gtkselector_h__
#define __gtkselector_h__
#ifdef interface
#undef interface
#endif
#include <string>
#include <vector>
#include <gtkmm.h>
#include "gtkmm2ext/visibility.h"
namespace Gtkmm2ext {
class LIBGTKMM2EXT_API TreeView_Selector : public Gtk::TreeView
{
public:
TreeView_Selector() {}
virtual ~TreeView_Selector() {}
protected:
virtual bool on_button_press_event(GdkEventButton *ev);
};
typedef void (SelectorRefillFunction)(Glib::RefPtr<Gtk::ListStore>, void *);
class LIBGTKMM2EXT_API Selector : public Gtk::VBox
{
friend class Gtkmm2ext::TreeView_Selector;
public:
Selector (SelectorRefillFunction, void *arg,
std::vector<std::string> titles);
virtual ~Selector ();
Glib::RefPtr<Gtk::ListStore> liststore () { return lstore; }
void reset (void (*refiller)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg);
void set_size (unsigned int w, unsigned int h) {
scroll.set_size_request (w, h);
tview.columns_autosize ();
}
struct Result {
Gtk::TreeView& view;
Glib::RefPtr<Gtk::TreeSelection> selection;
Result (Gtk::TreeView& v, Glib::RefPtr<Gtk::TreeSelection> sel)
: view (v), selection (sel) {}
};
/* selection is activated via a double click, choice via
a single click.
*/
sigc::signal<void,Result*> selection_made;
sigc::signal<void,Result*> choice_made;
sigc::signal<void,Result*> shift_made;
sigc::signal<void,Result*> control_made;
sigc::signal<void> update_contents;
void accept();
void cancel();
void rescan();
protected:
virtual void on_map ();
virtual void on_show ();
private:
Gtk::ScrolledWindow scroll;
Gtk::TreeModel::ColumnRecord column_records;
Glib::RefPtr<Gtk::ListStore> lstore;
Gtkmm2ext::TreeView_Selector tview;
void (*refiller)(Glib::RefPtr<Gtk::ListStore>, void *);
void *refill_arg;
gint selected_row;
gint selected_column;
void refill ();
void chosen ();
void shift_clicked ();
void control_clicked ();
static gint _accept (gpointer);
static gint _chosen (gpointer);
static gint _shift_clicked (gpointer);
static gint _control_clicked (gpointer);
};
} /* namespace */
#endif // __gtkselector_h__

View File

@ -27,7 +27,6 @@
#include <gtkmm/label.h>
#include <gtkmm/notebook.h>
#include "gtkmm2ext/cairo_icon.h"
#include "gtkmm2ext/window_proxy.h"
#include "gtkmm2ext/visibility.h"

View File

@ -1,73 +0,0 @@
/*
Copyright (C) 2000-2007 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define _BSD_SOURCE
#include <gtkmm2ext/idle_adjustment.h>
#include <gtkmm/main.h>
#include <glibmm/main.h>
#include <iostream>
#include "pbd/timersub.h"
using namespace Gtk;
using namespace sigc;
using namespace Gtkmm2ext;
IdleAdjustment::IdleAdjustment (Gtk::Adjustment& adj)
{
adj.signal_value_changed().connect (mem_fun (*this, &IdleAdjustment::underlying_adjustment_value_changed));
timeout_queued = 0;
last_vc = g_get_monotonic_time();
}
IdleAdjustment::~IdleAdjustment ()
{
}
void
IdleAdjustment::underlying_adjustment_value_changed ()
{
last_vc = g_get_monotonic_time();
if (timeout_queued) {
return;
}
Glib::signal_timeout().connect(mem_fun(*this, &IdleAdjustment::timeout_handler), 250);
timeout_queued = true;
}
gint
IdleAdjustment::timeout_handler ()
{
int64_t now, tdiff;
now = g_get_monotonic_time();
tdiff = now - last_vc;
std::cerr << "timer elapsed, diff = " << tdiff << " usec" << std::endl;
if (tdiff > 250000) {
std::cerr << "send signal\n";
value_changed ();
timeout_queued = false;
return FALSE;
} else {
return TRUE;
}
}

View File

@ -1,274 +0,0 @@
/*
Copyright (C) 2005 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <gtkmm.h>
#include "gtkmm2ext/pixscroller.h"
#include "gtkmm2ext/keyboard.h"
using namespace std;
using namespace Gtk;
using namespace Gtkmm2ext;
PixScroller::PixScroller (Adjustment& a,
Glib::RefPtr<Gdk::Pixbuf> s,
Glib::RefPtr<Gdk::Pixbuf> r)
: adj (a),
rail (r),
slider (s)
{
Cairo::Format format;
dragging = false;
add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
adj.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed));
default_value = adj.get_value();
sliderrect.set_width(slider->get_width());
sliderrect.set_height(slider->get_height());
railrect.set_width(rail->get_width());
railrect.set_height(rail->get_height());
railrect.set_y(sliderrect.get_height() / 2);
sliderrect.set_x(0);
overall_height = railrect.get_height() + sliderrect.get_height();
sliderrect.set_y((int) rint ((overall_height - sliderrect.get_height()) * (adj.get_upper() - adj.get_value())));
railrect.set_x((sliderrect.get_width() / 2) - 2);
if (rail->get_has_alpha()) {
format = Cairo::FORMAT_ARGB32;
} else {
format = Cairo::FORMAT_RGB24;
}
rail_surface = Cairo::ImageSurface::create (format, rail->get_width(), rail->get_height());
rail_context = Cairo::Context::create (rail_surface);
Gdk::Cairo::set_source_pixbuf (rail_context, rail, 0.0, 0.0);
rail_context->paint();
if (slider->get_has_alpha()) {
format = Cairo::FORMAT_ARGB32;
} else {
format = Cairo::FORMAT_RGB24;
}
slider_surface = Cairo::ImageSurface::create (format, slider->get_width(), slider->get_height());
slider_context = Cairo::Context::create (slider_surface);
Gdk::Cairo::set_source_pixbuf (slider_context, slider, 0.0, 0.0);
slider_context->paint();
}
void
PixScroller::on_size_request (GtkRequisition* requisition)
{
requisition->width = sliderrect.get_width();
requisition->height = overall_height;
}
bool
PixScroller::on_expose_event (GdkEventExpose* ev)
{
GdkRectangle intersect;
Glib::RefPtr<Gdk::Window> win (get_window());
Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
if (gdk_rectangle_intersect (railrect.gobj(), &ev->area, &intersect)) {
context->save();
context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
context->clip();
context->set_source (rail_surface, intersect.x - railrect.get_x(), intersect.y - railrect.get_y());
context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
context->clip();
context->paint();
context->restore();
}
if (gdk_rectangle_intersect (sliderrect.gobj(), &ev->area, &intersect)) {
context->save();
context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
context->clip();
context->set_source (rail_surface, intersect.x - sliderrect.get_x(), intersect.y - sliderrect.get_y());
context->rectangle (intersect.x, intersect.y, intersect.width, intersect.height);
context->clip();
context->paint();
context->restore();
}
return true;
}
bool
PixScroller::on_button_press_event (GdkEventButton* ev)
{
switch (ev->button) {
case 1:
if (!(ev->state & Keyboard::TertiaryModifier)) {
add_modal_grab();
grab_y = ev->y;
grab_start = ev->y;
grab_window = ev->window;
dragging = true;
}
break;
default:
break;
}
return false;
}
bool
PixScroller::on_button_release_event (GdkEventButton* ev)
{
double scale;
if (ev->state & Keyboard::PrimaryModifier) {
if (ev->state & Keyboard::SecondaryModifier) {
scale = 0.05;
} else {
scale = 0.1;
}
} else {
scale = 1.0;
}
switch (ev->button) {
case 1:
if (dragging) {
remove_modal_grab();
dragging = false;
if (ev->y == grab_start) {
/* no motion - just a click */
double fract;
if (ev->y < sliderrect.get_height()/2) {
/* near the top */
fract = 1.0;
} else {
fract = 1.0 - (ev->y - sliderrect.get_height()/2) / railrect.get_height();
}
fract = min (1.0, fract);
fract = max (0.0, fract);
adj.set_value (scale * fract * (adj.get_upper() - adj.get_lower()));
}
} else {
if (ev->state & Keyboard::TertiaryModifier) {
adj.set_value (default_value);
cerr << "default value = " << default_value << endl;
}
}
break;
default:
break;
}
return false;
}
bool
PixScroller::on_scroll_event (GdkEventScroll* ev)
{
double scale;
if (ev->state & Keyboard::PrimaryModifier) {
if (ev->state & Keyboard::SecondaryModifier) {
scale = 0.05;
} else {
scale = 0.1;
}
} else {
scale = 0.5;
}
switch (ev->direction) {
case GDK_SCROLL_UP:
/* wheel up */
adj.set_value (adj.get_value() + (adj.get_page_increment() * scale));
break;
case GDK_SCROLL_DOWN:
/* wheel down */
adj.set_value (adj.get_value() - (adj.get_page_increment() * scale));
break;
default:
break;
}
return false;
}
bool
PixScroller::on_motion_notify_event (GdkEventMotion* ev)
{
if (dragging) {
double fract;
double delta;
double scale;
if (ev->window != grab_window) {
grab_y = ev->y;
grab_window = ev->window;
return true;
}
if (ev->state & Keyboard::PrimaryModifier) {
if (ev->state & Keyboard::SecondaryModifier) {
scale = 0.05;
} else {
scale = 0.1;
}
} else {
scale = 1.0;
}
delta = ev->y - grab_y;
grab_y = ev->y;
fract = (delta / railrect.get_height());
fract = min (1.0, fract);
fract = max (-1.0, fract);
fract = -fract;
adj.set_value (adj.get_value() + scale * fract * (adj.get_upper() - adj.get_lower()));
}
return true;
}
void
PixScroller::adjustment_changed ()
{
int y = (int) rint ((overall_height - sliderrect.get_height()) * (adj.get_upper() - adj.get_value()));
if (y != sliderrect.get_y()) {
sliderrect.set_y(y);
queue_draw ();
}
}

View File

@ -1,237 +0,0 @@
/*
Copyright (C) 1999 Paul Barton-Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <glibmm.h>
#include <gdkmm.h>
#include "gtkmm2ext/keyboard.h"
#include "gtkmm2ext/selector.h"
#include "gtkmm2ext/utils.h"
using namespace std;
using namespace Gtkmm2ext;
Selector::Selector (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg,
vector<string> titles)
{
scroll.add (tview);
scroll.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
pack_start (scroll, true, true);
vector<string>::iterator i;
for (i = titles.begin(); i != titles.end(); ++i) {
Gtk::TreeModelColumn<Glib::ustring> title;
column_records.add(title);
}
lstore = Gtk::ListStore::create(column_records);
tview.set_model(lstore);
update_contents.connect(mem_fun(*this,&Selector::rescan));
tview.show ();
refiller = func;
refill_arg = arg;
selected_row = -1;
selected_column = -1;
}
Selector::~Selector ()
{
/* ensure that any row data set with set_row_data_full() is deleted */
hide_all ();
lstore.clear ();
}
void
Selector::on_map()
{
Gtk::VBox::on_map ();
selected_row = -1;
selected_column = -1;
refill();
}
void
Selector::on_show()
{
VBox::on_show();
rescan();
}
void
Selector::reset (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg)
{
refiller = func;
refill_arg = arg;
selected_row = -1;
selected_column = -1;
refill();
}
void
Selector::refill ()
{
if (refiller) {
lstore.clear ();
refiller (lstore, refill_arg);
}
}
gint
Selector::_accept (gpointer arg)
{
((Selector *) arg)->accept ();
return FALSE;
}
gint
Selector::_chosen (gpointer arg)
{
((Selector *) arg)->chosen ();
return FALSE;
}
gint
Selector::_shift_clicked (gpointer arg)
{
((Selector *) arg)->shift_clicked ();
return FALSE;
}
gint
Selector::_control_clicked (gpointer arg)
{
((Selector *) arg)->control_clicked ();
return FALSE;
}
void
Selector::accept ()
{
Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
Gtk::TreeModel::iterator iter = tree_sel->get_selected();
if (iter) {
selection_made (new Result (tview, tree_sel));
} else {
cancel ();
}
}
void
Selector::chosen ()
{
Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
Gtk::TreeModel::iterator iter = tree_sel->get_selected();
if (iter) {
choice_made (new Result (tview, tree_sel));
} else {
cancel ();
}
}
void
Selector::shift_clicked ()
{
Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
Gtk::TreeModel::iterator iter = tree_sel->get_selected();
if (iter) {
shift_made (new Result (tview, tree_sel));
} else {
cancel ();
}
}
void
Selector::control_clicked ()
{
Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
Gtk::TreeModel::iterator iter = tree_sel->get_selected();
if (iter) {
control_made (new Result (tview, tree_sel));
} else {
cancel ();
}
}
void
Selector::cancel ()
{
Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
tree_sel->unselect_all();
selection_made (new Result (tview, tree_sel));
}
void
Selector::rescan ()
{
selected_row = -1;
selected_column = -1;
refill ();
show_all ();
}
struct string_cmp {
bool operator()(const string* a, const string* b) {
return *a < *b;
}
};
bool
TreeView_Selector::on_button_press_event(GdkEventButton* ev)
{
bool return_value = TreeView::on_button_press_event(ev);
if (ev && (ev->type == GDK_BUTTON_RELEASE || ev->type == GDK_2BUTTON_PRESS)) {
if (ev->state & Keyboard::PrimaryModifier) {
g_idle_add (Selector::_control_clicked, this);
} else if (ev->state & Keyboard::TertiaryModifier) {
g_idle_add (Selector::_shift_clicked, this);
} else if (ev->type == GDK_2BUTTON_PRESS) {
g_idle_add (Selector::_accept, this);
} else {
g_idle_add (Selector::_chosen, this);
}
}
return return_value;
}

View File

@ -1,895 +0,0 @@
/*
Copyright (C) 2003-2006 Paul Davis
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stdlib.h>
#include <glibmm.h>
#include <gdkmm.h>
#include <gdkmm/rectangle.h>
#include <gtkmm2ext/fastmeter.h>
#include <gtkmm2ext/utils.h>
#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
using namespace std;
int FastMeter::min_pattern_metric_size = 16;
int FastMeter::max_pattern_metric_size = 1024;
bool FastMeter::no_rgba_overlay = false;
FastMeter::Pattern10Map FastMeter::vm_pattern_cache;
FastMeter::PatternBgMap FastMeter::vb_pattern_cache;
FastMeter::Pattern10Map FastMeter::hm_pattern_cache;
FastMeter::PatternBgMap FastMeter::hb_pattern_cache;
FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len,
int clr0, int clr1, int clr2, int clr3,
int clr4, int clr5, int clr6, int clr7,
int clr8, int clr9,
int bgc0, int bgc1,
int bgh0, int bgh1,
float stp0, float stp1,
float stp2, float stp3,
int styleflags
)
: pixheight(0)
, pixwidth(0)
, _styleflags(1)
, orientation(o)
, hold_cnt(hold)
, hold_state(0)
, bright_hold(false)
, current_level(0)
, current_peak(0)
, highlight(false)
{
last_peak_rect.width = 0;
last_peak_rect.height = 0;
last_peak_rect.x = 0;
last_peak_rect.y = 0;
no_rgba_overlay = ! Glib::getenv("NO_METER_SHADE").empty();
_clr[0] = clr0;
_clr[1] = clr1;
_clr[2] = clr2;
_clr[3] = clr3;
_clr[4] = clr4;
_clr[5] = clr5;
_clr[6] = clr6;
_clr[7] = clr7;
_clr[8] = clr8;
_clr[9] = clr9;
_bgc[0] = bgc0;
_bgc[1] = bgc1;
_bgh[0] = bgh0;
_bgh[1] = bgh1;
_stp[0] = stp0;
_stp[1] = stp1;
_stp[2] = stp2;
_stp[3] = stp3;
set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
pixrect.x = 0;
pixrect.y = 0;
if (!len) {
len = 250;
}
if (orientation == Vertical) {
pixheight = len;
pixwidth = dimen;
fgpattern = request_vertical_meter(pixwidth, pixheight, _clr, _stp, _styleflags);
bgpattern = request_vertical_background (pixwidth, pixheight, _bgc, false);
} else {
pixheight = dimen;
pixwidth = len;
fgpattern = request_horizontal_meter(pixwidth, pixheight, _clr, _stp, _styleflags);
bgpattern = request_horizontal_background (pixwidth, pixheight, _bgc, false);
}
pixrect.width = pixwidth;
pixrect.height = pixheight;
request_width = pixrect.width;
request_height= pixrect.height;
clear ();
}
FastMeter::~FastMeter ()
{
}
void
FastMeter::flush_pattern_cache ()
{
hb_pattern_cache.clear();
hm_pattern_cache.clear();
vb_pattern_cache.clear();
vm_pattern_cache.clear();
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::generate_meter_pattern (
int width, int height, int *clr, float *stp, int styleflags, bool horiz)
{
guint8 r,g,b,a;
double knee;
const double soft = 3.0 / (double) height;
const double offs = -1.0 / (double) height;
cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
/*
Cairo coordinate space goes downwards as y value goes up, so invert
knee-based positions by using (1.0 - y)
*/
UINT_TO_RGBA (clr[9], &r, &g, &b, &a); // top/clip
cairo_pattern_add_color_stop_rgb (pat, 0.0,
r/255.0, g/255.0, b/255.0);
knee = offs + stp[3] / 115.0f; // -0dB
UINT_TO_RGBA (clr[8], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[7], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
knee = offs + stp[2]/ 115.0f; // -3dB || -2dB
UINT_TO_RGBA (clr[6], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[5], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
knee = offs + stp[1] / 115.0f; // -9dB
UINT_TO_RGBA (clr[4], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[3], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
knee = offs + stp[0] / 115.0f; // -18dB
UINT_TO_RGBA (clr[2], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[1], &r, &g, &b, &a);
cairo_pattern_add_color_stop_rgb (pat, 1.0 - knee + soft,
r/255.0, g/255.0, b/255.0);
UINT_TO_RGBA (clr[0], &r, &g, &b, &a); // bottom
cairo_pattern_add_color_stop_rgb (pat, 1.0,
r/255.0, g/255.0, b/255.0);
if ((styleflags & 1) && !no_rgba_overlay) {
cairo_pattern_t* shade_pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
cairo_pattern_add_color_stop_rgba (shade_pattern, 0, 0.0, 0.0, 0.0, 0.15);
cairo_pattern_add_color_stop_rgba (shade_pattern, 0.4, 1.0, 1.0, 1.0, 0.05);
cairo_pattern_add_color_stop_rgba (shade_pattern, 1, 0.0, 0.0, 0.0, 0.25);
cairo_surface_t* surface;
cairo_t* tc = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
tc = cairo_create (surface);
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
cairo_pattern_destroy (pat);
cairo_set_source (tc, shade_pattern);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
cairo_pattern_destroy (shade_pattern);
if (styleflags & 2) { // LED stripes
cairo_save (tc);
cairo_set_line_width(tc, 1.0);
cairo_set_source_rgba(tc, .0, .0, .0, 0.4);
//cairo_set_operator (tc, CAIRO_OPERATOR_SOURCE);
for (float y=0.5; y < height; y+= 2.0) {
cairo_move_to(tc, 0, y);
cairo_line_to(tc, width, y);
cairo_stroke (tc);
}
cairo_restore (tc);
}
pat = cairo_pattern_create_for_surface (surface);
cairo_destroy (tc);
cairo_surface_destroy (surface);
}
if (horiz) {
cairo_surface_t* surface;
cairo_t* tc = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
tc = cairo_create (surface);
cairo_matrix_t m;
cairo_matrix_init_rotate (&m, -M_PI/2.0);
cairo_matrix_translate (&m, -height, 0);
cairo_pattern_set_matrix (pat, &m);
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, height, width);
cairo_fill (tc);
cairo_pattern_destroy (pat);
pat = cairo_pattern_create_for_surface (surface);
cairo_destroy (tc);
cairo_surface_destroy (surface);
}
Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
return p;
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::generate_meter_background (
int width, int height, int *clr, bool shade, bool horiz)
{
guint8 r0,g0,b0,r1,g1,b1,a;
cairo_pattern_t* pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height);
UINT_TO_RGBA (clr[0], &r0, &g0, &b0, &a);
UINT_TO_RGBA (clr[1], &r1, &g1, &b1, &a);
cairo_pattern_add_color_stop_rgb (pat, 0.0,
r1/255.0, g1/255.0, b1/255.0);
cairo_pattern_add_color_stop_rgb (pat, 1.0,
r0/255.0, g0/255.0, b0/255.0);
if (shade && !no_rgba_overlay) {
cairo_pattern_t* shade_pattern = cairo_pattern_create_linear (0.0, 0.0, width, 0.0);
cairo_pattern_add_color_stop_rgba (shade_pattern, 0.0, 1.0, 1.0, 1.0, 0.15);
cairo_pattern_add_color_stop_rgba (shade_pattern, 0.6, 0.0, 0.0, 0.0, 0.10);
cairo_pattern_add_color_stop_rgba (shade_pattern, 1.0, 1.0, 1.0, 1.0, 0.20);
cairo_surface_t* surface;
cairo_t* tc = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
tc = cairo_create (surface);
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
cairo_set_source (tc, shade_pattern);
cairo_rectangle (tc, 0, 0, width, height);
cairo_fill (tc);
cairo_pattern_destroy (pat);
cairo_pattern_destroy (shade_pattern);
pat = cairo_pattern_create_for_surface (surface);
cairo_destroy (tc);
cairo_surface_destroy (surface);
}
if (horiz) {
cairo_surface_t* surface;
cairo_t* tc = 0;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, height, width);
tc = cairo_create (surface);
cairo_matrix_t m;
cairo_matrix_init_rotate (&m, -M_PI/2.0);
cairo_matrix_translate (&m, -height, 0);
cairo_pattern_set_matrix (pat, &m);
cairo_set_source (tc, pat);
cairo_rectangle (tc, 0, 0, height, width);
cairo_fill (tc);
cairo_pattern_destroy (pat);
pat = cairo_pattern_create_for_surface (surface);
cairo_destroy (tc);
cairo_surface_destroy (surface);
}
Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
return p;
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_vertical_meter(
int width, int height, int *clr, float *stp, int styleflags)
{
height = max(height, min_pattern_metric_size);
height = min(height, max_pattern_metric_size);
const Pattern10MapKey key (width, height,
stp[0], stp[1], stp[2], stp[3],
clr[0], clr[1], clr[2], clr[3],
clr[4], clr[5], clr[6], clr[7],
clr[8], clr[9], styleflags);
Pattern10Map::iterator i;
if ((i = vm_pattern_cache.find (key)) != vm_pattern_cache.end()) {
return i->second;
}
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
width, height, clr, stp, styleflags, false);
vm_pattern_cache[key] = p;
return p;
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_vertical_background(
int width, int height, int *bgc, bool /*shade */)
{
height = max(height, min_pattern_metric_size);
height = min(height, max_pattern_metric_size);
height += 2;
const PatternBgMapKey key (width, height, bgc[0], bgc[1], false);
PatternBgMap::iterator i;
if ((i = vb_pattern_cache.find (key)) != vb_pattern_cache.end()) {
return i->second;
}
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
width, height, bgc, false, false);
vb_pattern_cache[key] = p;
return p;
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_horizontal_meter(
int width, int height, int *clr, float *stp, int styleflags)
{
width = max(width, min_pattern_metric_size);
width = min(width, max_pattern_metric_size);
const Pattern10MapKey key (width, height,
stp[0], stp[1], stp[2], stp[3],
clr[0], clr[1], clr[2], clr[3],
clr[4], clr[5], clr[6], clr[7],
clr[8], clr[9], styleflags);
Pattern10Map::iterator i;
if ((i = hm_pattern_cache.find (key)) != hm_pattern_cache.end()) {
return i->second;
}
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_pattern (
height, width, clr, stp, styleflags, true);
hm_pattern_cache[key] = p;
return p;
}
Cairo::RefPtr<Cairo::Pattern>
FastMeter::request_horizontal_background(
int width, int height, int *bgc, bool /* shade */)
{
width = max(width, min_pattern_metric_size);
width = min(width, max_pattern_metric_size);
width += 2;
const PatternBgMapKey key (width, height, bgc[0], bgc[1], false);
PatternBgMap::iterator i;
if ((i = hb_pattern_cache.find (key)) != hb_pattern_cache.end()) {
return i->second;
}
// TODO flush pattern cache if it gets too large
Cairo::RefPtr<Cairo::Pattern> p = generate_meter_background (
height, width, bgc, false, true);
hb_pattern_cache[key] = p;
return p;
}
void
FastMeter::set_hold_count (long val)
{
if (val < 1) {
val = 1;
}
hold_cnt = val;
hold_state = 0;
current_peak = 0;
queue_draw ();
}
void
FastMeter::on_size_request (GtkRequisition* req)
{
if (orientation == Vertical) {
vertical_size_request (req);
} else {
horizontal_size_request (req);
}
}
void
FastMeter::vertical_size_request (GtkRequisition* req)
{
req->height = request_height;
req->height = max(req->height, min_pattern_metric_size);
req->height = min(req->height, max_pattern_metric_size);
req->height += 2;
req->width = request_width;
}
void
FastMeter::horizontal_size_request (GtkRequisition* req)
{
req->width = request_width;
req->width = max(req->width, min_pattern_metric_size);
req->width = min(req->width, max_pattern_metric_size);
req->width += 2;
req->height = request_height;
}
void
FastMeter::on_size_allocate (Gtk::Allocation &alloc)
{
if (orientation == Vertical) {
vertical_size_allocate (alloc);
} else {
horizontal_size_allocate (alloc);
}
queue_draw ();
}
void
FastMeter::vertical_size_allocate (Gtk::Allocation &alloc)
{
if (alloc.get_width() != request_width) {
alloc.set_width (request_width);
}
int h = alloc.get_height();
h = max (h, min_pattern_metric_size + 2);
h = min (h, max_pattern_metric_size + 2);
if (h != alloc.get_height()) {
alloc.set_height (h);
}
if (pixheight != h) {
fgpattern = request_vertical_meter (request_width, h, _clr, _stp, _styleflags);
bgpattern = request_vertical_background (request_width, h, highlight ? _bgh : _bgc, false);
pixheight = h;
pixwidth = request_width;
}
CairoWidget::on_size_allocate (alloc);
}
void
FastMeter::horizontal_size_allocate (Gtk::Allocation &alloc)
{
if (alloc.get_height() != request_height) {
alloc.set_height (request_height);
}
int w = alloc.get_width();
w = max (w, min_pattern_metric_size + 2);
w = min (w, max_pattern_metric_size + 2);
if (w != alloc.get_width()) {
alloc.set_width (w);
}
if (pixwidth != w) {
fgpattern = request_horizontal_meter (w, request_height, _clr, _stp, _styleflags);
bgpattern = request_horizontal_background (w, request_height, highlight ? _bgh : _bgc, false);
pixwidth = w;
pixheight = request_height;
}
CairoWidget::on_size_allocate (alloc);
}
void
FastMeter::render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t* area)
{
if (orientation == Vertical) {
return vertical_expose (cr->cobj(), area);
} else {
return horizontal_expose (cr->cobj(), area);
}
}
void
FastMeter::vertical_expose (cairo_t* cr, cairo_rectangle_t* area)
{
gint top_of_meter;
// GdkRectangle background;
// GdkRectangle eventarea;
//cairo_set_source_rgb (cr, 0, 0, 0); // black
//rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
//cairo_stroke (cr);
top_of_meter = (gint) floor (pixheight * current_level);
/* reset the height & origin of the rect that needs to show the pixbuf
*/
pixrect.height = top_of_meter;
pixrect.y = pixheight - top_of_meter;
// background.x = 0;
// background.y = 0;
// background.width = pixrect.width;
// background.height = pixheight - top_of_meter;
// eventarea.x = area->x;
// eventarea.y = area->y;
// eventarea.width = area->width;
// eventarea.height = area->height;
// Switching to CAIRO we would like to draw on the container's bkg.
// if (gdk_rectangle_intersect (&background, &eventarea, &intersection)) {
// cairo_set_source (cr, bgpattern->cobj());
// cairo_rectangle (cr, intersection.x, intersection.y, intersection.width, intersection.height);
// cairo_fill (cr);
// }
// MEMO: Normaly MATURE OS clips so called invalidated rects itself making APP free of
// heavy operations which OS does with graphic HW
// NOTE FROM PAUL: GTK does clip already. The invalidated rect isn't the only area
// we want to clip to however, which is why this object/class is called FastMeter.
// I have left stuff commented out as I found it when I merged from Ardour in August 2014,
// but this commenting and the previous MEMO comment represent a misunderstanding
// of what this code is doing.
// if (gdk_rectangle_intersect (&pixrect, &eventarea, &intersection)) {
// draw the part of the meter image that we need. the area we draw is bounded "in reverse" (top->bottom)
//cairo_set_source (cr, fgpattern->cobj());
cairo_set_source_rgba (cr, 0.69, 0.69, 0.69, 1);
cairo_rectangle (cr, pixrect.x, pixrect.y, pixrect.width, pixrect.height);
cairo_fill (cr);
//}
// draw peak bar
if (hold_state) {
last_peak_rect.x = 0;
last_peak_rect.width = pixwidth;
last_peak_rect.y = max(0, pixheight - (gint) floor (pixheight * current_peak));
if (bright_hold || (_styleflags & 2)) {
last_peak_rect.height = max(0, min(3, pixheight - last_peak_rect.y ));
} else {
last_peak_rect.height = max(0, min(2, pixheight - last_peak_rect.y ));
}
cairo_set_source (cr, fgpattern->cobj());
cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
if (bright_hold && !no_rgba_overlay) {
cairo_fill_preserve (cr);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.3);
}
cairo_fill (cr);
} else {
last_peak_rect.width = 0;
last_peak_rect.height = 0;
}
}
void
FastMeter::horizontal_expose (cairo_t* cr, cairo_rectangle_t* area)
{
gint right_of_meter;
//cairo_set_source_rgb (cr, 0, 0, 0); // black
//rounded_rectangle (cr, 0, 0, pixwidth + 2, pixheight + 2, 2);
//cairo_stroke (cr);
right_of_meter = (gint) floor (pixwidth * current_level);
/* reset the height & origin of the rect that needs to show the pixbuf
*/
pixrect.width = right_of_meter;
// draw peak bar
if (hold_state) {
last_peak_rect.y = 1;
last_peak_rect.height = pixheight;
const int xpos = floor (pixwidth * current_peak);
if (bright_hold || (_styleflags & 2)) {
last_peak_rect.width = min(3, xpos );
} else {
last_peak_rect.width = min(2, xpos );
}
last_peak_rect.x = 1 + max(0, xpos - last_peak_rect.width);
cairo_set_source (cr, fgpattern->cobj());
cairo_rectangle (cr, last_peak_rect.x, last_peak_rect.y, last_peak_rect.width, last_peak_rect.height);
if (bright_hold && !no_rgba_overlay) {
cairo_fill_preserve (cr);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.3);
}
cairo_fill (cr);
} else {
last_peak_rect.width = 0;
last_peak_rect.height = 0;
}
}
void
FastMeter::set (float lvl, float peak)
{
float old_level = current_level;
float old_peak = current_peak;
if (pixwidth <= 0 || pixheight <=0) return;
if (peak == -1) {
if (lvl >= current_peak) {
current_peak = lvl;
hold_state = hold_cnt;
}
if (hold_state > 0) {
if (--hold_state == 0) {
current_peak = lvl;
}
}
bright_hold = false;
} else {
current_peak = peak;
hold_state = 1;
bright_hold = true;
}
current_level = lvl;
if (current_level == old_level && current_peak == old_peak && (hold_state == 0 || peak != -1)) {
return;
}
Glib::RefPtr<Gdk::Window> win;
if ((win = get_window()) == 0) {
queue_draw ();
return;
}
if (orientation == Vertical) {
queue_vertical_redraw (win, old_level);
} else {
queue_horizontal_redraw (win, old_level);
}
}
void
FastMeter::queue_vertical_redraw (const Glib::RefPtr<Gdk::Window>& win, float old_level)
{
GdkRectangle rect;
gint new_top = (gint) floor (pixheight * current_level);
rect.x = 0;
rect.width = pixwidth;
rect.height = new_top;
rect.y = pixheight - new_top;
if (current_level > old_level) {
/* colored/pixbuf got larger, just draw the new section */
/* rect.y stays where it is because of X coordinates */
/* height of invalidated area is between new.y (smaller) and old.y
(larger).
X coordinates just make my brain hurt.
*/
rect.height = pixrect.y - rect.y;
} else {
/* it got smaller, compute the difference */
/* rect.y becomes old.y (the smaller value) */
rect.y = pixrect.y;
/* rect.height is the old.y (smaller) minus the new.y (larger)
*/
rect.height = pixrect.height - rect.height;
}
GdkRegion* region = 0;
bool queue = false;
if (rect.height != 0) {
/* ok, first region to draw ... */
region = gdk_region_rectangle (&rect);
queue = true;
}
/* redraw the last place where the last peak hold bar was;
the next expose will draw the new one whether its part of
expose region or not.
*/
if (last_peak_rect.width * last_peak_rect.height != 0) {
if (!queue) {
region = gdk_region_new ();
queue = true;
}
gdk_region_union_with_rect (region, &last_peak_rect);
}
if (hold_state && current_peak > 0) {
if (!queue) {
region = gdk_region_new ();
queue = true;
}
rect.x = 1;
rect.y = max(1, 1 + pixheight - (gint) floor (pixheight * current_peak));
if (bright_hold || (_styleflags & 2)) {
rect.height = max(0, min(3, pixheight - last_peak_rect.y -1 ));
} else {
rect.height = max(0, min(2, pixheight - last_peak_rect.y -1 ));
}
rect.width = pixwidth;
gdk_region_union_with_rect (region, &rect);
}
if (queue) {
gdk_window_invalidate_region (win->gobj(), region, true);
}
if (region) {
gdk_region_destroy(region);
region = 0;
}
}
void
FastMeter::queue_horizontal_redraw (const Glib::RefPtr<Gdk::Window>& win, float old_level)
{
GdkRectangle rect;
gint new_right = (gint) floor (pixwidth * current_level);
rect.height = pixheight;
rect.y = 1;
if (current_level > old_level) {
rect.x = 1 + pixrect.width;
/* colored/pixbuf got larger, just draw the new section */
rect.width = new_right - pixrect.width;
} else {
/* it got smaller, compute the difference */
rect.x = 1 + new_right;
/* rect.height is the old.x (smaller) minus the new.x (larger) */
rect.width = pixrect.width - new_right;
}
GdkRegion* region = 0;
bool queue = false;
if (rect.height != 0) {
/* ok, first region to draw ... */
region = gdk_region_rectangle (&rect);
queue = true;
}
/* redraw the last place where the last peak hold bar was;
the next expose will draw the new one whether its part of
expose region or not.
*/
if (last_peak_rect.width * last_peak_rect.height != 0) {
if (!queue) {
region = gdk_region_new ();
queue = true;
}
gdk_region_union_with_rect (region, &last_peak_rect);
}
if (hold_state && current_peak > 0) {
if (!queue) {
region = gdk_region_new ();
queue = true;
}
rect.y = 1;
rect.height = pixheight;
const int xpos = floor (pixwidth * current_peak);
if (bright_hold || (_styleflags & 2)) {
rect.width = min(3, xpos);
} else {
rect.width = min(2, xpos);
}
rect.x = 1 + max(0, xpos - rect.width);
gdk_region_union_with_rect (region, &rect);
}
if (queue) {
gdk_window_invalidate_region (win->gobj(), region, true);
}
if (region) {
gdk_region_destroy(region);
region = 0;
}
}
void
FastMeter::set_highlight (bool onoff)
{
if (highlight == onoff) {
return;
}
highlight = onoff;
if (orientation == Vertical) {
bgpattern = request_vertical_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, false);
} else {
bgpattern = request_horizontal_background (pixwidth + 2, pixheight + 2, highlight ? _bgh : _bgc, false);
}
queue_draw ();
}
void
FastMeter::clear ()
{
current_level = 0;
current_peak = 0;
hold_state = 0;
queue_draw ();
}

View File

@ -27,10 +27,7 @@ gtkmm2ext_sources = [
'application.cc',
'ardour_icon.cc',
'binding_proxy.cc',
'bindable_button.cc',
'bindings.cc',
'cairocell.cc',
'cairo_icon.cc',
'cairo_packer.cc',
'cairo_widget.cc',
'cell_renderer_color_selector.cc',
@ -42,20 +39,16 @@ gtkmm2ext_sources = [
'dndtreeview.cc',
'emscale.cc',
'eventboxext.cc',
'grouped_buttons.cc',
'gtk_ui.cc',
'gtkapplication.c',
'idle_adjustment.cc',
'keyboard.cc',
'menu_elems.cc',
'pane.cc',
'paths_dialog.cc',
'persistent_tooltip.cc',
'pixscroller.cc',
'popup.cc',
'prompter.cc',
'scroomer.cc',
'selector.cc',
'stateful_button.cc',
'tabbable.cc',
'tearoff.cc',
@ -86,8 +79,6 @@ def configure(conf):
def build(bld):
# operate on copy to avoid adding sources twice
sources = list(gtkmm2ext_sources)
if bld.is_tracks_build():
sources += [ 'waves_fastmeter.cc', 'fader.cc' ]
if bld.is_defined ('INTERNAL_SHARED_LIBS'):
obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=sources)