]> git.tdb.fi Git - libs/gltk.git/commitdiff
Refactor filling from Part to Alignment
authorMikko Rasa <tdb@tdb.fi>
Fri, 14 Dec 2007 16:20:48 +0000 (16:20 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 14 Dec 2007 16:20:48 +0000 (16:20 +0000)
Implement VSlider
Make [HV]Slider loabable from datafiles

12 files changed:
source/entry.cpp
source/geometry.cpp
source/geometry.h
source/hslider.cpp
source/hslider.h
source/panel.cpp
source/part.cpp
source/part.h
source/slider.cpp
source/slider.h
source/vslider.cpp [new file with mode: 0644]
source/vslider.h [new file with mode: 0644]

index eed2c39a942ced2e7299a6f357be9142cd6b4c15..7e503b3dbc0e960b8c04397dc27b0ff14e640436 100644 (file)
@@ -81,21 +81,14 @@ void Entry::render_special(const Part &part) const
                const GL::Font *const font=style->get_font();
                const float font_size=font->get_default_size();
 
-               const Geometry &pgeom=part.get_geometry();
-               unsigned gw=pgeom.w;
-               unsigned gh=(part.get_fill_y() ? geom.h : pgeom.h);
-
-               Geometry rgeom;
+               Geometry rgeom=part.get_geometry();
+               rgeom.x=static_cast<unsigned>(font->get_string_width(text.substr(0, edit_pos))*font_size);
                rgeom.w=static_cast<unsigned>(font->get_string_width(text)*font_size);
-               rgeom.h=(part.get_fill_y() ? geom.h : pgeom.h);
                part.get_alignment().apply(rgeom, geom, part.get_margin());
-               rgeom.x+=static_cast<unsigned>(font->get_string_width(text.substr(0, edit_pos))*font_size);
 
                GL::push_matrix();
                GL::translate(rgeom.x, rgeom.y, 0);
-
-               part.get_graphic(state)->render(gw, gh);
-
+               part.get_graphic(state)->render(part.get_geometry().w, rgeom.h);
                GL::pop_matrix();
        }
 }
index 81efcd05bad2e69d22325eb3e7df851f638d3644..126a0fc7aa48b731d72819dc70ec302575062d37 100644 (file)
@@ -36,12 +36,22 @@ Sides::Loader::Loader(Sides &s):
 
 void Alignment::apply(Geometry &geom, const Geometry &parent) const
 {
+       if(parent.w>geom.w)
+               geom.w+=static_cast<unsigned>((parent.w-geom.w)*w);
+       if(parent.h>geom.h)
+               geom.h+=static_cast<unsigned>((parent.h-geom.h)*h);
+
        geom.x+=static_cast<int>((parent.w-geom.w)*x);
        geom.y+=static_cast<int>((parent.h-geom.h)*y);
 }
 
 void Alignment::apply(Geometry &geom, const Geometry &parent, const Sides &margin) const
 {
+       if(parent.w>geom.w)
+               geom.w+=static_cast<unsigned>((parent.w-geom.w)*w);
+       if(parent.h>geom.h)
+               geom.h+=static_cast<unsigned>((parent.h-geom.h)*h);
+
        geom.x+=static_cast<int>(margin.left+(parent.w-margin.left-margin.right-geom.w)*x);
        geom.y+=static_cast<int>(margin.bottom+(parent.h-margin.bottom-margin.top-geom.h)*y);
 }
index 6559414dd0497ae5cdd8a8e8a0136ed6af062876..6fa8e7f1287ffd1f39942979f1f046889bc97ecc 100644 (file)
@@ -56,9 +56,9 @@ Performs alignment of nested geometries, such as widgets and their parts.
 struct Alignment
 {
        float x, y;
+       float w, h;
 
-       Alignment(): x(0), y(0) { }
-       Alignment(float x_, float y_): x(x_), y(y_) { }
+       Alignment(): x(0), y(0), w(1), h(1) { }
        void apply(Geometry &, const Geometry &) const;
        void apply(Geometry &, const Geometry &, const Sides &) const;
 };
