Back to index

easystroke  0.5.5.1
gesture.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00011  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
00013  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00014  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 #ifndef __GESTURE_H__
00017 #define __GESTURE_H__
00018 
00019 #include "stroke.h"
00020 #include <gdkmm/pixbuf.h>
00021 #include <vector>
00022 #include <boost/shared_ptr.hpp>
00023 #include <boost/serialization/access.hpp>
00024 #include <boost/serialization/version.hpp>
00025 #include <boost/serialization/split_member.hpp>
00026 
00027 #include <X11/X.h> // Time
00028 
00029 #define STROKE_SIZE 64
00030 
00031 class Stroke;
00032 class PreStroke;
00033 
00034 typedef boost::shared_ptr<Stroke> RStroke;
00035 typedef boost::shared_ptr<PreStroke> RPreStroke;
00036 
00037 int get_default_button();
00038 
00039 struct Triple {
00040        float x;
00041        float y;
00042        Time t;
00043 };
00044 typedef boost::shared_ptr<Triple> RTriple;
00045 void update_triple(RTriple e, float x, float y, Time t);
00046 RTriple create_triple(float x, float y, Time t);
00047 
00048 class PreStroke;
00049 class Stroke {
00050        friend class PreStroke;
00051        friend class boost::serialization::access;
00052        friend class Stats;
00053 public:
00054        struct Point {
00055               double x;
00056               double y;
00057               Point operator+(const Point &p) {
00058                      Point sum = { x + p.x, y + p.y };
00059                      return sum;
00060               }
00061               Point operator-(const Point &p) {
00062                      Point sum = { x - p.x, y - p.y };
00063                      return sum;
00064               }
00065               Point operator*(const double a) {
00066                      Point product = { x * a, y * a };
00067                      return product;
00068               }
00069               template<class Archive> void serialize(Archive & ar, const unsigned int version) {
00070                      ar & x; ar & y;
00071                      if (version == 0) {
00072                             double time;
00073                             ar & time;
00074                      }
00075               }
00076        };
00077 
00078 private:
00079        Stroke(PreStroke &s, int trigger_, int button_, bool timeout_);
00080 
00081        Glib::RefPtr<Gdk::Pixbuf> draw_(int size, double width = 2.0, bool inv = false) const;
00082        mutable Glib::RefPtr<Gdk::Pixbuf> pb[2];
00083 
00084        static Glib::RefPtr<Gdk::Pixbuf> drawEmpty_(int);
00085        static Glib::RefPtr<Gdk::Pixbuf> pbEmpty;
00086 
00087        BOOST_SERIALIZATION_SPLIT_MEMBER()
00088        template<class Archive> void save(Archive & ar, const unsigned int version) const {
00089               std::vector<Point> ps;
00090               for (unsigned int i = 0; i < size(); i++)
00091                      ps.push_back(points(i));
00092               ar & ps;
00093               ar & button;
00094               ar & trigger;
00095               ar & timeout;
00096        }
00097        template<class Archive> void load(Archive & ar, const unsigned int version) {
00098               std::vector<Point> ps;
00099               ar & ps;
00100               if (ps.size()) {
00101                      stroke_t *s = stroke_alloc(ps.size());
00102                      for (std::vector<Point>::iterator i = ps.begin(); i != ps.end(); ++i)
00103                             stroke_add_point(s, i->x, i->y);
00104                      stroke_finish(s);
00105                      stroke.reset(s, &stroke_free);
00106               }
00107               if (version == 0) return;
00108               ar & button;
00109               if (version >= 2)
00110                      ar & trigger;
00111               if (version < 4 && (!button || trigger == get_default_button()))
00112                      trigger = 0;
00113               if (version < 3)
00114                      return;
00115               ar & timeout;
00116        }
00117 
00118 public:
00119        int trigger;
00120        int button;
00121        bool timeout;
00122        boost::shared_ptr<stroke_t> stroke;
00123 
00124        Stroke() : trigger(0), button(0), timeout(false) {}
00125        static RStroke create(PreStroke &s, int trigger_, int button_, bool timeout_) {
00126               return RStroke(new Stroke(s, trigger_, button_, timeout_));
00127        }
00128         Glib::RefPtr<Gdk::Pixbuf> draw(int size, double width = 2.0, bool inv = false) const;
00129        void draw(Cairo::RefPtr<Cairo::Surface> surface, int x, int y, int w, int h, double width = 2.0, bool inv = false) const;
00130        void draw_svg(std::string filename) const;
00131        bool show_icon();
00132 
00133        static RStroke trefoil();
00134        static int compare(RStroke, RStroke, double &);
00135        static Glib::RefPtr<Gdk::Pixbuf> drawEmpty(int);
00136        static Glib::RefPtr<Gdk::Pixbuf> drawDebug(RStroke, RStroke, int);
00137 
00138        unsigned int size() const { return stroke ? stroke_get_size(stroke.get()) : 0; }
00139        bool trivial() const { return size() == 0 && button == 0; }
00140        Point points(int n) const { Point p; stroke_get_point(stroke.get(), n, &p.x, &p.y); return p; }
00141        double time(int n) const { return stroke_get_time(stroke.get(), n); }
00142        bool is_timeout() const { return timeout; }
00143 };
00144 BOOST_CLASS_VERSION(Stroke, 4)
00145 BOOST_CLASS_VERSION(Stroke::Point, 1)
00146 
00147 class PreStroke : public std::vector<RTriple> {
00148 public:
00149        static RPreStroke create() { return RPreStroke(new PreStroke()); }
00150        void add(RTriple p) { push_back(p); }
00151        bool valid() const { return size() > 2; }
00152 };
00153 #endif