[haiku-commits] BRANCH HaikuPM-github.package-management [b53a2e6] src/kits/interface headers/private/interface src/servers/package headers/os/interface

  • From: HaikuPM-github.package-management <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 Sep 2013 05:00:35 +0200 (CEST)

added 6 changesets to branch 'refs/remotes/HaikuPM-github/package-management'
old head: 38c62dfb8b5acffe9373b19e087d037d38a281a5
new head: b53a2e6af53a5f375e63a50c4a021bb8967cb2d7
overview: https://github.com/haiku/HaikuPM/compare/38c62df...b53a2e6

----------------------------------------------------------------------------

406ad5b: BString::SetToFormat(): Add printf format function attribute

b1c3379: _user_debug_output(): Fix for long strings
  
  The wrong length was passed to debug_puts().

4a8da96: BLayoutUtils: Add GetLayoutTreeDump()
  
  Returns a debug output string listing the basic layout properties of
  the view/item hierarchy.

5c56812: BControlLook::ComposeSpacing(): Avoid non-integers

88f12ad: Add private BViewPort class
  
  * It simplifies putting regular layout-aware views or layout items into
    a BScrollView.
  * Not quite complete yet: Height-for-width support is missing, but that
    also requires fixing BScrollView in this respect. Scroll bar auto-hide
    support would be nice as well.

b53a2e6: package daemon: ProblemWindow: Use a scroll view

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

10 files changed, 521 insertions(+), 13 deletions(-)
headers/os/interface/LayoutUtils.h    |  18 +-
headers/os/support/String.h           |   3 +-
headers/private/interface/ViewPort.h  |  53 ++++++
src/kits/interface/ControlLook.cpp    |   6 +-
src/kits/interface/Jamfile            |   1 +
src/kits/interface/LayoutUtils.cpp    | 115 ++++++++++-
src/kits/interface/ViewPort.cpp       | 306 ++++++++++++++++++++++++++++++
src/servers/package/Jamfile           |   2 +-
src/servers/package/ProblemWindow.cpp |  22 ++-
src/system/kernel/debug/debug.cpp     |   8 +-

############################################################################

Commit:      406ad5becebc1761f0858fbd0af64f0be8870ec0
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:43:05 2013 UTC

BString::SetToFormat(): Add printf format function attribute

----------------------------------------------------------------------------

diff --git a/headers/os/support/String.h b/headers/os/support/String.h
index 4ce0d13..e33fbc0 100644
--- a/headers/os/support/String.h
+++ b/headers/os/support/String.h
@@ -55,7 +55,8 @@ public:
                        BString&                SetToChars(const BString& 
string, int32 charCount);
                        BString&                AdoptChars(BString& from, int32 
charCount);
 
-                       BString&                SetToFormat(const char* format, 
...);
+                       BString&                SetToFormat(const char* format, 
...)
+                                                               
__attribute__((__format__(__printf__, 2, 3)));
                        BString&                SetToFormatVarArgs(const char* 
format,
                                                                va_list args);
 

############################################################################

Commit:      b1c3379c7e17a5368f3ce6642e3e995143779481
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:43:47 2013 UTC

_user_debug_output(): Fix for long strings

The wrong length was passed to debug_puts().

----------------------------------------------------------------------------

diff --git a/src/system/kernel/debug/debug.cpp 
b/src/system/kernel/debug/debug.cpp
index caa90d1..15adaba 100644
--- a/src/system/kernel/debug/debug.cpp
+++ b/src/system/kernel/debug/debug.cpp
@@ -2268,13 +2268,15 @@ _user_debug_output(const char* userString)
 
        char string[512];
        int32 length;
+       int32 toWrite;
        do {
                length = user_strlcpy(string, userString, sizeof(string));
                if (length <= 0)
                        break;
-               debug_puts(string, length);
-               userString += sizeof(string) - 1;
-       } while (length >= (ssize_t)sizeof(string));
+               toWrite = std::min(length, (int32)sizeof(string) - 1);
+               debug_puts(string, toWrite);
+               userString += toWrite;
+       } while (length > toWrite);
 }
 
 

############################################################################

Commit:      4a8da96088a5aa35d7377c97746f6151ff0e6457
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:46:36 2013 UTC