index d764797971029c08da73015f391e6ab6a9867795..3b68dacfa1b142eafe31851ed6f8dfc6fcd5d64e 100644 (file)
@@ -59,13 +59,15 @@ void HSlider::render_special(const Part &part) const
 {
        if(part.get_name()=="slider")
        {
-               const Geometry &pgeom=part.get_geometry();
-               unsigned gw=pgeom.w;
-               unsigned gh=(part.get_fill_y() ? geom.h : pgeom.h);
+               Alignment align=part.get_alignment();
+               align.x=(value-min)/(max-min);
+
+               Geometry pgeom=part.get_geometry();
+               align.apply(pgeom, geom, part.get_margin());
+
                GL::push_matrix();
-               GL::translate((geom.w-gw)*(value-min)/(max-min), (geom.h-gh)*(part.get_alignment().y+1)/2, 0);
-               const Graphic *graphic=part.get_graphic(state);
-               graphic->render(gw, gh);
+               GL::translate(pgeom.x, pgeom.y, 0);
+               part.get_graphic(state)->render(pgeom.w, pgeom.h);
                GL::pop_matrix();
        }
 }
index 310cc4e3c073dcdffc3021405f5f228c1c10dd13..8f0be9f810b2343d72365f30215138d12a0c1dd8 100644 (file)
@@ -15,7 +15,7 @@ namespace GLtk {
 
 /**
 Horizontal slider widget.  A special part named "slider" will be positioned at
-the current value of the widget.  The fill_x attribute is ignored.
+the current value of the widget.
 */
 class HSlider: public Slider
 {
index bfd0aa8eca7f8f33e5d0ab0ab9688ac1431de911..91562cea2b5d7df9a108128d8e31e2927e83ae1a 100644 (file)
@@ -8,9 +8,11 @@ Distributed under the LGPL
 #include <msp/core/refptr.h>
 #include "button.h"
 #include "entry.h"
+#include "hslider.h"
 #include "label.h"
 #include "panel.h"
 #include "part.h"
+#include "vslider.h"
 
 using namespace std;
 
@@ -181,8 +183,10 @@ Panel::Loader::Loader(Panel &p, map<string, Widget *> &m):
 {
        add("button", &Loader::child<Button>);
        add("entry",  &Loader::child<Entry>);
+       add("hslider", &Loader::child<HSlider>);
        add("label",  &Loader::child<Label>);
        add("panel",  &Loader::panel);
+       add("vslider", &Loader::child<VSlider>);
 }
 
 template<typename T>
index a92e7208ca6883015cd978eb5c9218700538faec..ec36de9774aba7def07af052677af8d843be2568 100644 (file)
@@ -16,9 +16,7 @@ namespace Msp {
 namespace GLtk {
 
 Part::Part(const string &n):
-       name(n),
-       fill_x(true),
-       fill_y(true)
+       name(n)
 {
        for(unsigned i=0; i<N_STATES_; ++i)
                graphic[i]=0;
@@ -38,10 +36,6 @@ void Part::render(const Geometry &parent, State state) const
                return;
 
        Geometry rgeom=geom;
-       if(fill_x)
-               rgeom.w=parent.w-margin.left-margin.right;
-       if(fill_y)
-               rgeom.h=parent.h-margin.bottom-margin.top;
        align.apply(rgeom, parent, margin);
        GL::translate(rgeom.x, rgeom.y, 0);
        graphic[state]->render(rgeom.w, rgeom.h);
@@ -84,10 +78,10 @@ void Part::Loader::align(float x, float y)
        part.align.y=y;
 }
 
-void Part::Loader::fill(bool x, bool y)
+void Part::Loader::fill(float w, float h)
 {
-       part.fill_x=x;
-       part.fill_y=y;
+       part.align.w=w;
+       part.align.h=h;
 }
 
 void Part::Loader::margin()
index a94f29db87421d5fdff157cbae4462f89884f1d6..edc8f77a5b84230d883d277f5bf29c2e77fe6ef9 100644 (file)
@@ -39,7 +39,7 @@ public:
        private:
                void graphic(State, const std::string &);
                void align(float, float);
-               void fill(bool, bool);
+               void fill(float, float);
                void margin();
        };
 
@@ -49,8 +49,6 @@ private:
        Geometry geom;
        Sides margin;
        Alignment align;
-       bool fill_x;
-       bool fill_y;
 
 public:
        Part(const std::string &);
@@ -59,8 +57,6 @@ public:
        const Geometry &get_geometry() const { return geom; }
        const Sides &get_margin() const { return margin; }
        const Alignment &get_alignment() const { return align; }
-       bool get_fill_x() const { return fill_x; }
-       bool get_fill_y() const { return fill_y; }
        void render(const Geometry &, State) const;
 };
 typedef std::list<Part> PartSeq;
index 52a4b4d3b97ccf11d4209b767619018aec3d8674..0b1d8b066ee2e992644d9cc0254dc672a6ac8db5 100644 (file)
@@ -49,5 +49,19 @@ void Slider::set_step(double s)
        set_value(value);
 }
 
+
+Slider::Loader::Loader(Slider &s):
+       Widget::Loader(s)
+{
+       add("range", &Slider::min, &Slider::max);
+       add("step",  &Slider::step);
+       add("value", &Slider::value);
+}
+
+Slider &Slider::Loader::get_object() const
+{
+       return static_cast<Slider &>(wdg);
+}
+
 } // namespace GLtk
 } // namespace Msp
