X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fslider.cpp;h=8ff342d56a81646aa6fe1786c58fcaf39a816068;hb=ab9fd8084f8bf8770d8d968354550cb2df99192f;hp=5034b2475d8c46f20e4e09f2fe626c69c196d19a;hpb=cecc9edd95fea4728325575406deb866db8227ee;p=libs%2Fgltk.git diff --git a/source/slider.cpp b/source/slider.cpp index 5034b24..8ff342d 100644 --- a/source/slider.cpp +++ b/source/slider.cpp @@ -1,9 +1,15 @@ +#include +#include +#include "graphic.h" +#include "part.h" #include "slider.h" +#include "style.h" namespace Msp { namespace GLtk { -Slider::Slider(): +Slider::Slider(Direction d): + dir(d), min(0), max(1), value(0), @@ -11,7 +17,8 @@ Slider::Slider(): dragging(false), drag_area_size(0), drag_area_offset(0), - slider_size(1) + slider_size(1), + total_margin(0) { } void Slider::set_value(double v) @@ -48,8 +55,49 @@ void Slider::set_step(double s) set_value(value); } -void Slider::click(int p) +void Slider::autosize_special(const Part &part, Geometry &ageom) const { + if(part.get_name()=="slider") + { + const Sides &margin = part.get_margin(); + const Geometry &pgeom = part.get_geometry(); + ageom.w = std::max(ageom.w, pgeom.w*(dir==HORIZONTAL)/2+margin.left+margin.right); + ageom.h = std::max(ageom.h, pgeom.h*(dir==VERTICAL)/2+margin.top+margin.bottom); + } +} + +void Slider::rebuild_special(const Part &part) +{ + if(part.get_name()=="slider") + { + const Graphic *graphic = part.get_graphic(state); + if(!graphic || !graphic->get_texture()) + return; + + float pos_fraction = ((max>min) ? (value-min)/(max-min) : 0); + + Alignment align = part.get_alignment(); + if(dir==HORIZONTAL) + align.x = pos_fraction; + else + align.y = pos_fraction; + + Geometry rgeom = part.get_geometry(); + align.apply(rgeom, geom, part.get_margin()); + + GL::MeshBuilder bld(part_cache.create_mesh(part, *graphic->get_texture())); + bld.matrix() *= GL::Matrix::translation(rgeom.x, rgeom.y, 0); + graphic->build(rgeom.w, rgeom.h, bld); + } +} + +void Slider::button_press(int x, int y, unsigned btn) +{ + if(btn!=1) + return; + + int p = (dir==HORIZONTAL ? x : y); + p -= drag_area_offset; if(p<0 || p>=static_cast(drag_area_size)) return; @@ -60,27 +108,61 @@ void Slider::click(int p) else if(p>=static_cast(sp+slider_size)) set_value(value+step*10); else - start_drag(drag_area_offset+p); + { + dragging = true; + drag_start_pos = p; + drag_start_value = value; + set_state(ACTIVE); + } } -void Slider::start_drag(int p) +void Slider::button_release(int, int, unsigned btn) { - dragging = true; - drag_start_pos = p; - drag_start_value = value; - set_state(ACTIVE); + if(btn==1 && dragging) + { + dragging = false; + clear_state(ACTIVE); + } } -void Slider::drag(int p) +void Slider::pointer_motion(int x, int y) { - if(max>min) + if(dragging && max>min) + { + int p = (dir==HORIZONTAL ? x : y); set_value(drag_start_value+(p-drag_start_pos)*(max-min)/(drag_area_size-slider_size)); + } } -void Slider::end_drag() +void Slider::on_size_change() { - dragging = false; - clear_state(ACTIVE); + drag_area_size = (dir==HORIZONTAL ? geom.w : geom.h)-total_margin; +} + +void Slider::on_style_change() +{ + if(!style) + return; + + if(const Part *slider_part = style->get_part("slider")) + { + const Geometry &pgeom = slider_part->get_geometry(); + const Sides &margin = slider_part->get_margin(); + if(dir==HORIZONTAL) + { + slider_size = pgeom.w; + drag_area_offset = margin.left; + total_margin = margin.left+margin.right; + } + else + { + slider_size = pgeom.h; + drag_area_offset = margin.bottom; + total_margin = margin.bottom+margin.top; + } + } + + on_size_change(); }