BLayoutUtils: Add GetLayoutTreeDump()

Returns a debug output string listing the basic layout properties of
the view/item hierarchy.

----------------------------------------------------------------------------

diff --git a/headers/os/interface/LayoutUtils.h 
b/headers/os/interface/LayoutUtils.h
index cac5c2e..24e91c0 100644
--- a/headers/os/interface/LayoutUtils.h
+++ b/headers/os/interface/LayoutUtils.h
@@ -1,16 +1,21 @@
 /*
- * Copyright 2006, Haiku, Inc. All rights reserved.
+ * Copyright 2006-2013, Haiku, Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef        _LAYOUT_UTILS_H
 #define        _LAYOUT_UTILS_H
 
+
 #include <Alignment.h>
 #include <Rect.h>
 #include <Size.h>
+#include <String.h>
+
 
+class BLayoutItem;
 class BView;
 
+
 class BLayoutUtils {
 public:
 //     static  float                           AddSizesFloat(float a, float b);
@@ -36,6 +41,17 @@ public:
                                                                        
BAlignment alignment);
        static  void                            AlignInFrame(BView* view, BRect 
frame);
        static  BRect                           MoveIntoFrame(BRect rect, BSize 
frameSize);
+
+       // debugging
+       static  BString                         GetLayoutTreeDump(BView* view);
+       static  BString                         GetLayoutTreeDump(BLayoutItem* 
item);
+
+private:
+       static  void                            _GetLayoutTreeDump(BView* view, 
int level,
+                                                                       
BString& _output);
+       static  void                            _GetLayoutTreeDump(BLayoutItem* 
item,
+                                                                       int 
level, bool isViewLayout,
+                                                                       
BString& _output);
 };
 
 #endif //      _LAYOUT_UTILS_H
diff --git a/src/kits/interface/LayoutUtils.cpp 
b/src/kits/interface/LayoutUtils.cpp
index 577da47..67e2bcc 100644
--- a/src/kits/interface/LayoutUtils.cpp
+++ b/src/kits/interface/LayoutUtils.cpp
@@ -1,12 +1,17 @@
 /*
- * Copyright 2006-2010, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2006-2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
 #include <LayoutUtils.h>
 
+#include <typeinfo>
+
+#include <Layout.h>
 #include <View.h>
 
+#include "ViewLayoutItem.h"
+
 
 // // AddSizesFloat
 // float
@@ -230,3 +235,111 @@ BLayoutUtils::MoveIntoFrame(BRect rect, BSize frameSize)
 
        return rect.OffsetToSelf(leftTop);
 }
+
+
+/*static*/ BString
+BLayoutUtils::GetLayoutTreeDump(BView* view)
+{
+       BString result;
+       _GetLayoutTreeDump(view, 0, result);
+       return result;
+}
+
+
+/*static*/ BString
+BLayoutUtils::GetLayoutTreeDump(BLayoutItem* item)
+{
+       BString result;
+       _GetLayoutTreeDump(item, 0, false, result);
+       return result;
+}
+
+
+/*static*/ void
+BLayoutUtils::_GetLayoutTreeDump(BView* view, int level, BString& _output)
+{
+       BString indent;
+       indent.SetTo(' ', level * 2);
+
+       if (view == NULL) {
+               _output << indent << "<null view>\n";
+               return;
+       }
+
+       BRect frame = view->Frame();
+       BSize min = view->MinSize();
+       BSize max = view->MinSize();
+       BSize preferred = view->PreferredSize();
+       _output << BString().SetToFormat(
+               "%sview %p (%s):\n"
+               "%s  frame: (%f, %f, %f, %f)\n"
+               "%s  min:   (%f, %f)\n"
+               "%s  max:   (%f, %f)\n"
+               "%s  pref:  (%f, %f)\n",
+               indent.String(), view, typeid(*view).name(),
+               indent.String(), frame.left, frame.top, frame.right, 
frame.bottom,
+               indent.String(), min.width, min.height,
+               indent.String(), max.width, max.height,
+               indent.String(), preferred.width, preferred.height);
+
+       if (BLayout* layout = view->GetLayout()) {
+               _GetLayoutTreeDump(layout, level, true, _output);
+               return;
+       }
+
+       int32 count = view->CountChildren();
+       for (int32 i = 0; i < count; i++) {
+               _output << indent << "  ---\n";
+               _GetLayoutTreeDump(view->ChildAt(i), level + 1, _output);
+       }
+}
+
+
+/*static*/ void
+BLayoutUtils::_GetLayoutTreeDump(BLayoutItem* item, int level,
+       bool isViewLayout, BString& _output)
+{
+       if (BViewLayoutItem* viewItem = dynamic_cast<BViewLayoutItem*>(item)) {
+               _GetLayoutTreeDump(viewItem->View(), level, _output);
+               return;
+       }
+
+       BString indent;
+       indent.SetTo(' ', level * 2);
+
+       if (item == NULL) {
+               _output << indent << "<null item>\n";
+               return;
+       }
+
+       BLayout* layout = dynamic_cast<BLayout*>(item);
+       BRect frame = item->Frame();
+       BSize min = item->MinSize();
+       BSize max = item->MinSize();
+       BSize preferred = item->PreferredSize();
+       if (isViewLayout) {
+               _output << indent << BString().SetToFormat("  [layout %p 
(%s)]\n",
+                       layout, typeid(*layout).name());
+       } else {
+               _output << indent << BString().SetToFormat("item %p (%s):\n",
+                       item, typeid(*item).name());
+       }
+       _output << BString().SetToFormat(
+               "%s  frame: (%f, %f, %f, %f)\n"
+               "%s  min:   (%f, %f)\n"
+               "%s  max:   (%f, %f)\n"
+               "%s  pref:  (%f, %f)\n",
+               indent.String(), frame.left, frame.top, frame.right, 
frame.bottom,
+               indent.String(), min.width, min.height,
+               indent.String(), max.width, max.height,
+               indent.String(), preferred.width, preferred.height);
+
+       if (layout == NULL)
+               return;
+
+       int32 count = layout->CountItems();
+       for (int32 i = 0; i < count; i++) {
+               _output << indent << "  ---\n";
+               _GetLayoutTreeDump(layout->ItemAt(i), level + 1, false, 
_output);
+       }
+}

