Back to index

easystroke  0.5.5.1
gesture.cc
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 #include "gesture.h"
00017 #include "prefdb.h"
00018 
00019 void update_triple(RTriple e, float x, float y, Time t) {
00020        e->x = x;
00021        e->y = y;
00022        e->t = t;
00023 }
00024 
00025 RTriple create_triple(float x, float y, Time t) {
00026        RTriple e(new Triple);
00027        update_triple(e, x, y, t);
00028        return e;
00029 }
00030 
00031 Stroke::Stroke(PreStroke &ps, int trigger_, int button_, bool timeout_) : button(button_), timeout(timeout_) {
00032        trigger = (trigger_ == get_default_button()) ? 0 : trigger_;
00033 
00034        if (ps.valid()) {
00035               stroke_t *s = stroke_alloc(ps.size());
00036               for (std::vector<RTriple>::iterator i = ps.begin(); i != ps.end(); ++i)
00037                      stroke_add_point(s, (*i)->x, (*i)->y);
00038               stroke_finish(s);
00039               stroke.reset(s, &stroke_free);
00040        }
00041 }
00042 
00043 int Stroke::compare(RStroke a, RStroke b, double &score) {
00044        score = 0.0;
00045        if (!a || !b)
00046               return -1;
00047        if (!a->timeout != !b->timeout)
00048               return -1;
00049        if (a->button != b->button)
00050               return -1;
00051        if (a->trigger != b->trigger) {
00052               if (a->trigger && b->trigger)
00053                      return -1;
00054               if (a->trigger + b->trigger != get_default_button())
00055                      return -1;
00056        }
00057        if (!a->stroke || !b->stroke) {
00058               if (!a->stroke && !b->stroke) {
00059                      score = 1.0;
00060                      return 1;
00061               }
00062               else
00063                      return -1;
00064        }
00065        double cost = stroke_compare(a->stroke.get(), b->stroke.get(), NULL, NULL);
00066        if (cost >= stroke_infinity)
00067               return -1;
00068        score = MAX(1.0 - 2.5*cost, 0.0);
00069        if (a->timeout)
00070               return score > 0.85;
00071        else
00072               return score > 0.7;
00073 }
00074 
00075 Glib::RefPtr<Gdk::Pixbuf> Stroke::draw(int size, double width, bool inv) const {
00076        if (size != STROKE_SIZE || (width != 2.0 && width != 4.0) || inv)
00077               return draw_(size, width, inv);
00078        int i = width == 2.0;
00079        if (pb[i])
00080               return pb[i];
00081        pb[i] = draw_(size, width);
00082        return pb[i];
00083 }
00084 
00085 Glib::RefPtr<Gdk::Pixbuf> Stroke::pbEmpty;
00086 
00087 Glib::RefPtr<Gdk::Pixbuf> Stroke::drawEmpty(int size) {
00088        if (size != STROKE_SIZE)
00089               return drawEmpty_(size);
00090        if (pbEmpty)
00091               return pbEmpty;
00092        pbEmpty = drawEmpty_(size);
00093        return pbEmpty;
00094 }
00095 
00096 
00097 RStroke Stroke::trefoil() {
00098        PreStroke s;
00099        const int n = 40;
00100        for (int i = 0; i<=n; i++) {
00101               double phi = M_PI*(-4.0*i/n)-2.7;
00102               double r = exp(1.0 + sin(6.0*M_PI*i/n)) + 2.0;
00103               s.add(create_triple(r*cos(phi), r*sin(phi), i));
00104        }
00105        return Stroke::create(s, 0, 0, false);
00106 }