#include <clocale>
#include <cstring>
#include <cctype>
+#include <cmath>
#include <fstream>
#include <list>
#include <sys/stat.h>
-#include <libart_lgpl/art_misc.h>
#include <gtkmm/rc.h>
#include <gtkmm/window.h>
#include <gtkmm/combo.h>
#include <gtkmm2ext/utils.h>
#include "ardour/rc_configuration.h"
-
#include "ardour/filesystem_paths.h"
+#include "canvas/item.h"
+#include "canvas/utils.h"
+
#include "ardour_ui.h"
#include "debug.h"
#include "public_editor.h"
#include "utils.h"
#include "i18n.h"
#include "rgb_macros.h"
-#include "canvas_impl.h"
#include "gui_thread.h"
using namespace std;
sigc::signal<void> DPIReset;
+#ifdef PLATFORM_WINDOWS
+#define random() rand()
+#endif
+
/** Add an element to a menu, settings its sensitivity.
* @param m Menu to add to.
return (savergb);
}
-ArdourCanvas::Points*
-get_canvas_points (string /*who*/, uint32_t npoints)
-{
- // cerr << who << ": wants " << npoints << " canvas points" << endl;
-#ifdef TRAP_EXCESSIVE_POINT_REQUESTS
- if (npoints > (uint32_t) gdk_screen_width() + 4) {
- abort ();
- }
-#endif
- return new ArdourCanvas::Points (npoints);
-}
-
Pango::FontDescription
get_font_for_style (string widgetname)
{
if (state == Gtk::STATE_NORMAL && rgba) {
return (uint32_t) RGBA_TO_UINT(r,g,b,a);
} else {
- return (uint32_t) RGB_TO_UINT(r,g,b);
+ return (uint32_t) RGBA_TO_UINT(r,g,b,255);
}
}
return true;
}
-bool
-canvas_item_visible (ArdourCanvas::Item* item)
+void
+set_color_from_rgb (Gdk::Color& c, uint32_t rgb)
{
- return (item->gobj()->object.flags & GNOME_CANVAS_ITEM_VISIBLE) ? true : false;
+ /* Gdk::Color color ranges are 16 bit, so scale from 8 bit by
+ multiplying by 256.
+ */
+ c.set_rgb ((rgb >> 16)*256, ((rgb & 0xff00) >> 8)*256, (rgb & 0xff)*256);
}
void
-set_color (Gdk::Color& c, int rgb)
+set_color_from_rgba (Gdk::Color& c, uint32_t rgba)
+{
+ /* Gdk::Color color ranges are 16 bit, so scale from 8 bit by
+ multiplying by 256.
+ */
+ c.set_rgb ((rgba >> 24)*256, ((rgba & 0xff0000) >> 16)*256, ((rgba & 0xff00) >> 8)*256);
+}
+
+uint32_t
+gdk_color_to_rgba (Gdk::Color const& c)
{
- c.set_rgb((rgb >> 16)*256, ((rgb & 0xff00) >> 8)*256, (rgb & 0xff)*256);
+ /* since alpha value is not available from a Gdk::Color, it is
+ hardcoded as 0xff (aka 255 or 1.0)
+ */
+
+ const uint32_t r = c.get_red_p () * 255.0;
+ const uint32_t g = c.get_green_p () * 255.0;
+ const uint32_t b = c.get_blue_p () * 255.0;
+ const uint32_t a = 0xff;
+
+ return RGBA_TO_UINT (r,g,b,a);
+}
+
+uint32_t
+contrasting_text_color (uint32_t c)
+{
+ double r, g, b, a;
+ ArdourCanvas::color_to_rgba (c, r, g, b, a);
+
+ const double black_r = 0.0;
+ const double black_g = 0.0;
+ const double black_b = 0.0;
+
+ const double white_r = 1.0;
+ const double white_g = 1.0;
+ const double white_b = 1.0;
+
+ /* Use W3C contrast guideline calculation */
+
+ double white_contrast = (max (r, white_r) - min (r, white_r)) +
+ (max (g, white_g) - min (g, white_g)) +
+ (max (b, white_b) - min (b, white_b));
+
+ double black_contrast = (max (r, black_r) - min (r, black_r)) +
+ (max (g, black_g) - min (g, black_g)) +
+ (max (b, black_b) - min (b, black_b));
+
+ if (white_contrast > black_contrast) {
+ /* use white */
+ return ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0);
+ } else {
+ /* use black */
+ return ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0);
+ }
}
bool
relay_key_press (GdkEventKey* ev, Gtk::Window* win)
{
+ PublicEditor& ed (PublicEditor::instance());
+
if (!key_press_focus_accelerator_handler (*win, ev)) {
- return PublicEditor::instance().on_key_press_event(ev);
+ if (&ed == 0) {
+ /* early key press in pre-main-window-dialogs, no editor yet */
+ return false;
+ }
+ return ed.on_key_press_event(ev);
} else {
return true;
}
ev.state = 0;
ev.keyval = keyval;
ev.length = 0;
- ev.string = (const gchar*) "";
+ ev.string = const_cast<gchar*> ("");
ev.hardware_keycode = keymapkey[0].keycode;
ev.group = keymapkey[0].group;
g_free(keymapkey);
{
if (!xpm_map[name]) {
- SearchPath spath(ARDOUR::ardour_data_search_path());
+ Searchpath spath(ARDOUR::ardour_data_search_path());
spath.add_subdirectory_to_paths("pixmaps");
return xpm_map[name];
}
+vector<string>
+get_icon_sets ()
+{
+ Searchpath spath(ARDOUR::ardour_data_search_path());
+ spath.add_subdirectory_to_paths ("icons");
+ vector<string> r;
+
+ r.push_back (_("default"));
+
+ for (vector<string>::iterator s = spath.begin(); s != spath.end(); ++s) {
+
+ vector<string> entries;
+
+ get_files_in_directory (*s, entries);
+
+ for (vector<string>::iterator e = entries.begin(); e != entries.end(); ++e) {
+
+ string d = *e;
+
+ /* ignore dotfiles, . and .. */
+
+ if (d.empty() || d[0] == '.') {
+ continue;
+ }
+
+ Glib::ustring path = Glib::build_filename (*s, *e);
+
+ if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
+ r.push_back (Glib::filename_to_utf8 (*e));
+ }
+ }
+ }
+
+ return r;
+}
+
std::string
-get_icon_path (const char* cname)
+get_icon_path (const char* cname, string icon_set)
{
+ std::string data_file_path;
string name = cname;
name += X_(".png");
- SearchPath spath(ARDOUR::ardour_data_search_path());
+ Searchpath spath(ARDOUR::ardour_data_search_path());
- spath.add_subdirectory_to_paths("icons");
-
- std::string data_file_path;
+ if (!icon_set.empty() && icon_set != _("default")) {
- if (!find_file_in_search_path (spath, name, data_file_path)) {
- fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg;
+ /* add "icons/icon_set" but .. not allowed to add both of these at once */
+ spath.add_subdirectory_to_paths ("icons");
+ spath.add_subdirectory_to_paths (icon_set);
+
+ find_file_in_search_path (spath, name, data_file_path);
+ }
+
+ if (data_file_path.empty()) {
+
+ if (!icon_set.empty() && icon_set != _("default")) {
+ warning << string_compose (_("icon \"%1\" not found for icon set \"%2\", fallback to default"), cname, icon_set) << endmsg;
+ }
+
+ Searchpath def (ARDOUR::ardour_data_search_path());
+ def.add_subdirectory_to_paths ("icons");
+
+ if (!find_file_in_search_path (def, name, data_file_path)) {
+ fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg;
+ /*NOTREACHED*/
+ }
}
return data_file_path;
}
+Glib::RefPtr<Gdk::Pixbuf>
+get_icon (const char* cname, string icon_set)
+{
+ Glib::RefPtr<Gdk::Pixbuf> img;
+ try {
+ img = Gdk::Pixbuf::create_from_file (get_icon_path (cname, icon_set));
+ } catch (const Gdk::PixbufError &e) {
+ cerr << "Caught PixbufError: " << e.what() << endl;
+ } catch (...) {
+ error << string_compose (_("Caught exception while loading icon named %1"), cname) << endmsg;
+ }
+
+ return img;
+}
+
Glib::RefPtr<Gdk::Pixbuf>
get_icon (const char* cname)
{
/* FT2 rendering - used by GnomeCanvas, sigh */
+#ifndef PLATFORM_WINDOWS
pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_new(), val/1024, val/1024);
+#endif
/* Cairo rendering, in case there is any */
while (1) {
- /* avoid neon/glowing tones by limiting them to the
- "inner section" (paler) of a color wheel/circle.
- */
+ double h, s, v;
- const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
+ h = fmod (random(), 360.0);
+ s = (random() % 65535) / 65535.0;
+ v = (random() % 65535) / 65535.0;
- newcolor.set_red (random() % max_saturation);
- newcolor.set_blue (random() % max_saturation);
- newcolor.set_green (random() % max_saturation);
+ s = min (0.5, s); /* not too saturated */
+ v = max (0.9, v); /* not too bright */
+ newcolor.set_hsv (h, s, v);
if (used_colors.size() == 0) {
used_colors.push_back (newcolor);
gdelta = newcolor.get_green() - c.get_green();
if (sqrt (rdelta*rdelta + bdelta*bdelta + gdelta*gdelta) > 25.0) {
+ /* different enough */
used_colors.push_back (newcolor);
return newcolor;
}
/* XXX need throttle here to make sure we don't spin for ever */
}
}
+
+string
+rate_as_string (float r)
+{
+ char buf[32];
+ if (fmod (r, 1000.0f)) {
+ snprintf (buf, sizeof (buf), "%.1f kHz", r/1000.0);
+ } else {
+ snprintf (buf, sizeof (buf), "%.0f kHz", r/1000.0);
+ }
+ return buf;
+}