############################################################################

Commit:      5c56812d900c7777c62eab899c0bb553459ef67b
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:47:28 2013 UTC

BControlLook::ComposeSpacing(): Avoid non-integers

----------------------------------------------------------------------------

diff --git a/src/kits/interface/ControlLook.cpp 
b/src/kits/interface/ControlLook.cpp
index acb95ed..bd44d4f 100644
--- a/src/kits/interface/ControlLook.cpp
+++ b/src/kits/interface/ControlLook.cpp
@@ -67,13 +67,13 @@ BControlLook::ComposeSpacing(float spacing)
        if (spacing == B_USE_DEFAULT_SPACING || spacing == B_USE_ITEM_SPACING) {
                return be_control_look->DefaultItemSpacing();
        } else if (spacing == B_USE_HALF_ITEM_SPACING) {
-               return be_control_look->DefaultItemSpacing() * 0.5f;
+               return ceilf(be_control_look->DefaultItemSpacing() * 0.5f);
        } else if (spacing == B_USE_WINDOW_INSETS) {
                return be_control_look->DefaultItemSpacing();
        } else if (spacing == B_USE_SMALL_SPACING) {
-               return be_control_look->DefaultItemSpacing() * 0.7f;
+               return ceilf(be_control_look->DefaultItemSpacing() * 0.7f);
        } else if (spacing == B_USE_BIG_SPACING) {
-               return be_control_look->DefaultItemSpacing() * 1.3f;
+               return ceilf(be_control_look->DefaultItemSpacing() * 1.3f);
        }
        return spacing;
 }

############################################################################

Commit:      88f12ad84fa46739ba94376b5324cdc35bd50b9c
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:51:03 2013 UTC

Add private BViewPort class

* It simplifies putting regular layout-aware views or layout items into
  a BScrollView.
* Not quite complete yet: Height-for-width support is missing, but that
  also requires fixing BScrollView in this respect. Scroll bar auto-hide
  support would be nice as well.

----------------------------------------------------------------------------