index 8eb373667405dbb17cc25bb22fc5f9167b985eb9..e6cbe0d0a37706e02948e1e33ff7e7f743d840b7 100644 (file)
@@ -16,11 +16,19 @@ namespace GLtk {
 
 /**
 Sliders are used to adjust numeric values visually.  This class provides the
-common interface for sliders - see classes HSlider and VSlider (NYI) for
-concrete variations.
+common interface for sliders - see classes HSlider and VSlider for concrete
+variations.
 */
 class Slider: public Widget
 {
+public:
+       class Loader: public Widget::Loader
+       {
+       public:
+               Loader(Slider &);
+               Slider &get_object() const;
+       };
+
 protected:
        double min, max;
        double value;
diff --git a/source/vslider.cpp b/source/vslider.cpp
new file mode 100644 (file)
index 0000000..397713b
--- /dev/null
@@ -0,0 +1,86 @@
+/* $Id$
+
+This file is part of libmspgltk
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/gl/matrix.h>
+#include <msp/gl/transform.h>
+#include "graphic.h"
+#include "part.h"
+#include "style.h"
+#include "vslider.h"
+
+namespace Msp {
+namespace GLtk {
+
+VSlider::VSlider(const Resources &r):
+       Slider(r),
+       dragging(false)
+{
+       update_style();
+}
+
+void VSlider::button_press(int x, int y, unsigned btn)
+{
+       if(geom.is_inside(x, y))
+       {
+               int sh=get_slider_height();
+               int sy=geom.y+static_cast<int>((geom.h-sh)*(value-min)/(max-min));
+               if(btn==1 && y>=sy && y<sy+sh)
+               {
+                       dragging=true;
+                       state=ACTIVE;
+                       drag_start_y=y;
+                       drag_start_value=value;
+               }
+       }
+}
+
+void VSlider::button_release(int, int, unsigned btn)
+{
+       if(btn==1)
+       {
+               dragging=false;
+               state=NORMAL;
+       }
+}
+
+void VSlider::pointer_motion(int, int y)
+{
+       if(dragging)
+       {
+               set_value(drag_start_value+(y-drag_start_y)*(max-min)/(geom.h-get_slider_height()));
+       }
+}
+
+void VSlider::render_special(const Part &part) const
+{
+       if(part.get_name()=="slider")
+       {
+               Alignment align=part.get_alignment();
+               align.y=(value-min)/(max-min);
+
+               Geometry pgeom=part.get_geometry();
+               align.apply(pgeom, geom, part.get_margin());
+
+               GL::push_matrix();
+               GL::translate(pgeom.x, pgeom.y, 0);
+               part.get_graphic(state)->render(pgeom.w, pgeom.h);
+               GL::pop_matrix();
+       }
+}
+
+unsigned VSlider::get_slider_height() const
+{
+       for(PartSeq::const_iterator i=style->get_parts().begin(); i!=style->get_parts().end(); ++i)
+               if(i->get_name()=="slider")
+                       return i->get_geometry().h;
+
+       return 0;
+}
+
+} // namespace GLtk
+} // namespace Msp
+
diff --git a/source/vslider.h b/source/vslider.h
new file mode 100644 (file)
index 0000000..2696051
--- /dev/null
@@ -0,0 +1,37 @@
+/* $Id$
+
+This file is part of libmspgltk
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GLTK_VSLIDER_H_
+#define MSP_GLTK_VSLIDER_H_
+
+#include "slider.h"
+
+namespace Msp {
+namespace GLtk {
+
+class VSlider: public Slider
+{
+private:
+       bool dragging;
+       int drag_start_y;
+       double drag_start_value;
+
+public:
+       VSlider(const Resources &);
+       virtual void button_press(int, int, unsigned);
+       virtual void button_release(int, int, unsigned);
+       virtual void pointer_motion(int, int);
+private:
+       virtual const char *get_class() const { return "vslider"; }
+       virtual void render_special(const Part &) const;
+       unsigned get_slider_height() const;
+};
+
+} // namespace GLtk
+} // namespace Msp
+
+#endif