[Haiku-commits] r27508 - in haiku/trunk: headers/os/interface src/kits/interface

stippi at mail.berlios.de stippi at mail.berlios.de
Sun Sep 14 21:01:58 CEST 2008


Author: stippi
Date: 2008-09-14 21:01:54 +0200 (Sun, 14 Sep 2008)
New Revision: 27508
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=27508&view=rev

Modified:
   haiku/trunk/headers/os/interface/MenuField.h
   haiku/trunk/src/kits/interface/MenuField.cpp
Log:
Several fixes to BMenuField layout calculations.
* The most important fix is that in BMenuField::_ValidateLayoutData(),
  divider was calculated, but then never used. If the menu field was not
  using the layout management, it should take the existing fDivider into
  account, but never did. This caused #2728.
* Added some tracing that helped me debug this.
* Fixed a bunch of layouting inconsistencies. It will also improve some
  unnecessary resizing of the menu bar.

Will test all of this some more. But in the test app I do have, the BMenuField
works more like in BeOS now.


Modified: haiku/trunk/headers/os/interface/MenuField.h
===================================================================
--- haiku/trunk/headers/os/interface/MenuField.h	2008-09-14 18:52:30 UTC (rev 27507)
+++ haiku/trunk/headers/os/interface/MenuField.h	2008-09-14 19:01:54 UTC (rev 27508)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 
@@ -115,7 +115,7 @@
 			void			DrawLabel(BRect bounds, BRect update);
 	static	void			InitMenu(BMenu* menu);
 	
-			int32		_MenuTask();
+			int32			_MenuTask();
 	static	int32			_thread_entry(void *arg);
 	
 			void			_UpdateFrame();
@@ -123,6 +123,7 @@
 								BRect frame, bool fixedSize);
 
 			void			_ValidateLayoutData();
+			float			_MenuBarWidthDiff() const;
 
 			char*			fLabel;
 			BMenu*			fMenu;

Modified: haiku/trunk/src/kits/interface/MenuField.cpp
===================================================================
--- haiku/trunk/src/kits/interface/MenuField.cpp	2008-09-14 18:52:30 UTC (rev 27507)
+++ haiku/trunk/src/kits/interface/MenuField.cpp	2008-09-14 19:01:54 UTC (rev 27508)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2006, Haiku, Inc.
+ * Copyright 2001-2008, Haiku, Inc.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -20,6 +20,21 @@
 #include <Window.h>
 
 