diff --git a/headers/private/interface/ViewPort.h 
b/headers/private/interface/ViewPort.h
new file mode 100644
index 0000000..cee7afb
--- /dev/null
+++ b/headers/private/interface/ViewPort.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+#ifndef _VIEW_PORT_H
+#define _VIEW_PORT_H
+
+
+#include <View.h>
+
+
+namespace BPrivate {
+
+
+class BViewPort : public BView {
+public:
+                                                               
BViewPort(BView* child = NULL);
+                                                               
BViewPort(BLayoutItem* child);
+                                                               BViewPort(const 
char* name,
+                                                                       BView* 
child = NULL);
+                                                               BViewPort(const 
char* name,
+                                                                       
BLayoutItem* child);
+       virtual                                         ~BViewPort();
+
+                       BView*                          ChildView() const;
+                       void                            SetChildView(BView* 
child);
+
+                       BLayoutItem*            ChildItem() const;
+                       void                            
SetChildItem(BLayoutItem* child);
+
+private:
+                       class ViewPortLayout;
+                       friend class ViewPortLayout;
+
+private:
+                       void                            _Init();
+
+private:
+                       ViewPortLayout*         fLayout;
+                       BLayoutItem*            fChild;
+};
+
+
+}      // namespace BPrivate
+
+
+using ::BPrivate::BViewPort;
+
+
+#endif // _VIEW_PORT_H
diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile
index 5fe6215..ad31fd2 100644
--- a/src/kits/interface/Jamfile
+++ b/src/kits/interface/Jamfile
@@ -129,6 +129,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
                        TwoDimensionalLayout.cpp
                        View.cpp
                        ViewLayoutItem.cpp
+                       ViewPort.cpp
                        Window.cpp
                        WindowStack.cpp
                        ZombieReplicantView.cpp
