Adding XML scripting to ArdourCanvas

[git-p4: depot-paths = "//Abdaw/dev_main/tracks/": change = 452743]
This commit is contained in:
Valeriy Kamyshniy 2014-04-14 12:37:20 -05:00
parent 8cbcffc3ad
commit a1709c74c6
24 changed files with 534 additions and 122 deletions

View file

@ -173,9 +173,9 @@ WavesDialog::read_layout (std::string file_name)
return false;
}
std::string title = WavesUI::xml_property (*root, "title", WavesUI::XMLNodeMap(), "");
std::string title = xml_property (*root, "title", "");
set_title(title);
bool resizeable = WavesUI::xml_property (*root, "resizeable", WavesUI::XMLNodeMap(), false);
bool resizeable = xml_property (*root, "resizeable", false);
property_allow_grow().set_value(resizeable);
set_border_width(0);

View file

@ -23,6 +23,9 @@
#include <gtkmm.h>
#include "ardour/session_handle.h"
#include "canvas/xml_ui.h"
using namespace ArdourCanvas::XMLUI;
namespace WM {
class ProxyTemporary;

View file

@ -17,159 +17,87 @@
*/
#include "waves_ui.h"
#include "canvas/canvas.h"
#include "waves_button.h"
//std::ofstream dbg_out("/users/WavesUILog.txt");
void
WavesUI::get_styles(const XMLTree& layout, WavesUI::XMLNodeMap &styles)
{
XMLNode* root = layout.root();
if (root != NULL) {
for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
if ( !strcasecmp((*i)->name().c_str(), "style")) {
std::string style_name = ((*i)->property("name") ? (*i)->property("name")->value() : std::string(""));
if (!style_name.empty()) {
styles[style_name] = *i;
}
}
}
}
}
double
WavesUI::xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, double default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
return atof(property.c_str());
}
int
WavesUI::xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, int default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
return atoi(property.c_str());
}
bool
WavesUI::xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, bool default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
std::transform(property.begin(), property.end(), property.begin(), ::toupper);
return property == "TRUE";
}
std::string
WavesUI::xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, const std::string default_value)
{
std::string property = node.property (prop_name) ? node.property(prop_name)->value() : "";
if (property.empty()) {
std::string style_name = node.property ("style") ? node.property("style")->value() : "";
if (!style_name.empty()) {
XMLNodeMap::const_iterator style = styles.find(style_name);
if (style != styles.end()) {
return WavesUI::xml_property (*style->second, prop_name, styles, default_value);
}
}
}
if (property.empty()) {
return default_value;
}
return property;
}
std::string
WavesUI::xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const char* default_value)
{
return xml_property (node, prop_name, styles, std::string(default_value));
}
Gtk::Widget*
WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Gtk::Widget*> &named_widgets)
{
Gtk::Widget* child = NULL;
std::string widget_type = definition.name();
std::string widget_id = WavesUI::xml_property (definition, "id", styles, "");
std::string widget_id = xml_property (definition, "id", styles, "");
std::string text = WavesUI::xml_property (definition, "text", styles, "");
std::string text = xml_property (definition, "text", styles, "");
boost::replace_all(text, "\\n", "\n");
int height = WavesUI::xml_property (definition, "height", styles, -1);
int width = WavesUI::xml_property (definition, "width", styles, -1);
std::transform(widget_type.begin(), widget_type.end(), widget_type.begin(), ::toupper);
if (widget_type == "BUTTON") {
child = manage (new WavesButton(text));
((WavesButton*)child)->set_border_width (WavesUI::xml_property (definition, "borderwidth", styles, "0").c_str());
((WavesButton*)child)->set_border_color (WavesUI::xml_property (definition, "bordercolor", styles, "#000000").c_str());
((WavesButton*)child)->set_border_width (xml_property (definition, "borderwidth", styles, "0").c_str());
((WavesButton*)child)->set_border_color (xml_property (definition, "bordercolor", styles, "#000000").c_str());
} else if (widget_type == "COMBOBOXTEXT") {
child = manage (new Gtk::ComboBoxText);
} else if (widget_type == "LABEL") {
child = manage (new Gtk::Label(text));
} else if (widget_type == "LAYOUT") {
child = manage (new Gtk::Layout);
} else if (widget_type == "CANVAS") {
std::map<std::string, ArdourCanvas::Item*> named_items;
child = new ArdourCanvas::GtkCanvas(definition, styles, named_items);
}
if (child != NULL) {
int height = xml_property (definition, "height", styles, -1);
int width = xml_property (definition, "width", styles, -1);
child->set_size_request (width, height);
if (!widget_id.empty())
{
named_widgets[widget_id] = child;
}
std::string property = WavesUI::xml_property (definition, "bgnormal", styles, "");
std::string property = xml_property (definition, "bgnormal", styles, "");
if (!property.empty()) {
child->modify_bg(Gtk::STATE_NORMAL, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "bgdisabled", styles, property);
property = xml_property (definition, "bgdisabled", styles, property);
if (!property.empty()) {
child->modify_bg(Gtk::STATE_INSENSITIVE, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "bgactive", styles, "");
property = xml_property (definition, "bgactive", styles, "");
if (!property.empty()) {
child->modify_bg(Gtk::STATE_ACTIVE, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "bghover", styles, "");
property = xml_property (definition, "bghover", styles, "");
if (!property.empty()) {
child->modify_bg(Gtk::STATE_PRELIGHT, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "fgnormal", styles, "");
property = xml_property (definition, "fgnormal", styles, "");
if (!property.empty()) {
child->modify_fg(Gtk::STATE_NORMAL, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "fgdisabled", styles, property);
property = xml_property (definition, "fgdisabled", styles, property);
if (!property.empty()) {
child->modify_fg(Gtk::STATE_INSENSITIVE, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "fgactive", styles, "");
property = xml_property (definition, "fgactive", styles, "");
if (!property.empty()) {
child->modify_fg(Gtk::STATE_ACTIVE, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "fghover", styles, "");
property = xml_property (definition, "fghover", styles, "");
if (!property.empty()) {
child->modify_fg(Gtk::STATE_PRELIGHT, Gdk::Color(property));
}
property = WavesUI::xml_property (definition, "font", styles, "");
property = xml_property (definition, "font", styles, "");
if (!property.empty()) {
child->modify_font(Pango::FontDescription(property));
}
@ -199,8 +127,8 @@ WavesUI::add_widget (Gtk::Layout& parent, const XMLNode& definition, const XMLNo
if (child != NULL)
{
parent.put (*child,
WavesUI::xml_property (definition, "x", styles, 0),
WavesUI::xml_property (definition, "y", styles, 0));
xml_property (definition, "x", styles, 0),
xml_property (definition, "y", styles, 0));
}
return child;
}
@ -235,7 +163,7 @@ void
WavesUI::create_ui (const XMLTree& layout, Gtk::Widget& root, std::map<std::string, Gtk::Widget*> &named_widgets)
{
XMLNodeMap styles;
WavesUI::get_styles(layout, styles);
get_styles(layout, styles);
const XMLNodeList& definition = layout.root()->children();
WavesUI::create_ui (definition, styles, root, named_widgets);
}

View file

@ -17,27 +17,20 @@
*/
#ifndef __WAVES_UI_H__
#define __WAVES_UI_H__
#include <string>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include "gtkmm/box.h"
#include "gtkmm/layout.h"
#include "gtkmm/label.h"
#include "pbd/xml++.h"
#include "waves_button.h"
#include "canvas/xml_ui.h"
using namespace ArdourCanvas::XMLUI;
namespace WavesUI {
typedef std::map<std::string, XMLNode*> XMLNodeMap;
void get_styles(const XMLTree& layout, WavesUI::XMLNodeMap &styles);
double xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, double default_value);
int xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, int default_value);
bool xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, bool default_value);
std::string xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const std::string default_value);
std::string xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const char* default_value);
void create_ui (const XMLTree& layout, Gtk::Widget& root, std::map<std::string, Gtk::Widget*> &named_widgets);
void create_ui (const XMLNodeList& definition, const XMLNodeMap& styles, Gtk::Widget& root, std::map<std::string, Gtk::Widget*> &named_widgets);
Gtk::Widget* create_widget (const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Gtk::Widget*> &named_widgets);
@ -46,3 +39,5 @@ namespace WavesUI {
Gtk::Widget* add_widget (Gtk::Widget& parent, const XMLNode &definition, const XMLNodeMap& styles, std::map<std::string, Gtk::Widget*> &named_widgets);
}
#endif //__WAVES_UI_H__

View file

@ -46,6 +46,18 @@ Canvas::Canvas ()
set_epoch ();
}
Canvas::Canvas (const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: _root (this)
, _scroll_offset_x (0)
, _scroll_offset_y (0)
{
set_epoch ();
const XMLNodeList& children = definition.children();
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
XMLUI::create_item (root(), **i, styles, named_items);
}
}
void
Canvas::scroll_to (Coord x, Coord y)
{
@ -278,6 +290,19 @@ GtkCanvas::GtkCanvas ()
Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK);
}
GtkCanvas::GtkCanvas (const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Canvas(definition, styles, named_items)
, _current_item (0)
, _new_current_item (0)
, _grabbed_item (0)
, _focused_item (0)
{
/* these are the events we want to know about */
add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK |
Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK);
}
void
GtkCanvas::pick_current_item (int state)
{
@ -752,8 +777,11 @@ GtkCanvas::request_size (Duple size)
if (req.y > INT_MAX) {
req.y = INT_MAX;
}
set_size_request (req.x, req.y);
int applied_width;
int applied_height;
get_size_request(applied_width, applied_height);
set_size_request (applied_width == -1 ? req.x : applied_width,
applied_height == -1 ? req.y : applied_height );
}
/** `Grab' an item, so that all events are sent to that item until it is `ungrabbed'.

View file

@ -38,9 +38,11 @@
#include "canvas/root_group.h"
#include "canvas/xml_ui.h"
namespace ArdourCanvas
{
using namespace XMLUI;
class Rect;
class Group;
@ -58,6 +60,7 @@ class LIBCANVAS_API Canvas
{
public:
Canvas ();
Canvas (const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
virtual ~Canvas () {}
/** called to request a redraw of an area of the canvas */
@ -134,6 +137,7 @@ class LIBCANVAS_API GtkCanvas : public Canvas, public Gtk::EventBox
{
public:
GtkCanvas ();
GtkCanvas (const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
void request_redraw (Rect const &);
void request_size (Duple);

View file

@ -27,11 +27,13 @@
#include "canvas/item.h"
namespace ArdourCanvas {
using namespace XMLUI;
class LIBCANVAS_API Fill : virtual public Item
{
public:
Fill (Group *);
Fill (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
virtual void set_fill_color (Color);
virtual void set_fill (bool);

View file

@ -28,13 +28,17 @@
#include "canvas/types.h"
#include "canvas/lookup_table.h"
#include "canvas/xml_ui.h"
namespace ArdourCanvas {
using namespace XMLUI;
class LIBCANVAS_API Group : public Item
{
public:
explicit Group (Group *);
explicit Group (Group *, Duple);
explicit Group (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
~Group ();
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;

View file

@ -30,9 +30,11 @@
#include "canvas/visibility.h"
#include "canvas/types.h"
#include "canvas/xml_ui.h"
namespace ArdourCanvas
{
using namespace XMLUI;
class Canvas;
class Group;
@ -54,6 +56,7 @@ class LIBCANVAS_API Item
public:
Item (Canvas *);
Item (Group *);
Item (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
Item (Group *, Duple);
virtual ~Item ();

View file

@ -32,6 +32,7 @@ class LIBCANVAS_API Outline : virtual public Item
{
public:
Outline (Group *);
Outline (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
virtual ~Outline () {}
Color outline_color () const {

View file

@ -24,17 +24,20 @@
#include "canvas/visibility.h"
#include "canvas/item.h"
#include "canvas/xml_ui.h"
namespace Gdk {
class Pixbuf;
}
namespace ArdourCanvas {
using namespace XMLUI;
class LIBCANVAS_API Pixbuf : public Item
{
public:
Pixbuf (Group *);
Pixbuf (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;
void compute_bounding_box () const;

View file

@ -33,6 +33,7 @@ class LIBCANVAS_API Rectangle : virtual public Item, public Outline, public Fill
{
public:
Rectangle (Group *);
Rectangle (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
Rectangle (Group *, Rect const &);
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;

View file

@ -27,11 +27,13 @@
#include "canvas/item.h"
namespace ArdourCanvas {
using namespace XMLUI;
class LIBCANVAS_API Text : public Item
{
public:
Text (Group *);
Text (Group *, const XMLNode&, const XMLNodeMap&, std::map<std::string, Item*>&);
~Text();
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;

View file

@ -85,6 +85,13 @@ struct LIBCANVAS_API Rect
, y1 (y1_)
{}
Rect (const Duple& p0, const Duple &p1)
: x0 (p0.x)
, y0 (p0.y)
, x1 (p1.x)
, y1 (p1.y)
{}
Coord x0;
Coord y0;
Coord x1;

View file

@ -0,0 +1,64 @@
/*
Copyright (C) 2014 Valeriy Kamyshniy
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 __CANVAS_XML_UI_H__
#define __CANVAS_XML_UI_H__
#include "canvas/visibility.h"
#include <string>
#include <map>
#include <boost/algorithm/string.hpp>
#include <pangomm/layout.h>
#include "pbd/xml++.h"
namespace ArdourCanvas {
class Item;
class Canvas;
class Group;
namespace XMLUI {
typedef std::map<std::string, XMLNode*> XMLNodeMap;
extern LIBCANVAS_API void get_styles(const XMLTree& layout, XMLNodeMap &styles);
extern LIBCANVAS_API double xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, double default_value);
extern LIBCANVAS_API double xml_property (const XMLNode& node, const char* prop_name, double default_value);
extern LIBCANVAS_API int32_t xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, int32_t default_value);
extern LIBCANVAS_API uint32_t xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, uint32_t default_value);
extern LIBCANVAS_API bool xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, bool default_value);
extern LIBCANVAS_API bool xml_property (const XMLNode& node, const char* prop_name, bool default_value);
extern LIBCANVAS_API std::string xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const std::string& default_value);
extern LIBCANVAS_API std::string xml_property (const XMLNode& node, const char* prop_name, const std::string& default_value);
extern LIBCANVAS_API std::string xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const char* default_value);
extern LIBCANVAS_API std::string xml_property (const XMLNode& node, const char* prop_name, const char* default_value);
extern LIBCANVAS_API std::string xml_nodetype(const XMLNode& node);
extern LIBCANVAS_API std::string xml_id(const XMLNode& node);
extern LIBCANVAS_API double xml_x (const XMLNode& node, const XMLNodeMap& styles, double default_value = 0);
extern LIBCANVAS_API double xml_y (const XMLNode& node, const XMLNodeMap& styles, double default_value = 0);
extern LIBCANVAS_API Pango::Alignment xml_text_alignment (const XMLNode& node, const XMLNodeMap& styles, Pango::Alignment default_value = Pango::ALIGN_LEFT);
extern LIBCANVAS_API ArdourCanvas::Item* create_item (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*> &named_items);
}
}
#endif //__CANVAS_XML_UI_H__

View file

@ -37,6 +37,15 @@ Fill::Fill (Group* parent)
}
Fill::Fill (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (parent, definition, styles, named_items)
, _fill_color (xml_property(definition, "fillcolor", styles, 0x000000ff))
, _fill (xml_property(definition, "fill", styles, true))
, _transparent (xml_property(definition, "transparent", styles, false))
{
}
void
Fill::set_fill_color (Color color)
{

View file

@ -56,6 +56,16 @@ Group::Group (Group* parent, Duple position)
}
Group::Group (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (parent, definition, styles, named_items)
, _lut (0)
{
const XMLNodeList& children = definition.children();
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
XMLUI::create_item (this, **i, styles, named_items);
}
}
Group::~Group ()
{
clear_items (true);

View file

@ -42,14 +42,39 @@ Item::Item (Canvas* canvas)
Item::Item (Group* parent)
: _canvas (parent->canvas ())
, _parent (parent)
, _visible (true)
, _bounding_box_dirty (true)
, _ignore_events (false)
{
init ();
}
Item::Item (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: _canvas (parent->canvas ())
, _parent (parent)
, _position(xml_x (definition, styles),
xml_y (definition, styles))
, _visible (xml_property(definition, "visible", styles, true))
, _bounding_box_dirty (true)
, _ignore_events (false)
{
std::string item_id = xml_id (definition);
if (!item_id.empty()) {
named_items[item_id] = this;
}
_position = Duple (xml_x (definition, styles),
xml_y (definition, styles));
init ();
}
Item::Item (Group* parent, Duple position)
: _canvas (parent->canvas())
, _parent (parent)
, _position (position)
, _visible (true)
, _bounding_box_dirty (true)
, _ignore_events (false)
{
init ();
}
@ -57,9 +82,6 @@ Item::Item (Group* parent, Duple position)
void
Item::init ()
{
_visible = true;
_bounding_box_dirty = true;
_ignore_events = false;
if (_parent) {
_parent->add (this);

View file

@ -38,6 +38,16 @@ Outline::Outline (Group* parent)
}
Outline::Outline (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (parent, definition, styles, named_items)
, _outline_color (xml_property(definition, "linecolor", styles, 0x000000ff))
, _outline_width (xml_property(definition, "linewidth", styles, 1.0))
, _outline (xml_property(definition, "contour", styles, true))
{
}
void
Outline::set_outline_color (Color color)
{

View file

@ -16,14 +16,23 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//#include "gtkmm/messagedialog.h"
#include <cairomm/cairomm.h>
#include <gdkmm/general.h>
#include "canvas/pixbuf.h"
#include "pbd/error.h"
#include "pbd/compose.h"
#include "pbd/search_path.h"
#include "pbd/file_utils.h"
#include "ardour/filesystem_paths.h"
using namespace std;
using namespace ArdourCanvas;
using namespace PBD;
//#define dbg_msg(a) Gtk::MessageDialog (a, "ArdourCanvas::Pixbuf").run();
Pixbuf::Pixbuf (Group* g)
: Item (g)
@ -31,10 +40,48 @@ Pixbuf::Pixbuf (Group* g)
}
void
Pixbuf::render (Rect const & /*area*/, Cairo::RefPtr<Cairo::Context> context) const
Pixbuf::Pixbuf (Group* g, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (g, definition, styles, named_items)
{
Gdk::Cairo::set_source_pixbuf (context, _pixbuf, 0, 0);
std::string imagename = xml_property(definition, "file", styles, "");
if (!imagename.empty())
{
Searchpath spath(ARDOUR::ardour_data_search_path());
std::string dirname = Glib::path_get_dirname (imagename);
std::string filename = Glib::path_get_basename (imagename);
if (!dirname.empty()) {
spath.add_subdirectory_to_paths(dirname);
}
std::string data_file_path;
if (find_file_in_search_path (spath, filename, data_file_path)) {
try {
_pixbuf = Gdk::Pixbuf::create_from_file (data_file_path);
} catch (const Gdk::PixbufError &e) {
cerr << "Caught PixbufError: " << e.what() << endl;
} catch (...) {
cerr << string_compose ("Caught exception while loading icon named %1", imagename) << endmsg;
}
}
}
}
void
Pixbuf::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{
Rect self = item_to_window (Rect (position(), position().translate (Duple (_pixbuf->get_width(), _pixbuf->get_height()))));
boost::optional<Rect> r = self.intersection (area);
if (!r) {
return;
}
Rect draw = r.get ();
context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
Gdk::Cairo::set_source_pixbuf (context, _pixbuf, draw.x0, draw.y0);
context->paint ();
}

View file

@ -38,6 +38,18 @@ Rectangle::Rectangle (Group* parent)
{
}
Rectangle::Rectangle (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (parent, definition, styles, named_items)
, Outline (parent, definition, styles, named_items)
, Fill (parent, definition, styles, named_items)
, _outline_what ((What) (LEFT | RIGHT | TOP | BOTTOM))
{
//_rect.x0 = xml_property(definition, "x", styles, 0.0);
//_rect.y0 = xml_property(definition, "y", styles, 0.0);
_rect.x1 = _rect.x0 + xml_property(definition, "width", styles, 0.0);
_rect.y1 = _rect.y0 + xml_property(definition, "height", styles, 0.0);
}
Rectangle::Rectangle (Group* parent, Rect const & rect)
: Item (parent)
, Outline (parent)

View file

@ -44,6 +44,20 @@ Text::Text (Group* parent)
}
Text::Text (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, Item*>& named_items)
: Item (parent, definition, styles, named_items)
, _color (xml_property(definition, "color", styles, 0x000000ff))
, _font_description ((xml_property(definition, "font", styles, "") == "") ? 0 :
new Pango::FontDescription (xml_property(definition, "font", styles, "")))
, _alignment (xml_text_alignment(definition, styles, Pango::ALIGN_LEFT))
, _width (xml_property(definition, "width", styles, 0.0))
, _height (xml_property(definition, "heigt", styles, 0.0))
, _text (xml_property(definition, "text", styles, ""))
, _need_redraw (false)
, _clamped_width (COORD_MAX)
{
}
Text::~Text ()
{
delete _font_description;

View file

@ -54,7 +54,8 @@ canvas_sources = [
'text.cc',
'types.cc',
'utils.cc',
'wave_view.cc'
'wave_view.cc',
'xml_ui.cc'
]
def options(opt):

242
libs/canvas/xml_ui.cc Normal file
View file

@ -0,0 +1,242 @@
/*
Copyright (C) 2014 Valeriy Kamyshniy
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 "canvas/xml_ui.h"
#include "canvas/group.h"
#include "canvas/rectangle.h"
#include "canvas/pixbuf.h"
#include "canvas/text.h"
//std::ofstream dbg_out("/users/WavesUILog.txt");
namespace ArdourCanvas {
namespace XMLUI {
void
get_styles(const XMLTree& layout, XMLNodeMap &styles)
{
XMLNode* root = layout.root();
if (root != NULL) {
for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
if ( !strcasecmp((*i)->name().c_str(), "style")) {
std::string style_name = ((*i)->property("name") ? (*i)->property("name")->value() : std::string(""));
if (!style_name.empty()) {
styles[style_name] = *i;
}
}
}
}
}
double
xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, double default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
return atof(property.c_str());
}
int32_t
xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, int32_t default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
int32_t value;
int num_of_read_values;
const char* source = property.c_str();
if (source[0] == '#') {
num_of_read_values = sscanf(property.c_str()+1, "%x", &value);
} else {
num_of_read_values = sscanf(property.c_str(), "%d", &value);
}
if(num_of_read_values != 1) {
return default_value;
}
return value;
}
uint32_t
xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, uint32_t default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
uint32_t value;
int num_of_read_values;
const char* source = property.c_str();
if (source[0] == '#') {
num_of_read_values = sscanf(property.c_str()+1, "%x", &value);
} else {
num_of_read_values = sscanf(property.c_str(), "%u", &value);
}
if(num_of_read_values != 1) {
return default_value;
}
return value;
}
bool
xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, bool default_value)
{
std::string property = xml_property(node, prop_name, styles, "");
if (property.empty()) {
return default_value;
}
std::transform(property.begin(), property.end(), property.begin(), ::toupper);
return property == "TRUE";
}
bool
xml_property (const XMLNode &node, const char *prop_name, bool default_value)
{
std::string property = xml_property(node, prop_name, "");
if (property.empty()) {
return default_value;
}
std::transform(property.begin(), property.end(), property.begin(), ::toupper);
return property == "TRUE";
}
std::string
xml_property (const XMLNode &node, const char *prop_name, const XMLNodeMap& styles, const std::string& default_value)
{
if (!node.property (prop_name)) {
std::string style_name = node.property ("style") ? node.property("style")->value() : "";
if (!style_name.empty()) {
XMLNodeMap::const_iterator style = styles.find(style_name);
if (style != styles.end()) {
return xml_property (*style->second, prop_name, styles, std::string(default_value));
}
}
}
else
{
return node.property(prop_name)->value();
}
return default_value;
}
std::string
xml_property (const XMLNode &node, const char *prop_name, const std::string& default_value)
{
return node.property (prop_name) ? node.property(prop_name)->value() : "";
}
std::string
xml_property (const XMLNode& node, const char* prop_name, const XMLNodeMap& styles, const char* default_value)
{
return xml_property (node, prop_name, styles, std::string(default_value));
}
std::string
xml_property (const XMLNode& node, const char* prop_name, const char* default_value)
{
return xml_property (node, prop_name, std::string(default_value));
}
std::string
xml_nodetype(const XMLNode& node)
{
std::string item_type = node.name();
std::transform(item_type.begin(), item_type.end(), item_type.begin(), ::toupper);
return item_type;
}
std::string
xml_id(const XMLNode& node)
{
return xml_property (node, "id", std::string(""));
}
double xml_x (const XMLNode& node, const XMLNodeMap& styles, double default_value)
{
return xml_property (node, "x", styles, default_value);
}
double xml_y (const XMLNode& node, const XMLNodeMap& styles, double default_value)
{
return xml_property (node, "y", styles, default_value);
}
Pango::Alignment xml_text_alignment (const XMLNode& node, const XMLNodeMap& styles, Pango::Alignment default_value)
{
std::string property = xml_property(node, "alignment", styles, "");
std::transform(property.begin(), property.end(), property.begin(), ::toupper);
if (property == "LEFT") {
return Pango::ALIGN_LEFT;
} else if (property == "RIGHT") {
return Pango::ALIGN_RIGHT;
} else if (property == "CENTER") {
return Pango::ALIGN_CENTER;
}
return default_value;
}
ArdourCanvas::Item*
create_item (Group* parent, const XMLNode& definition, const XMLNodeMap& styles, std::map<std::string, ArdourCanvas::Item*>& named_items)
{
ArdourCanvas::Item* child = NULL;
std::string item_type = definition.name();
std::transform(item_type.begin(), item_type.end(), item_type.begin(), ::toupper);
if (item_type == "GROUP") {
child = new Group (parent, definition, styles, named_items);
} else if (item_type == "RECTANGLE") {
child = new Rectangle (parent, definition, styles, named_items);
} else if (item_type == "ICON") {
child = new Pixbuf (parent, definition, styles, named_items);
} else if (item_type == "TEXT") {
child = new Text (parent, definition, styles, named_items);
} else if (item_type == "FROMSTYLE") {
std::string style_name = xml_property (definition, "style", "");
if (!style_name.empty()) {
XMLNodeMap::const_iterator style = styles.find(style_name);
if (style != styles.end()) {
const XMLNodeList& children = (*style->second).children();
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
create_item(parent, **i, styles, named_items);
}
}
}
}
return child;
}
}
}