+//#define TRACE_MENU_FIELD
+#ifdef TRACE_MENU_FIELD
+#	include <FunctionTracer.h>
+	static int32 sFunctionDepth = -1;
+#	define CALLED(x...)	FunctionTracer _ft("BMenuField", __FUNCTION__, \
+							sFunctionDepth)
+#	define TRACE(x...)	{ BString _to; \
+							_to.Append(' ', (sFunctionDepth + 1) * 2); \
+							printf("%s", _to.String()); printf(x); }
+#else
+#	define CALLED(x...)
+#	define TRACE(x...)
+#endif
+
+
 class BMenuField::LabelLayoutItem : public BAbstractLayoutItem {
 public:
 								LabelLayoutItem(BMenuField* parent);
@@ -98,6 +113,10 @@
 	BMenu *menu, uint32 resize, uint32 flags)
 	: BView(frame, name, resize, flags)
 {
+	CALLED();
+
+	TRACE("frame.width: %.2f, height: %.2f\n", frame.Width(), frame.Height());
+
 	InitObject(label);
 
 	frame.OffsetTo(B_ORIGIN);
@@ -280,6 +299,8 @@
 void
 BMenuField::AttachedToWindow()
 {
+	CALLED();
+
 	BView* parent = Parent();
 	if (parent != NULL) {
 		// inherit the color from parent
@@ -296,8 +317,14 @@
 void
 BMenuField::AllAttached()
 {
+	CALLED();
+
+	TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height());
+
 	ResizeTo(Bounds().Width(),
 		fMenuBar->Bounds().Height() + kVMargin + kVMargin);
+
+	TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height());
 }
 
 
@@ -592,18 +619,26 @@
 void
 BMenuField::ResizeToPreferred()
 {
+	CALLED();
+
+	TRACE("fMenuBar->Frame().width: %.2f, height: %.2f\n",
+		fMenuBar->Frame().Width(), fMenuBar->Frame().Height());
+
 	fMenuBar->ResizeToPreferred();
 
+	TRACE("fMenuBar->Frame().width: %.2f, height: %.2f\n",
+		fMenuBar->Frame().Width(), fMenuBar->Frame().Height());
+
 	BView::ResizeToPreferred();
 
 	if (fFixedSizeMB) {
-		// we have let the menubar resize itsself, but
+		// we have let the menubar resize itself, but
 		// in fixed size mode, the menubar is supposed to
 		// be at the right end of the view always. Since
 		// the menu bar is in follow left/right mode then,
 		// resizing ourselfs might have caused the menubar
 		// to be outside now
-		fMenuBar->ResizeTo(Bounds().Width() - fDivider - 2,
+		fMenuBar->ResizeTo(Bounds().Width() - _MenuBarWidthDiff(),
 			fMenuBar->Frame().Height());
 	}
 }
@@ -612,6 +647,8 @@
 void
 BMenuField::GetPreferredSize(float *_width, float *_height)
 {
+	CALLED();
+
 	_ValidateLayoutData();
 
 	if (_width)
@@ -625,6 +662,8 @@
 BSize
 BMenuField::MinSize()
 {
+	CALLED();
+
 	_ValidateLayoutData();
 	return BLayoutUtils::ComposeSize(ExplicitMinSize(), fLayoutData->min);
 }
@@ -633,6 +672,8 @@
 BSize
 BMenuField::MaxSize()
 {
+	CALLED();
+
 	_ValidateLayoutData();
 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), fLayoutData->min);
 }
@@ -641,6 +682,8 @@
 BSize
 BMenuField::PreferredSize()
 {
+	CALLED();
+
 	_ValidateLayoutData();
 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), fLayoutData->min);
 }