diff --git a/src/kits/interface/ViewPort.cpp b/src/kits/interface/ViewPort.cpp
new file mode 100644
index 0000000..c2ea225
--- /dev/null
+++ b/src/kits/interface/ViewPort.cpp
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <ViewPort.h>
+
+#include <algorithm>
+
+#include <AbstractLayout.h>
+#include <ScrollBar.h>
+
+#include "ViewLayoutItem.h"
+
+
+namespace BPrivate {
+
+
+// #pragma mark - ViewPortLayout
+
+
+class BViewPort::ViewPortLayout : public BAbstractLayout {
+public:
+       ViewPortLayout(BViewPort* viewPort)
+               :
+               BAbstractLayout(),
+               fViewPort(viewPort),
+               fHasViewChild(false),
+               fIsCacheValid(false),
+               fMin(),
+               fMax(),
+               fPreferred()
+       {
+       }
+
+       BView* ChildView() const
+       {
+               if (!fHasViewChild)
+                       return NULL;
+               if (BViewLayoutItem* item = 
dynamic_cast<BViewLayoutItem*>(ItemAt(0)))
+                       return item->View();
+               return NULL;
+       }
+
+       void SetChildView(BView* view)
+       {
+               _UnsetChild();
+
+               if (view != NULL && AddView(0, view) != NULL)
+                       fHasViewChild = true;
+       }
+
+       BLayoutItem* ChildItem() const
+       {
+               return ItemAt(0);
+       }
+
+       void SetChildItem(BLayoutItem* item)
+       {
+               _UnsetChild();
+
+               if (item != NULL)
+                       AddItem(0, item);
+       }
+
+       virtual BSize BaseMinSize()
+       {
+               _ValidateMinMax();
+               return fMin;
+       }
+
+       virtual BSize BaseMaxSize()
+       {
+               _ValidateMinMax();
+               return fMax;
+       }
+
+       virtual BSize BasePreferredSize()
+       {
+               _ValidateMinMax();
+               return fPreferred;
+       }
+
+       virtual BAlignment BaseAlignment()
+       {
+               return BAbstractLayout::BaseAlignment();
+       }
+
+       virtual bool HasHeightForWidth()
+       {
+               _ValidateMinMax();
+               return false;
+               // TODO: Support height-for-width!
+       }
+
+       virtual void GetHeightForWidth(float width, float* min, float* max,
+               float* preferred)
+       {
+               if (!HasHeightForWidth())
+                       return;
+
+               // TODO: Support height-for-width!
+       }
+
+       virtual void LayoutInvalidated(bool children)
+       {
+               fIsCacheValid = false;
+       }
+
+       virtual void DoLayout()
+       {
+               _ValidateMinMax();
+
+               BLayoutItem* child = ItemAt(0);
+               if (child == NULL)
+                       return;
+
+               // Determine the layout area: LayoutArea() will only give us 
the size
+               // of the view port's frame.
+               BSize viewSize = LayoutArea().Size();
+               BSize layoutSize = viewSize;
+
+               BSize childMin = child->MinSize();
+               BSize childMax = child->MaxSize();
+
+               // apply the maximum constraints
+               layoutSize.width = std::min(layoutSize.width, childMax.width);
+               layoutSize.height = std::min(layoutSize.height, 
childMax.height);
+
+               // apply the minimum constraints
+               layoutSize.width = std::max(layoutSize.width, childMin.width);
+               layoutSize.height = std::max(layoutSize.height, 
childMin.height);
+
+               // TODO: Support height-for-width!
+
+               child->AlignInFrame(BRect(BPoint(0, 0), layoutSize));
+
+               _UpdateScrollBar(fViewPort->ScrollBar(B_HORIZONTAL), 
viewSize.width,
+                       layoutSize.width);
+               _UpdateScrollBar(fViewPort->ScrollBar(B_VERTICAL), 
viewSize.height,
+                       layoutSize.height);
+       }
+
+private:
+       void _UnsetChild()
+       {
+               if (CountItems() > 0) {
+                       BLayoutItem* item = RemoveItem((int32)0);
+                       if (fHasViewChild)
+                               delete item;
+                       fHasViewChild = false;
+               }
+       }
+
+       void _ValidateMinMax()
+       {
+               if (fIsCacheValid)
+                       return;
+
+               if (BLayoutItem* child = ItemAt(0)) {
+                       fMin = child->MinSize();
+                       if (_IsHorizontallyScrollable())
+                               fMin.width = -1;
+                       if (_IsVerticallyScrollable())
+                               fMin.height = -1;
+                       fMax = child->MaxSize();
+                       fPreferred = child->PreferredSize();
+                       // TODO: Support height-for-width!
+               } else {
+                       fMin.Set(-1, -1);
+                       fMax.Set(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
+                       fPreferred.Set(20, 20);
+               }
+
+               fIsCacheValid = true;
+       }
+
+       bool _IsHorizontallyScrollable() const
+       {
+               return fViewPort->ScrollBar(B_HORIZONTAL) != NULL;
+       }
+
+       bool _IsVerticallyScrollable() const
+       {
+               return fViewPort->ScrollBar(B_VERTICAL) != NULL;
+       }
+
+       void _UpdateScrollBar(BScrollBar* scrollBar, float viewPortSize,
+               float dataSize)
+       {
+               if (scrollBar == NULL)
+                       return;
+
+               if (viewPortSize < dataSize) {
+                       scrollBar->SetRange(0, dataSize - viewPortSize);
+                       scrollBar->SetProportion(viewPortSize / dataSize);
+                       float smallStep;
+                       scrollBar->GetSteps(&smallStep, NULL);
+                       scrollBar->SetSteps(smallStep, viewPortSize);
+               } else {
+                       scrollBar->SetRange(0, 0);
+                       scrollBar->SetProportion(1);
+               }
+       }
+
+private:
+       BViewPort*      fViewPort;
+       bool            fHasViewChild;
+       bool            fIsCacheValid;
+       BSize           fMin;
+       BSize           fMax;
+       BSize           fPreferred;
+};
+
+
+// #pragma mark - BViewPort
+
+
+BViewPort::BViewPort(BView* child)
+       :
+       BView(NULL, 0),
+       fChild(NULL)
+{
+       _Init();
+       SetChildView(child);
+}
+
+
+BViewPort::BViewPort(BLayoutItem* child)
+       :
+       BView(NULL, 0),
+       fChild(NULL)
+{
+       _Init();
+       SetChildItem(child);
+}
+
+
+BViewPort::BViewPort(const char* name, BView* child)
+       :
+       BView(name, 0),
+       fChild(NULL)
+{
+       _Init();
+       SetChildView(child);
+}
+
+
+BViewPort::BViewPort(const char* name, BLayoutItem* child)
+       :
+       BView(name, 0),
+       fChild(NULL)
+{
+       _Init();
+       SetChildItem(child);
+}
+
+
+BViewPort::~BViewPort()
+{
+}
+
+
+BView*
+BViewPort::ChildView() const
+{
+       return fLayout->ChildView();
+}
+
+
+void
+BViewPort::SetChildView(BView* child)
+{
+       fLayout->SetChildView(child);
+       InvalidateLayout();
+}
+
+
+BLayoutItem*
+BViewPort::ChildItem() const
+{
+       return fLayout->ChildItem();
+}
+
+
+void
+BViewPort::SetChildItem(BLayoutItem* child)
+{
+       fLayout->SetChildItem(child);
+       InvalidateLayout();
+}
+
+
+void
+BViewPort::_Init()
+{
+       fLayout = new ViewPortLayout(this);
+       SetLayout(fLayout);
+}
+
+
+}      // namespace BPrivate
+
+
+using ::BPrivate::BViewPort;

############################################################################

Commit:      b53a2e6af53a5f375e63a50c4a021bb8967cb2d7
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Wed Sep 11 02:53:06 2013 UTC

package daemon: ProblemWindow: Use a scroll view

----------------------------------------------------------------------------

diff --git a/src/servers/package/Jamfile b/src/servers/package/Jamfile
index 348dc1b..d2859db 100644
--- a/src/servers/package/Jamfile
+++ b/src/servers/package/Jamfile
@@ -1,7 +1,7 @@
 SubDir HAIKU_TOP src servers package ;
 
 UsePrivateSystemHeaders ;
-UsePrivateHeaders app kernel shared ;
+UsePrivateHeaders app interface kernel shared ;
 
 Server package_daemon
        :
diff --git a/src/servers/package/ProblemWindow.cpp 
b/src/servers/package/ProblemWindow.cpp
index db0493a..8dc68de 100644
--- a/src/servers/package/ProblemWindow.cpp
+++ b/src/servers/package/ProblemWindow.cpp
@@ -10,6 +10,7 @@
 #include <GroupView.h>
 #include <LayoutBuilder.h>
 #include <RadioButton.h>
+#include <ScrollView.h>
 #include <StringView.h>
 #include <package/solver/Solver.h>
 #include <package/solver/SolverPackage.h>
@@ -18,6 +19,7 @@
 
 #include <AutoLocker.h>
 #include <package/manager/Exceptions.h>
+#include <ViewPort.h>
 
 
 using namespace BPackageKit;
@@ -70,19 +72,33 @@ ProblemWindow::ProblemWindow()
        if (fDoneSemaphore < 0)
                throw std::bad_alloc();
 
+       BStringView* topTextView = NULL;
+       BViewPort* viewPort = NULL;
+
        BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
                .SetInsets(B_USE_SMALL_INSETS)
-               .Add(new BStringView(NULL,
+               .Add(topTextView = new BStringView(NULL,
                        "The following problems have been encountered. Please 
select a "
                        "solution for each:"))
-// TODO: Use a scroll view!
-               .Add(fContainerView = new BGroupView(B_VERTICAL, 0))
+               .Add(new BScrollView(NULL, viewPort = new BViewPort(), 0, 
false, true))
                .AddGroup(B_HORIZONTAL)
                        .Add(fCancelButton = new BButton("Cancel", new 
BMessage(B_CANCEL)))
                        .AddGlue()
                        .Add(fRetryButton = new BButton("Retry",
                                new BMessage(kRetryMessage)))
                .End();
+
+       topTextView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
+
+       viewPort->SetChildView(fContainerView = new BGroupView(B_VERTICAL, 0));
+
+       // set small scroll step (large step will be set by the view port)
+       BFont font;
+       topTextView->GetFont(&font);
+       font_height fontHeight;
+       font.GetHeight(&fontHeight);
+       float smallStep = ceilf(fontHeight.ascent + fontHeight.descent);
+       viewPort->ScrollBar(B_VERTICAL)->SetSteps(smallStep, smallStep);
 }
 
 


Other related posts: