mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
Remove unused sources & includes
This commit is contained in:
parent
f6e182b937
commit
b5e9451bc7
44 changed files with 5 additions and 3536 deletions
|
|
@ -55,8 +55,6 @@
|
||||||
#include <gtkmm/adjustment.h>
|
#include <gtkmm/adjustment.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/bindings.h"
|
#include "gtkmm2ext/bindings.h"
|
||||||
#include "gtkmm2ext/visibility_tracker.h"
|
#include "gtkmm2ext/visibility_tracker.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@
|
||||||
#include "pbd/basename.h"
|
#include "pbd/basename.h"
|
||||||
#include "pbd/fastlog.h"
|
#include "pbd/fastlog.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/cairocell.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/window_title.h"
|
#include "gtkmm2ext/window_title.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
#include <gtkmm/style.h>
|
#include <gtkmm/style.h>
|
||||||
#include <sigc++/bind.h>
|
#include <sigc++/bind.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/cairocell.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/rgb_macros.h"
|
#include "gtkmm2ext/rgb_macros.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/selector.h"
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
||||||
#include "widgets/ardour_button.h"
|
#include "widgets/ardour_button.h"
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
#include <gtkmm/radiomenuitem.h>
|
#include <gtkmm/radiomenuitem.h>
|
||||||
#include <gtkmm/checkmenuitem.h>
|
#include <gtkmm/checkmenuitem.h>
|
||||||
|
|
||||||
#include <gtkmm2ext/selector.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#include "pbd/i18n.h"
|
#include "pbd/i18n.h"
|
||||||
|
|
||||||
#include <gtkmm2ext/utils.h>
|
#include <gtkmm2ext/utils.h>
|
||||||
#include <gtkmm2ext/selector.h>
|
|
||||||
#include <gtkmm2ext/gtk_ui.h>
|
#include <gtkmm2ext/gtk_ui.h>
|
||||||
|
|
||||||
#include "ardour/selection.h"
|
#include "ardour/selection.h"
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,8 @@
|
||||||
|
|
||||||
#include "gtkmm2ext/bindings.h"
|
#include "gtkmm2ext/bindings.h"
|
||||||
#include "gtkmm2ext/eventboxext.h"
|
#include "gtkmm2ext/eventboxext.h"
|
||||||
#include "gtkmm2ext/grouped_buttons.h"
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include <gtkmm2ext/keyboard.h>
|
#include "gtkmm2ext/keyboard.h"
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/window_title.h"
|
#include "gtkmm2ext/window_title.h"
|
||||||
#include "gtkmm2ext/choice.h"
|
#include "gtkmm2ext/choice.h"
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@
|
||||||
#include "gtkmm2ext/bindings.h"
|
#include "gtkmm2ext/bindings.h"
|
||||||
#include "gtkmm2ext/dndtreeview.h"
|
#include "gtkmm2ext/dndtreeview.h"
|
||||||
#include "gtkmm2ext/pane.h"
|
#include "gtkmm2ext/pane.h"
|
||||||
#include "gtkmm2ext/selector.h"
|
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
|
||||||
|
|
||||||
#include "pbd/stateful.h"
|
#include "pbd/stateful.h"
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
|
|
@ -114,7 +112,6 @@ class EditorRoutes;
|
||||||
class EditorRouteGroups;
|
class EditorRouteGroups;
|
||||||
class EditorSnapshots;
|
class EditorSnapshots;
|
||||||
class EditorSummary;
|
class EditorSummary;
|
||||||
class GroupedButtons;
|
|
||||||
class GUIObjectState;
|
class GUIObjectState;
|
||||||
class ArdourMarker;
|
class ArdourMarker;
|
||||||
class MidiRegionView;
|
class MidiRegionView;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
#ifndef __gtk_ardour_editor_route_groups_h__
|
#ifndef __gtk_ardour_editor_route_groups_h__
|
||||||
#define __gtk_ardour_editor_route_groups_h__
|
#define __gtk_ardour_editor_route_groups_h__
|
||||||
|
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
|
||||||
#include "editor_component.h"
|
#include "editor_component.h"
|
||||||
|
|
||||||
class EditorRouteGroups : public EditorComponent, public ARDOUR::SessionHandlePtr
|
class EditorRouteGroups : public EditorComponent, public ARDOUR::SessionHandlePtr
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "gtkmm/button.h"
|
#include "gtkmm/button.h"
|
||||||
#include "gtkmm/radiobutton.h"
|
#include "gtkmm/radiobutton.h"
|
||||||
#include "gtkmm/label.h"
|
#include "gtkmm/label.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
#include "gtkmm2ext/stateful_button.h"
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@
|
||||||
#include "pbd/stateful_diff_command.h"
|
#include "pbd/stateful_diff_command.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/selector.h"
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
||||||
#include "widgets/tooltips.h"
|
#include "widgets/tooltips.h"
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@
|
||||||
#include <gtkmm/radiomenuitem.h>
|
#include <gtkmm/radiomenuitem.h>
|
||||||
#include <gtkmm/checkmenuitem.h>
|
#include <gtkmm/checkmenuitem.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/selector.h"
|
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
#include "ardour/region.h"
|
#include "ardour/region.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/choice.h"
|
#include "gtkmm2ext/choice.h"
|
||||||
#include "gtkmm2ext/doi.h"
|
#include "gtkmm2ext/doi.h"
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
|
|
||||||
#include "widgets/tooltips.h"
|
#include "widgets/tooltips.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,6 @@
|
||||||
#include <gtkmm/textview.h>
|
#include <gtkmm/textview.h>
|
||||||
#include <gtkmm/adjustment.h>
|
#include <gtkmm/adjustment.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
|
||||||
|
|
||||||
#include "pbd/stateful.h"
|
#include "pbd/stateful.h"
|
||||||
|
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
#include "pbd/replace_all.h"
|
#include "pbd/replace_all.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/tearoff.h"
|
#include "gtkmm2ext/tearoff.h"
|
||||||
#include "gtkmm2ext/actions.h"
|
#include "gtkmm2ext/actions.h"
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#include <gtkmm/table.h>
|
#include <gtkmm/table.h>
|
||||||
#include <gtkmm/eventbox.h>
|
#include <gtkmm/eventbox.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/bindings.h"
|
#include "gtkmm2ext/bindings.h"
|
||||||
|
|
||||||
#include "widgets/ardour_button.h"
|
#include "widgets/ardour_button.h"
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
#include <gtkmm/scrolledwindow.h>
|
#include <gtkmm/scrolledwindow.h>
|
||||||
#include <gtkmm/button.h>
|
#include <gtkmm/button.h>
|
||||||
#include <gtkmm/treeview.h>
|
#include <gtkmm/treeview.h>
|
||||||
#include <gtkmm2ext/selector.h>
|
#include <gtkmm/treestore.h>
|
||||||
|
|
||||||
#include "ardour_dialog.h"
|
#include "ardour_dialog.h"
|
||||||
#include "ardour/session_handle.h"
|
#include "ardour/session_handle.h"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include <gtkmm/notebook.h>
|
#include <gtkmm/notebook.h>
|
||||||
#include <gtkmm/treeview.h>
|
#include <gtkmm/treeview.h>
|
||||||
#include "gtkmm2ext/dndtreeview.h"
|
#include "gtkmm2ext/dndtreeview.h"
|
||||||
#include <gtkmm2ext/selector.h>
|
|
||||||
|
|
||||||
#include "ardour/plugin.h"
|
#include "ardour/plugin.h"
|
||||||
#include "ardour/session_handle.h"
|
#include "ardour/session_handle.h"
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,6 @@
|
||||||
#include "gtkmm/menu.h"
|
#include "gtkmm/menu.h"
|
||||||
#include "gtkmm/menuitem.h"
|
#include "gtkmm/menuitem.h"
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/selector.h"
|
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
||||||
#include "widgets/ardour_button.h"
|
#include "widgets/ardour_button.h"
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@
|
||||||
#include <gtkmm/checkmenuitem.h>
|
#include <gtkmm/checkmenuitem.h>
|
||||||
#include <gtkmm/adjustment.h>
|
#include <gtkmm/adjustment.h>
|
||||||
|
|
||||||
#include <gtkmm2ext/selector.h>
|
|
||||||
|
|
||||||
#include "widgets/ardour_button.h"
|
#include "widgets/ardour_button.h"
|
||||||
|
|
||||||
#include "ardour/playlist.h"
|
#include "ardour/playlist.h"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/choice.h"
|
#include "gtkmm2ext/choice.h"
|
||||||
#include "gtkmm2ext/doi.h"
|
#include "gtkmm2ext/doi.h"
|
||||||
#include "gtkmm2ext/bindable_button.h"
|
|
||||||
#include "gtkmm2ext/gtk_ui.h"
|
#include "gtkmm2ext/gtk_ui.h"
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
|
|
||||||
|
|
@ -1431,10 +1430,6 @@ RouteUI::build_solo_menu (void)
|
||||||
items.push_back (CheckMenuElem(*check));
|
items.push_back (CheckMenuElem(*check));
|
||||||
solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
|
solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
|
||||||
check->show_all();
|
check->show_all();
|
||||||
|
|
||||||
//items.push_back (SeparatorElem());
|
|
||||||
// items.push_back (MenuElem (_("MIDI Bind"), sigc::mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1471,9 +1466,6 @@ RouteUI::build_mute_menu(void)
|
||||||
items.push_back (CheckMenuElem(*main_mute_check));
|
items.push_back (CheckMenuElem(*main_mute_check));
|
||||||
main_mute_check->show_all();
|
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());
|
_route->mute_points_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::muting_change, this), gui_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
#include "gtkmm2ext/keyboard.h"
|
#include "gtkmm2ext/keyboard.h"
|
||||||
#include "gtkmm2ext/gui_thread.h"
|
#include "gtkmm2ext/gui_thread.h"
|
||||||
#include "gtkmm2ext/cairocell.h"
|
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/rgb_macros.h"
|
#include "gtkmm2ext/rgb_macros.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
#include <gtkmm2ext/doi.h>
|
#include <gtkmm2ext/doi.h>
|
||||||
#include <gtkmm2ext/utils.h>
|
#include <gtkmm2ext/utils.h>
|
||||||
#include <gtkmm2ext/selector.h>
|
|
||||||
|
|
||||||
#include "canvas/canvas.h"
|
#include "canvas/canvas.h"
|
||||||
#include "canvas/rectangle.h"
|
#include "canvas/rectangle.h"
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,8 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "pbd/compose.h"
|
#include "pbd/compose.h"
|
||||||
|
|
||||||
#include "gtkmm2ext/cairocell.h"
|
|
||||||
#include "gtkmm2ext/gui_thread.h"
|
#include "gtkmm2ext/gui_thread.h"
|
||||||
#include "gtkmm2ext/utils.h"
|
#include "gtkmm2ext/utils.h"
|
||||||
#include "gtkmm2ext/stateful_button.h"
|
|
||||||
#include "gtkmm2ext/actions.h"
|
#include "gtkmm2ext/actions.h"
|
||||||
|
|
||||||
#include "ardour/location.h"
|
#include "ardour/location.h"
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <gtkmm/table.h>
|
#include <gtkmm/table.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/cairo_packer.h"
|
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
#include "ardour/session_handle.h"
|
#include "ardour/session_handle.h"
|
||||||
|
|
||||||
|
#include "gtkmm2ext/cairo_packer.h"
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
class Session;
|
class Session;
|
||||||
class Location;
|
class Location;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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 ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__ */
|
|
||||||
|
|
@ -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__
|
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <gtkmm/notebook.h>
|
#include <gtkmm/notebook.h>
|
||||||
|
|
||||||
#include "gtkmm2ext/cairo_icon.h"
|
|
||||||
#include "gtkmm2ext/window_proxy.h"
|
#include "gtkmm2ext/window_proxy.h"
|
||||||
#include "gtkmm2ext/visibility.h"
|
#include "gtkmm2ext/visibility.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 ();
|
|
||||||
}
|
|
||||||
|
|
@ -27,10 +27,7 @@ gtkmm2ext_sources = [
|
||||||
'application.cc',
|
'application.cc',
|
||||||
'ardour_icon.cc',
|
'ardour_icon.cc',
|
||||||
'binding_proxy.cc',
|
'binding_proxy.cc',
|
||||||
'bindable_button.cc',
|
|
||||||
'bindings.cc',
|
'bindings.cc',
|
||||||
'cairocell.cc',
|
|
||||||
'cairo_icon.cc',
|
|
||||||
'cairo_packer.cc',
|
'cairo_packer.cc',
|
||||||
'cairo_widget.cc',
|
'cairo_widget.cc',
|
||||||
'cell_renderer_color_selector.cc',
|
'cell_renderer_color_selector.cc',
|
||||||
|
|
@ -42,20 +39,16 @@ gtkmm2ext_sources = [
|
||||||
'dndtreeview.cc',
|
'dndtreeview.cc',
|
||||||
'emscale.cc',
|
'emscale.cc',
|
||||||
'eventboxext.cc',
|
'eventboxext.cc',
|
||||||
'grouped_buttons.cc',
|
|
||||||
'gtk_ui.cc',
|
'gtk_ui.cc',
|
||||||
'gtkapplication.c',
|
'gtkapplication.c',
|
||||||
'idle_adjustment.cc',
|
|
||||||
'keyboard.cc',
|
'keyboard.cc',
|
||||||
'menu_elems.cc',
|
'menu_elems.cc',
|
||||||
'pane.cc',
|
'pane.cc',
|
||||||
'paths_dialog.cc',
|
'paths_dialog.cc',
|
||||||
'persistent_tooltip.cc',
|
'persistent_tooltip.cc',
|
||||||
'pixscroller.cc',
|
|
||||||
'popup.cc',
|
'popup.cc',
|
||||||
'prompter.cc',
|
'prompter.cc',
|
||||||
'scroomer.cc',
|
'scroomer.cc',
|
||||||
'selector.cc',
|
|
||||||
'stateful_button.cc',
|
'stateful_button.cc',
|
||||||
'tabbable.cc',
|
'tabbable.cc',
|
||||||
'tearoff.cc',
|
'tearoff.cc',
|
||||||
|
|
@ -86,8 +79,6 @@ def configure(conf):
|
||||||
def build(bld):
|
def build(bld):
|
||||||
# operate on copy to avoid adding sources twice
|
# operate on copy to avoid adding sources twice
|
||||||
sources = list(gtkmm2ext_sources)
|
sources = list(gtkmm2ext_sources)
|
||||||
if bld.is_tracks_build():
|
|
||||||
sources += [ 'waves_fastmeter.cc', 'fader.cc' ]
|
|
||||||
|
|
||||||
if bld.is_defined ('INTERNAL_SHARED_LIBS'):
|
if bld.is_defined ('INTERNAL_SHARED_LIBS'):
|
||||||
obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=sources)
|
obj = bld.shlib(features = 'c cxx cshlib cxxshlib', source=sources)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue