Author: mordante
Date: Thu Jul 17 17:27:22 2008
New Revision: 28060

URL: http://svn.gna.org/viewcvs/wesnoth?rev=28060&view=rev
Log:
Rewrote the scrollbar positioner scale code and allow a maximum for the 
positioner. Also added some commented out debug code, I've been adding this
code too often ;-).

Modified:
    trunk/src/gui/widgets/scrollbar.cpp
    trunk/src/gui/widgets/scrollbar.hpp
    trunk/src/gui/widgets/settings.cpp
    trunk/src/gui/widgets/settings.hpp
    trunk/src/gui/widgets/vertical_scrollbar.cpp
    trunk/src/gui/widgets/vertical_scrollbar.hpp

Modified: trunk/src/gui/widgets/scrollbar.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/scrollbar.cpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/scrollbar.cpp (original)
+++ trunk/src/gui/widgets/scrollbar.cpp Thu Jul 17 17:27:22 2008
@@ -224,15 +224,16 @@
        }
 
        // Get the available size for the slider to move.
-       int available_length = 
-               get_length() - offset_before() - minimum_positioner_length() - 
offset_after();
+       const int available_length = 
+               get_length() - offset_before() - offset_after();
 
        assert(available_length > 0);
 
        // All visible.
        if(item_count_ <= visible_items_) {
                positioner_offset_ = offset_before();
-               positioner_length_ = available_length + 
minimum_positioner_length();
+               positioner_length_ = available_length;
+               recalculate_positioner();
                item_position_ = 0;
                update_canvas();
                return;
@@ -241,36 +242,48 @@
        assert(step_size_);
        assert(visible_items_);
 
-       const unsigned steps = (item_count_ + step_size_ - 1) / step_size_;
-
-       if(static_cast<int>(steps) < available_length) {
-
-               // We can show them all.
-               available_length += minimum_positioner_length();
-
-               pixels_per_step_ = available_length / static_cast<float>(steps);
-
-               positioner_length_ = static_cast<unsigned>(pixels_per_step_ * 
visible_items_) + available_length % steps;
-
-       } else {
-
-               // We'll skip some.
-               WRN_G << "The scrollbar is too small for the"
-                       " number of items, movement might seem jerky.\n";
-               
-               available_length += minimum_positioner_length();
-
-               pixels_per_step_ = available_length / static_cast<float>(steps);
-
-               // When a listbox is in 'pixel mode' (not fixed row height) the
-               // positioner might still be rather big so scale it 
proportional but
-               // respect the minimum.
-               positioner_length_ = std::max(
-                       available_length * visible_items_ / item_count_, 
-                       minimum_positioner_length());
-       }
+       const unsigned steps = (item_count_ - visible_items_ + step_size_ - 1) 
/ step_size_;
+
+       positioner_length_ = available_length * visible_items_ / item_count_;
+       recalculate_positioner();
+
+       // Make sure we can also show the last step, so add one more step.
+       pixels_per_step_ = 
+               (available_length - positioner_length_) 
+               / static_cast<float>(steps + 1);
 
        set_item_position(item_position_);
+#if 0
+       std::cerr << "Scrollbar recalculate overview:\n"
+               << "item_count_ " << item_count_
+               << " visible_items_ " << visible_items_
+               << " step_size_ " << step_size_
+               << " steps " << steps
+               << "\n"
+               << "minimum_positioner_length() " << 
minimum_positioner_length() 
+               << " maximum_positioner_length() " << 
maximum_positioner_length()
+               << "\n"
+               << " positioner_length_ " << positioner_length_
+               << " positioner_offset_ " << positioner_offset_
+               << "\n"
+               << "available_length " << available_length
+               << " pixels_per_step_ " << pixels_per_step_
+               << ".\n\n";
+#endif
+}
+
+void tscrollbar_::recalculate_positioner()
+{
+       const unsigned minimum = minimum_positioner_length();
+       const unsigned maximum = maximum_positioner_length();
+
+       if(minimum == maximum) {
+               positioner_length_ = maximum;
+       } else if(maximum != 0 && positioner_length_ > maximum) {
+               positioner_length_ = maximum;
+       } else if(positioner_length_ < minimum) {
+               positioner_length_ = minimum;
+       }
 }
 
 void tscrollbar_::update_canvas() {
@@ -284,19 +297,26 @@
 
 void tscrollbar_::move_positioner(const int distance)
 {
-  if(distance < 0 && -distance > static_cast<int>(positioner_offset_)) {
+       if(distance < 0 && -distance > static_cast<int>(positioner_offset_)) {
                positioner_offset_ = 0;
        } else {
                positioner_offset_ += distance;
        }
-       const unsigned length = get_length() - offset_before() - offset_after();
-
-       if(positioner_offset_ + positioner_length_ > length) {
-               positioner_offset_ = length - positioner_length_;
-       }
-
-       const unsigned position =
+
+       const unsigned length = get_length() - offset_before() - offset_after() 
- positioner_length_;
+
+       if(positioner_offset_ > length) {
+               positioner_offset_ = length;
+       }
+
+       unsigned position =
                static_cast<unsigned>(positioner_offset_ / pixels_per_step_); 
+
+       // Note due to floating point rounding the position might be outside the
+       // available positions so set it back.
+       if(position > item_count_ - visible_items_) {
+               position = item_count_ - visible_items_;
+       }
 
        if(position != item_position_) {
                item_position_ = position; 
@@ -305,7 +325,22 @@
                        callback_positioner_move_(this);
                }
        }
-
+#if 0
+       std::cerr << "Scrollbar move overview:\n"
+               << "item_count_ " << item_count_
+               << " visible_items_ " << visible_items_
+               << " step_size_ " << step_size_
+               << "\n"
+               << "minimum_positioner_length() " << 
minimum_positioner_length() 
+               << " maximum_positioner_length() " << 
maximum_positioner_length()
+               << "\n"
+               << " positioner_length_ " << positioner_length_
+               << " positioner_offset_ " << positioner_offset_
+               << "\n"
+               << " pixels_per_step_ " << pixels_per_step_
+               << " item_position_ " << item_position_
+               << ".\n\n";
+#endif
        update_canvas();
 }
 

Modified: trunk/src/gui/widgets/scrollbar.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/scrollbar.hpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/scrollbar.hpp (original)
+++ trunk/src/gui/widgets/scrollbar.hpp Thu Jul 17 17:27:22 2008
@@ -229,6 +229,9 @@
        /** The minimum length of the positioner. */
        virtual unsigned minimum_positioner_length() const = 0;
 
+       /** The maximum length of the positioner. */
+       virtual unsigned maximum_positioner_length() const = 0;
+
        /**
         * The number of pixels we can't use since they're used for borders.
         *
@@ -288,6 +291,13 @@
         */
        void recalculate();
 
+       /**
+        * Updates the positioner.
+        *
+        * This is a helper for recalculate().
+        */
+       void recalculate_positioner();
+
        /** After a recalculation the canvasses also need to be updated. */
        void update_canvas();
 

Modified: trunk/src/gui/widgets/settings.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/settings.cpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/settings.cpp (original)
+++ trunk/src/gui/widgets/settings.cpp Thu Jul 17 17:27:22 2008
@@ -857,6 +857,8 @@
        tresolution_definition_(cfg),
        minimum_positioner_length(
                
lexical_cast_default<unsigned>(cfg["minimum_positioner_length"])),
+       maximum_positioner_length(
+               
lexical_cast_default<unsigned>(cfg["maximum_positioner_length"])),
        top_offset(lexical_cast_default<unsigned>(cfg["top_offset"])),
        bottom_offset(lexical_cast_default<unsigned>(cfg["bottom_offset"]))
 {
@@ -875,11 +877,13 @@
  *                                     The minumum size the positioner is
  *                                     allowed to be. The engine needs to know
  *                                     this in order to calculate the best size
- *                                     for the positioner. There is no maximum
- *                                     size for the positioner it should be
- *                                     scaleable for the entire size. (Of 
course
- *                                     it is possible to file a FR if this is
- *                                     really wanted.)
+ *                                     for the positioner.  
+ *     maximum_positioner_length (unsigned = 0)
+ *                                     The maximum size the positioner is
+ *                                     allowed to be. If minimum and maximum 
are
+ *                                     the same value the positioner is fixed
+ *                                     size. If the maximum is 0 (and the
+ *                                     minimum not) there's no maximum.
  *     top_offset (unsigned = 0)       The number of pixels at the top which
  *                                     can't be used by the positioner.
  *     bottom_offset (unsigned = 0)    The number of pixels at the bottom which

Modified: trunk/src/gui/widgets/settings.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/settings.hpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/settings.hpp (original)
+++ trunk/src/gui/widgets/settings.hpp Thu Jul 17 17:27:22 2008
@@ -238,6 +238,7 @@
                tresolution(const config& cfg);
 
                unsigned minimum_positioner_length;
+               unsigned maximum_positioner_length;
 
                unsigned top_offset;
                unsigned bottom_offset;

Modified: trunk/src/gui/widgets/vertical_scrollbar.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/vertical_scrollbar.cpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/vertical_scrollbar.cpp (original)
+++ trunk/src/gui/widgets/vertical_scrollbar.cpp Thu Jul 17 17:27:22 2008
@@ -50,6 +50,14 @@
        return conf->minimum_positioner_length; 
 }
 
+unsigned tvertical_scrollbar::maximum_positioner_length() const
+{ 
+       const tvertical_scrollbar_definition::tresolution* conf = 
+               dynamic_cast<const 
tvertical_scrollbar_definition::tresolution*>(config());
+       assert(conf); 
+       return conf->maximum_positioner_length; 
+}
+
 unsigned tvertical_scrollbar::offset_before() const
 { 
        const tvertical_scrollbar_definition::tresolution* conf = 

Modified: trunk/src/gui/widgets/vertical_scrollbar.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/vertical_scrollbar.hpp?rev=28060&r1=28059&r2=28060&view=diff
==============================================================================
--- trunk/src/gui/widgets/vertical_scrollbar.hpp (original)
+++ trunk/src/gui/widgets/vertical_scrollbar.hpp Thu Jul 17 17:27:22 2008
@@ -38,6 +38,9 @@
        unsigned minimum_positioner_length() const;
 
        /** Inherited from tscrollbar. */
+       unsigned maximum_positioner_length() const;
+
+       /** Inherited from tscrollbar. */
        unsigned offset_before() const;
 
        /** Inherited from tscrollbar. */


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to