@@ -649,6 +692,8 @@
 void
 BMenuField::InvalidateLayout(bool descendants)
 {
+	CALLED();
+
 	fLayoutData->valid = false;
 
 	BView::InvalidateLayout(descendants);
@@ -687,6 +732,8 @@
 	if (!(Flags() & B_SUPPORTS_LAYOUT))
 		return;
 
+	CALLED();
+
 	// If the user set a layout, we let the base class version call its
 	// hook.
 	if (GetLayout()) {
@@ -747,6 +794,8 @@
 void
 BMenuField::InitObject(const char *label)
 {
+	CALLED();
+
 	fLabel = NULL;
 	fMenu = NULL;
 	fMenuBar = NULL;
@@ -773,14 +822,17 @@
 void
 BMenuField::InitObject2()
 {
-	font_height fontHeight;
-	GetFontHeight(&fontHeight);
+	CALLED();
 
-	// TODO: fix this calculation
-	float height = floorf(fontHeight.ascent + fontHeight.descent
-		+ fontHeight.leading) + 7;
+	float height;
+	fMenuBar->GetPreferredSize(NULL, &height);
+	fMenuBar->ResizeTo(Bounds().Width() - _MenuBarWidthDiff(), height);
 
-	fMenuBar->ResizeTo(Bounds().Width() - fDivider - 2, height);
+	TRACE("frame(%.1f, %.1f, %.1f, %.1f) (%.2f, %.2f)\n",
+		fMenuBar->Frame().left, fMenuBar->Frame().top,
+		fMenuBar->Frame().right, fMenuBar->Frame().bottom,
+		fMenuBar->Frame().Width(), fMenuBar->Frame().Height());
+
 	fMenuBar->AddFilter(new _BMCFilter_(this, B_MOUSE_DOWN));
 }
 
@@ -788,6 +840,8 @@
 void
 BMenuField::DrawLabel(BRect bounds, BRect update)
 {
+	CALLED();
+
 	_ValidateLayoutData();
 	font_height& fh = fLayoutData->font_info;
 
@@ -880,6 +934,8 @@
 void
 BMenuField::_UpdateFrame()
 {
+	CALLED();
+
 	if (fLayoutData->label_layout_item && fLayoutData->menu_bar_layout_item) {
 		BRect labelFrame = fLayoutData->label_layout_item->Frame();
 		BRect menuFrame = fLayoutData->menu_bar_layout_item->Frame();
@@ -905,13 +961,22 @@
 void
 BMenuField::_InitMenuBar(BMenu* menu, BRect frame, bool fixedSize)
 {
+	CALLED();
+
 	fMenu = menu;
 	InitMenu(menu);
 
-	fMenuBar = new _BMCMenuBar_(BRect(frame.left + fDivider + 1,
-		frame.top + kVMargin, frame.right - 2, frame.bottom - kVMargin),
-		fixedSize, this);
+	frame.left = fDivider + 1;
+	frame.top = kVMargin;
+	frame.right -= kVMargin;
+	frame.bottom -= kVMargin;
 
+	TRACE("frame(%.1f, %.1f, %.1f, %.1f) (%.2f, %.2f)\n",
+		frame.left, frame.top, frame.right, frame.bottom,
+		frame.Width(), frame.Height());
+
+	fMenuBar = new _BMCMenuBar_(frame, fixedSize, this);
+
 	// by default align the menu bar left in the available space
 	fMenuBar->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT,
 		B_ALIGN_VERTICAL_UNSET));
@@ -926,6 +991,8 @@
 void
 BMenuField::_ValidateLayoutData()
 {
+	CALLED();
+
 	if (fLayoutData->valid)
 		return;
 
@@ -946,11 +1013,17 @@
 		divider = max_c(divider, fDivider);
 
 	// get the minimal (== preferred) menu bar size
+	// TODO: BMenu::MinSize() is using the ResizeMode() to decide the
+	// minimum width. If the mode is B_FOLLOW_LEFT_RIGHT, it will use the
+	// parent's frame width or window's frame width. So at least the returned
+	// size is wrong, but appearantly it doesn't have much bad effect.
 	fLayoutData->menu_bar_min = fMenuBar->MinSize();
 
+	TRACE("menu bar min width: %.2f\n", fLayoutData->menu_bar_min.width);
+
 	// compute our minimal (== preferred) size
-	// TODO: The layout is a bit broken. A one pixel wide border is draw around
-	// the menu bar to give it it's look. When the view has the focus,
+	// TODO: The layout is a bit broken. A one pixel wide border is drawn
+	// around the menu bar to give it it's look. When the view has the focus,
 	// additionally a one pixel wide blue frame is drawn around it. In order
 	// to be able to easily visually align the menu bar with the text view of
 	// a text control, the divider must ignore the focus frame, though. Hence
@@ -959,17 +1032,27 @@
 	min.width += 2 * kVMargin - 1;
 	min.height += 2 * kVMargin;
 
-	if (fLayoutData->label_width > 0)
-		min.width += fLayoutData->label_width + 5;
+	if (divider > 0)
+		min.width += divider;
 	if (fLayoutData->label_height > min.height)
 		min.height = fLayoutData->label_height;
 
 	fLayoutData->min = min;
 
 	fLayoutData->valid = true;
+
+
+	TRACE("width: %.2f, height: %.2f\n", min.width, min.height);
 }
 
 
+float
+BMenuField::_MenuBarWidthDiff() const
+{
+	return fDivider + kVMargin + 1;
+}
+
+
 // #pragma mark -
 
 




More information about the Haiku-commits mailing list