<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html class="js" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Laying It All Out, Part 1 | Haiku Project</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="canonical" href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1"><meta name="keywords" content="development, gui, layout"><meta name="revisit-after" content="1 day"><link rel="search" type="application/opensearchdescription+xml" href="http://www.haiku-os.org/opensearch.xml" title="Haiku Project"><link rel="shortcut icon" href="http://www.haiku-os.org/sites/haiku-os.org/themes/shijin/favicon.ico" type="image/x-icon"> <link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/views.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/aggregator.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/book.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/node.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/poll.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/defaults.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/system.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/system-menus.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/user.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/cafepress.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/category.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/content-module.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/date.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/geshifilter.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/lightbox.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/logintoboggan.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/quote.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/forum.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/calendar.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/farbtastic.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/extlink.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/fieldgroup.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/comment.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/style.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/icons.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/icons-legacy.css"><link type="text/css" rel="stylesheet" media="all" href="laying_it_all_out_part_1_files/local.css"><!--[if IE 7]> <link rel="stylesheet" href="/sites/haiku-os.org/themes/shijin/ie7-fixes.css" type="text/css"> <![endif]--><!--[if lte IE 6]> <link rel="stylesheet" href="/sites/haiku-os.org/themes/shijin/ie6-fixes.css" type="text/css"> <![endif]--> <script type="text/javascript" src="laying_it_all_out_part_1_files/jquery.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/drupal.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/img_assist.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/auto_image_handling.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/lightbox.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/extlink.js"></script><script type="text/javascript" src="laying_it_all_out_part_1_files/nearest_mirror.js"></script><script type="text/javascript"><!--//--><![CDATA[//><!--jQuery.extend(Drupal.settings, { "basePath": "/", "googleanalytics": { "trackOutgoing": 1, "trackMailto": 1, "trackDownload": 1, "trackDownloadExtensions": "7z|aac|avi|csv|doc|exe|flv|gif|gz|jpe?g|js|mp(3|4|e?g)|mov|pdf|phps|png|ppt|rar|sit|tar|torrent|txt|wma|wmv|xls|xml|zip" }, "lightbox2": { "rtl": 0, "file_path": "/(\\w\\w/)files", "default_image": "/sites/all/modules/lightbox2/images/brokenimage.jpg", "border_size": "10", "font_color": "000", "box_color": "fff", "top_position": "", "overlay_opacity": "0.8", "overlay_color": "000", "disable_close_click": 0, "resize_sequence": "0", "resize_speed": 400, "fade_in_speed": 400, "slide_down_speed": 600, "use_alt_layout": 0, "disable_resize": 0, "disable_zoom": 0, "force_show_nav": 0, "loop_items": 0, "node_link_text": "Original image (opens new page)", "node_link_target": "_blank", "image_count": "Image !current of !total", "video_count": "Video !current of !total", "page_count": "Page !current of !total", "lite_press_x_close": "press \x3ca href=\"#\" onclick=\"hideLightbox(); return FALSE;\"\x3e\x3ckbd\x3ex\x3c/kbd\x3e\x3c/a\x3e to close", "download_link_text": "", "enable_login": false, "enable_contact": false, "keys_close": "c x 27", "keys_previous": "p 37", "keys_next": "n 39", "keys_zoom": "z", "keys_play_pause": "32", "display_image_size": "", "image_node_sizes": "(\\.thumbnail)", "trigger_lightbox_classes": "", "trigger_lightbox_group_classes": "img.inline,img.flickr-photo-img,img.flickr-photoset-img,img.ImageFrame_image,img.ImageFrame_none,img.image-img_assist_custom,img.thumbnail, img.image-thumbnail", "trigger_slideshow_classes": "", "trigger_lightframe_classes": "", "trigger_lightframe_group_classes": "", "custom_class_handler": 0, "custom_trigger_classes": "", "disable_for_gallery_lists": true, "disable_for_acidfree_gallery_lists": true, "enable_acidfree_videos": true, "slideshow_interval": 5000, "slideshow_automatic_start": 0, "slideshow_automatic_exit": 0, "show_play_pause": 0, "pause_on_next_click": 0, "pause_on_previous_click": true, "loop_slides": 0, "iframe_width": 600, "iframe_height": 400, "iframe_border": 1, "enable_video": 0 }, "extlink": { "extTarget": "_blank", "extClass": "ext", "extSubdomains": 0, "extExclude": "", "extInclude": "", "extAlert": 0, "extAlertText": "This link will take you to an external web site. We are not responsible for their content.", "mailtoClass": "mailto" } });//--><!]]></script></head><body class="logged-in not-front full-node node-type-content_document layout-first-main preface-last lightbox-processed"> <div id="page" class="clearfix"> <div id="header"> <div id="header-wrapper" class="clearfix"> <div id="header-first"> <div id="logo"> <a href="http://www.haiku-os.org/" title="Home"><img src="laying_it_all_out_part_1_files/logo.png" alt="Home"></a> </div> <span id="slogan">OPERATING SYSTEM</span> </div><!-- /header-first --> <div id="header-middle"> </div><!-- /header-middle --> <div id="header-last"><div id="top-links"><!-- BEGIN: LOGIN/LOGOFF--><a href="http://www.haiku-os.org/user" title="View/edit your account profile" class="toggleopacity"><img src="laying_it_all_out_part_1_files/Website_Edit_Profile_32.png" alt="View/edit your account profile"></a><a href="http://www.haiku-os.org/node/add" title="Submit article/document" class="toggleopacity"><img src="laying_it_all_out_part_1_files/Website_Submit_32.png" alt="Submit content"></a><a href="http://www.haiku-os.org/logout" title="Logout" class="toggleopacity"><img src="laying_it_all_out_part_1_files/Action_Logout_32.png" alt="Logout"></a><img style="padding: 0px ! important;" src="laying_it_all_out_part_1_files/topnav-separator.png" alt=""><a href="http://www.haiku-os.org/get-haiku" title="Get Haiku!" class="toggleopacity"><img src="laying_it_all_out_part_1_files/installer_32.png" alt="Get Haiku!"></a><a href="http://www.haiku-os.org/contact" title="Contact the Haiku Project" class="toggleopacity"><img src="laying_it_all_out_part_1_files/App_Mail_32.png" alt="Contact the Haiku Project"></a><a href="http://www.haiku-os.org/community/donating_to_haiku" title="Make a donation to the Haiku Project" class="toggleopacity"><img src="laying_it_all_out_part_1_files/App_Finance_32.png" alt="a donation to the Haiku Project"></a><!-- END: LOGIN/LOGOFF--></div><!-- /top-links --> </div><!-- /header-last --> </div><!-- /menu-wrapper --> <div id="menu-wrapper" class="clearfix"> <div id="primary-menu"> <ul class="menu"><li class="collapsed first"><a href="http://www.haiku-os.org/about" title="What is Haiku?">About</a></li><li class="collapsed"><a href="http://www.haiku-os.org/community" title="Learn about the Haiku community">Community</a></li><li class="collapsed"><a href="http://www.haiku-os.org/development" title="Development">Development</a></li><li class="collapsed last"><a href="http://www.haiku-os.org/documents" title="Documents">Documents</a></li></ul> </div><!-- /primary_menu --> <div id="search-box"> <form action="/documents/dev/laying_it_all_out_part_1" accept-charset="UTF-8" method="post" id="search-theme-form"><div><div id="search" class="container-inline"> <div class="form-item" id="edit-search-theme-form-1-wrapper"> <label for="edit-search-theme-form-1">Search this site: </label> <input maxlength="128" name="search_theme_form" id="edit-search-theme-form-1" size="15" value="" title="Enter the terms you wish to search for." class="form-text" type="text"></div><input name="op" id="edit-submit" value="Search" class="form-submit" type="submit"><input name="form_build_id" id="form-cf62e2d04c7e01da8daa96db5ddfd09b" value="form-cf62e2d04c7e01da8daa96db5ddfd09b" type="hidden"><input name="form_token" id="edit-search-theme-form-form-token" value="075c447f1e73c1da9d035163394d5ce8" type="hidden"><input name="form_id" id="edit-search-theme-form" value="search_theme_form" type="hidden"></div></div></form> </div><!-- /search-box --> </div><!-- /header-bottom --> </div><!-- /header --> <!-- PREFACE BLOCKS REMOVED --> <div id="main"> <div id="main-wrapper" class="clearfix"> <div id="breadcrumb"> <div class="breadcrumb"><a href="http://www.haiku-os.org/">Home</a> » <a href="http://www.haiku-os.org/articles">Articles</a> » Laying It All Out, Part 1</div> </div><!-- /breadcrumb --> <div id="sidebar-first"><!-- start block.tpl.php --><div class="block-wrapper odd"> <div id="block-views-article_views-block_1" class="block block-views"> <div class="block-icon pngfix"></div> <h2 class="title block-title pngfix">Latest Articles</h2> <div class="content"> <div class="view view-article-views view-style-normal view-id-article_views view-display-id-block_1"> <div class="view-content"> <div class="item-list"> <ul> <li class="views-row views-row-1 views-row-odd views-row-first"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/articles/2009-11-18_multiboot_installation_gpt_disk">Multiboot Installation on GPT Disk</a></span> </div></li> <li class="views-row views-row-2 views-row-even"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/articles/2009-10-30_how_work_webkit">How to work on WebKit</a></span> </div></li> <li class="views-row views-row-3 views-row-odd"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/documents/dev/system_calls">System calls</a></span> </div></li> <li class="views-row views-row-4 views-row-even"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/documents/user/haiku_under_emulation">Haiku Under Emulation</a></span> </div></li> <li class="views-row views-row-5 views-row-odd"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/documents/dev/how_build_haiku_mac_os_x">How to build Haiku on Mac OS X</a></span> </div></li> <li class="views-row views-row-6 views-row-even"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/documents/dev/beos_joystick_framework">BeOS Joystick Framework</a></span> </div></li> <li class="views-row views-row-7 views-row-odd views-row-last"> <div class="views-field-title"> <span class="field-content"><a href="http://www.haiku-os.org/documents/user/how_to_get_haiku_booted">How To Get Haiku Booted</a></span> </div></li> </ul></div> </div> <div class="view-footer"> <p style="text-align: right;"><a href="http://www.haiku-os.org/articles">Article Index...</a></p> </div></div> </div> </div></div><!-- /end block.tpl.php --> </div><!-- /sidebar-first --> <div id="content-wrapper"> <div id="content"> <div id="content-tabs"> <ul class="tabs primary"><li class="active"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1" class="active">View</a></li><li><a href="http://www.haiku-os.org/node/2220/revisions">Revisions</a></li></ul> </div> <div id="content-inner"> <h1 class="title">Laying It All Out, Part 1</h1> <div id="content-content"><!-- start node.tpl.php --><div id="node-2220" class="node odd full-node node-type-content_document"> <div class="meta">Article contributed by <a href="http://www.haiku-os.org/user/leavengood" title="View user profile.">leavengood</a> on Mon, 2008-07-14 17:53<div class="terms"><a href="http://www.haiku-os.org/tags/gui" rel="tag" title="">gui</a>, <a href="http://www.haiku-os.org/tags/layout" rel="tag" title="">layout</a>, <a href="http://www.haiku-os.org/tags/development_1" rel="tag" title="">development</a></div> <!--/terms--> </div> <!-- <span class="submitted">Posted Mon, 2008-07-14 17:53 by <a href="/user/leavengood" title="View user profile.">leavengood</a></span> --> <div class="content"> <div class="field field-type-text field-field-body"> <div class="field-items"> <div class="field-item"><h3>The Motivation for a Layout System</h3><p>One of the major complaints that any serious BeOS programmer wouldeventually make about the GUI classes in the Be API is the lack of easyfont sensitivity. What this means is that if one designs a GUI usingthe system default fonts and then a user of your application changestheir system fonts to be much smaller or larger than the default, theGUI will likely look bad (especially if the font size is larger.)Things that were previously aligned may not be, and likely text labelswill run into other components or even disappear into the side of thewindow. This is especially true in fixed sized GUIs like dialog boxesand configuration panels. See Figure 1.</p><!--break--><div style="border: 1px solid rgb(170, 170, 170); padding: 5px; float: left; width: 510px; margin-right: 40px;"> <img src="laying_it_all_out_part_1_files/oops.png"> <div style="margin-top: 10px;"> <strong>Figure 1.</strong> Oops, the programmer didn't expect someone to change to size 18 font! </div></div><p>Besides font sensitivity it is also tedious to have to explicitlydesign a GUI with precise locations and sizes for each component. Itmakes adding new components or moving things around more difficult thanit should be.</p><p>The solution to these problems is something called a layout manager.What a layout manager does is manage laying out all the components ofyour application based on various criteria such as the type of layoutas well as the minimum, preferred and maximum sizes of the GUIcomponents. If the user resizes the window or changes the font, thelayout manager gracefully resizes and realigns all the components underits management.</p><p>As implied in the first paragraph, BeOS never had a built-in layoutmanagement system. Several third parties did come to the rescue, suchas Marco Nelissen with his award winning liblayout, as well as BrianTietz in his Santa's Gift Bag library and Angry Red Planet in theirARPCommon library. Of course while these systems all achieved the samebasic goal, their implementation and usage was quite different."Porting" an application from one layout system to the other would befairly difficult.</p><p>Fortunately for us, Ingo Weinhold came to the rescue by committing alayout management system into the Haiku source tree back in August2006. It has been tweaked quite a bit since then but so far has notbeen put to much use. I figure that is because not many know about it.Ingo is a busy man, so I decided to learn the layout system and writethese articles.</p><p>This first article will describe the layout system from a higherlevel, and then in one or more future articles I will go into moredetail.</p><p>First things first, Ingo fully admits that much of the design ofthis layout system was inspired by the QLayout and friends in the Qtlibrary. So it might be helpful to <a target="_blank" class="ext" href="http://doc.trolltech.com/4.4/layout.html">read about that too</a><span class="ext"></span>, though I hope to tell you everything you need to know to work with Haiku's classes eventually.</p><h3>Types of Layout Managers</h3><p>I will start by describing the various types of layout managers thatare currently included in Haiku and how they layout the views undertheir control:</p><ul><li><strong>BCardLayout:</strong> the contained views are layed outlike a deck of cards, one on top of the other and all in the same area,and only one can show at a time. This would be useful in implementing atab-based interface for showing multiple documents in one window, orfor settings windows with multiple sections (like in the settings forBeIDE or FireFox.)</li><li><strong>BGridLayout:</strong> the contained views are layed out ina grid, with each view getting the same general amount of space (thoughthere are options to allow a view to span multiple rows and/orcolumns.) This would be useful in implementing a thumbnailingapplication for example, with each thumbnail getting it's own equalsized space.</li><li><strong>BGroupLayout:</strong> the contained views are layed out ina group, either horizontally or vertically, depending on whatorientation is wanted for the BGroupLayout. When used in combination(multiple horizontal BGroupLayouts contained in one verticalBGroupLayout for example) this is the most flexible and useful of thelayouts. I imagine many future Haiku applications will make much use ofthis layout class.</li><li><strong>BSplitLayout:</strong> this acts much like a BGroupLayout,except each view is separated by a splitter view that allows itscontained area to be resized. Also optionally the area can be resizedsuch that the view disappears completely, something called collapsing.You won't ever actually use this layout directly, but only through theBSplitView class.</li><li><strong>BALMLayout:</strong> the newest kid on the block, this wasadded in February 2008 from code created by Christof Lutteroth andJames Kim. ALM stands for Auckland Layout Model, which is a new kind oflayout invented by Christof at The University of Auckland. Moreinformation about ALM can be read <a target="_blank" class="ext" href="http://aucklandlayout.sourceforge.net/">on its SourceForge project page.</a><span class="ext"></span>I suspect I will dig into this layout more in the future and maydedicate an entire article to it. But the previous link provides a lotof information about the concepts behind ALM.</li></ul><h3>How To Build a GUI Using a Layout</h3><div style="border: 1px solid rgb(170, 170, 170); padding: 5px; float: right; width: 400px; margin-left: 40px;"> <img src="laying_it_all_out_part_1_files/midiplayer_before.png"> <div style="margin-top: 10px;"> <strong>Figure 2.</strong> The MidiPlayer at default (size 12) and size 18 fonts. Even the size 12 version could benefit from the layout system. </div></div><p>To build a Haiku GUI that uses the layout system, you first need tofigure out what kind of layout manager or managers you might need. Foran existing GUI it is probably fairly obvious from what you can see onthe screen. For a new GUI it would probably be helpful to draw it out,though this would probably be done even if there was no layout systeminvolved.</p><p>Once you know the kind of layouts you plan to use, you need to makesure all the BViews you are using have the needed methods to be used inthe layout system. All of the Haiku views and controls should alreadybe compatible with the layout system (and if they are not, <a target="_blank" class="ext" href="http://dev.haiku-os.org/">log a bug</a><span class="ext"></span>.)For custom BViews some extra work is required, which I will explore ina future article. For the purposes of this article I will only useviews that are already well-supported by the layout system.</p><p>For the purposes of an example I could put together a simple exampleGUI, but I think it will be more instructive to show an actual GUI thatalready exists in Haiku that is not font sensitive. The E-mailPreferences applet shown above is one example, but I don't want thecomplication of its GUI to interfere with showing how the layout systemworks. Luckily I have another good option in the MidiPlayer app. SeeFigure 2.</p><p>So based on the GUI in Figure 2, what layout managers will weneed? Well the first thing I see is that there are essentially foursections arranged vertically:</p><ol> <li>The "Drop MIDI file here" control.</li> <li>The labels and controls in the middle.</li> <li>A separator.</li> <li>The Play button.</li></ol><p>So this means that the highest-level layout manager should be avertical BGroupLayout. The set of labels and controls seems to bearranged in a grid, so for that section we can have another layoutmanager, a BGridLayout. But before I start showing the code forcreating this layout, let's look at the original GUI creation code. Itis contained within MidiPlayerWindow.cpp in the CreateViews() method.It also makes use of a few macros. The relevant code (with linenumbers) as of r26407 is show below:</p><pre><font color="#303030"> 32 </font><font color="#20a060">#define _W(a) (a->Frame().Width())</font><font color="#303030"> 33 </font><font color="#20a060">#define _H(a) (a->Frame().Height())</font>...<font color="#303030">240 </font><font color="#406080">void</font> MidiPlayerWindow::CreateViews()<font color="#303030">241 </font>{<font color="#303030">242 </font> scopeView = <font color="#506888">new</font> ScopeView;<font color="#303030">243 </font><font color="#303030">244 </font> showScope = <font color="#506888">new</font> BCheckBox(<font color="#303030">245 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">"showScope"</font>, <font color="#3080a0">"Scope"</font>,<font color="#303030">246 </font> <font color="#506888">new</font> BMessage(MSG_SHOW_SCOPE), B_FOLLOW_LEFT);<font color="#303030">247 </font><font color="#303030">248 </font> showScope->SetValue(B_CONTROL_ON);<font color="#303030">249 </font> showScope->ResizeToPreferred();<font color="#303030">250 </font><font color="#303030">251 </font> CreateInputMenu();<font color="#303030">252 </font> CreateReverbMenu();<font color="#303030">253 </font><font color="#303030">254 </font> volumeSlider = <font color="#506888">new</font> BSlider(<font color="#303030">255 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">"volumeSlider"</font>, <font color="#3080a0">NULL</font>, <font color="#3080a0">NULL</font>,<font color="#303030">256 </font> <font color="#806010">0</font>, <font color="#806010">100</font>, B_TRIANGLE_THUMB);<font color="#303030">257 </font><font color="#303030">258 </font> rgb_color col = { <font color="#806010">152</font>, <font color="#806010">152</font>, <font color="#806010">255</font> };<font color="#303030">259 </font> volumeSlider->UseFillColor(<font color="#3080a0">true</font>, &col);<font color="#303030">260 </font> volumeSlider->SetModificationMessage(<font color="#506888">new</font> BMessage(MSG_VOLUME));<font color="#303030">261 </font> volumeSlider->ResizeToPreferred();<font color="#303030">262 </font> volumeSlider->ResizeTo(_W(scopeView) - <font color="#806010">42</font>, _H(volumeSlider));<font color="#303030">263 </font><font color="#303030">264 </font> playButton = <font color="#506888">new</font> BButton(<font color="#303030">265 </font> BRect(<font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">80</font>, <font color="#806010">1</font>), <font color="#3080a0">"playButton"</font>, <font color="#3080a0">"Play"</font>, <font color="#506888">new</font> BMessage(MSG_PLAY_STOP),<font color="#303030">266 </font> B_FOLLOW_RIGHT);<font color="#303030">267 </font><font color="#303030">268 </font> <font color="#505010">//playButton->MakeDefault(true);</font><font color="#303030">269 </font> playButton->ResizeToPreferred();<font color="#303030">270 </font> playButton->SetEnabled(<font color="#3080a0">false</font>);<font color="#303030">271 </font><font color="#303030">272 </font> BBox* background = <font color="#506888">new</font> BBox(<font color="#303030">273 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,<font color="#303030">274 </font> B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,<font color="#303030">275 </font> B_PLAIN_BORDER);<font color="#303030">276 </font><font color="#303030">277 </font> BBox* divider = <font color="#506888">new</font> BBox(<font color="#303030">278 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,<font color="#303030">279 </font> B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);<font color="#303030">280 </font><font color="#303030">281 </font> divider->ResizeTo(_W(scopeView), <font color="#806010">1</font>);<font color="#303030">282 </font><font color="#303030">283 </font> BStringView* volumeLabel = <font color="#506888">new</font> BStringView(<font color="#303030">284 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">NULL</font>, <font color="#3080a0">"Volume:"</font>);<font color="#303030">285 </font><font color="#303030">286 </font> volumeLabel->ResizeToPreferred();<font color="#303030">287 </font><font color="#303030">288 </font> <font color="#406080">float</font> width = <font color="#806010">8</font> + _W(scopeView) + <font color="#806010">8</font>;<font color="#303030">289 </font><font color="#303030">290 </font> <font color="#406080">float</font> height =<font color="#303030">291 </font> <font color="#806010">8</font> + _H(scopeView)<font color="#303030">292 </font> + <font color="#806010">8</font> + _H(showScope)<font color="#303030">293 </font> + <font color="#806010">4</font> + _H(inputMenu)<font color="#303030">294 </font> + _H(reverbMenu)<font color="#303030">295 </font> + <font color="#806010">2</font> + _H(volumeSlider)<font color="#303030">296 </font> + <font color="#806010">10</font> + _H(divider)<font color="#303030">297 </font> + <font color="#806010">6</font> + _H(playButton)<font color="#303030">298 </font> + <font color="#806010">16</font>;<font color="#303030">299 </font><font color="#303030">300 </font> ResizeTo(width, height);<font color="#303030">301 </font><font color="#303030">302 </font> AddChild(background);<font color="#303030">303 </font> background->ResizeTo(width, height);<font color="#303030">304 </font> background->AddChild(scopeView);<font color="#303030">305 </font> background->AddChild(showScope);<font color="#303030">306 </font> background->AddChild(reverbMenu);<font color="#303030">307 </font> background->AddChild(inputMenu);<font color="#303030">308 </font> background->AddChild(volumeLabel);<font color="#303030">309 </font> background->AddChild(volumeSlider);<font color="#303030">310 </font> background->AddChild(divider);<font color="#303030">311 </font> background->AddChild(playButton);<font color="#303030">312 </font><font color="#303030">313 </font> <font color="#406080">float</font> y = <font color="#806010">8</font>;<font color="#303030">314 </font> scopeView->MoveTo(<font color="#806010">8</font>, y);<font color="#303030">315 </font><font color="#303030">316 </font> y += _H(scopeView) + <font color="#806010">8</font>;<font color="#303030">317 </font> showScope->MoveTo(<font color="#806010">8</font> + <font color="#806010">55</font>, y);<font color="#303030">318 </font><font color="#303030">319 </font> y += _H(showScope) + <font color="#806010">4</font>;<font color="#303030">320 </font> inputMenu->MoveTo(<font color="#806010">8</font>, y);<font color="#303030">321 </font><font color="#303030">322 </font> y += _H(inputMenu);<font color="#303030">323 </font> reverbMenu->MoveTo(<font color="#806010">8</font>, y);<font color="#303030">324 </font><font color="#303030">325 </font> y += _H(reverbMenu) + <font color="#806010">2</font>;<font color="#303030">326 </font> volumeLabel->MoveTo(<font color="#806010">8</font>, y);<font color="#303030">327 </font> volumeSlider->MoveTo(<font color="#806010">8</font> + <font color="#806010">49</font>, y);<font color="#303030">328 </font><font color="#303030">329 </font> y += _H(volumeSlider) + <font color="#806010">10</font>;<font color="#303030">330 </font> divider->MoveTo(<font color="#806010">8</font>, y);<font color="#303030">331 </font><font color="#303030">332 </font> y += _H(divider) + <font color="#806010">6</font>;<font color="#303030">333 </font> playButton->MoveTo((width - _W(playButton)) / <font color="#806010">2</font>, y);<font color="#303030">334 </font>}</pre><p>I am not going to walk through the code, but the main thing I wantnoticed is all the hard-coded numbers used in the manual layout, andall the work required to get things aligned. Another benefit to theHaiku layout system is cleaner code, and I think this example shouldprove that well. In fact I think I will let the code speak for itself.Here is the above CreateViews() method rewritten to use the layoutsystem:</p><pre><font color="#303030">246 </font><font color="#406080">void</font> MidiPlayerWindow::CreateViews()<font color="#303030">247 </font>{<font color="#303030">248 </font> <font color="#505010">// Set up needed views</font><font color="#303030">249 </font> scopeView = <font color="#506888">new</font> ScopeView;<font color="#303030">250 </font><font color="#303030">251 </font> showScope = <font color="#506888">new</font> BCheckBox(<font color="#303030">252 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">"showScope"</font>, <font color="#3080a0">"Scope"</font>,<font color="#303030">253 </font> <font color="#506888">new</font> BMessage(MSG_SHOW_SCOPE), B_FOLLOW_LEFT);<font color="#303030">254 </font> showScope->SetValue(B_CONTROL_ON);<font color="#303030">255 </font><font color="#303030">256 </font> CreateInputMenu();<font color="#303030">257 </font> CreateReverbMenu();<font color="#303030">258 </font><font color="#303030">259 </font> volumeSlider = <font color="#506888">new</font> BSlider(<font color="#303030">260 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">"volumeSlider"</font>, <font color="#3080a0">NULL</font>, <font color="#3080a0">NULL</font>,<font color="#303030">261 </font> <font color="#806010">0</font>, <font color="#806010">100</font>, B_TRIANGLE_THUMB);<font color="#303030">262 </font> rgb_color col = { <font color="#806010">152</font>, <font color="#806010">152</font>, <font color="#806010">255</font> };<font color="#303030">263 </font> volumeSlider->UseFillColor(<font color="#3080a0">true</font>, &col);<font color="#303030">264 </font> volumeSlider->SetModificationMessage(<font color="#506888">new</font> BMessage(MSG_VOLUME));<font color="#303030">265 </font><font color="#303030">266 </font> playButton = <font color="#506888">new</font> BButton(<font color="#303030">267 </font> BRect(<font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">80</font>, <font color="#806010">1</font>), <font color="#3080a0">"playButton"</font>, <font color="#3080a0">"Play"</font>, <font color="#506888">new</font> BMessage(MSG_PLAY_STOP),<font color="#303030">268 </font> B_FOLLOW_RIGHT);<font color="#303030">269 </font> playButton->SetEnabled(<font color="#3080a0">false</font>);<font color="#303030">270 </font><font color="#303030">271 </font> BBox* divider = <font color="#506888">new</font> BBox(<font color="#303030">272 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,<font color="#303030">273 </font> B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);<font color="#303030">274 </font> divider->SetExplicitMaxSize(<font color="#303030">275 </font> BSize(B_SIZE_UNLIMITED, <font color="#806010">1</font>));<font color="#303030">276 </font><font color="#303030">277 </font> BStringView* volumeLabel = <font color="#506888">new</font> BStringView(<font color="#303030">278 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">NULL</font>, <font color="#3080a0">"Volume:"</font>);<font color="#303030">279 </font> volumeLabel->SetAlignment(B_ALIGN_LEFT);<font color="#303030">280 </font> volumeLabel->SetExplicitMaxSize(<font color="#303030">281 </font> BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));<font color="#303030">282 </font><font color="#303030">283 </font> <font color="#505010">// Build the layout</font><font color="#303030">284 </font> SetLayout(<font color="#506888">new</font> BGroupLayout(B_HORIZONTAL));<font color="#303030">285 </font><font color="#303030">286 </font> AddChild(BGroupLayoutBuilder(B_VERTICAL, <font color="#806010">10</font>)<font color="#303030">287 </font> .Add(scopeView)<font color="#303030">288 </font> .Add(BGridLayoutBuilder(<font color="#806010">10</font>, <font color="#806010">10</font>)<font color="#303030">289 </font> .Add(BSpaceLayoutItem::CreateGlue(), <font color="#806010">0</font>, <font color="#806010">0</font>)<font color="#303030">290 </font> .Add(showScope, <font color="#806010">1</font>, <font color="#806010">0</font>)<font color="#303030">291 </font><font color="#303030">292 </font> .Add(reverbMenu->CreateLabelLayoutItem(), <font color="#806010">0</font>, <font color="#806010">1</font>)<font color="#303030">293 </font> .Add(reverbMenu->CreateMenuBarLayoutItem(), <font color="#806010">1</font>, <font color="#806010">1</font>)<font color="#303030">294 </font><font color="#303030">295 </font> .Add(inputMenu->CreateLabelLayoutItem(), <font color="#806010">0</font>, <font color="#806010">2</font>)<font color="#303030">296 </font> .Add(inputMenu->CreateMenuBarLayoutItem(), <font color="#806010">1</font>, <font color="#806010">2</font>)<font color="#303030">297 </font><font color="#303030">298 </font> .Add(volumeLabel, <font color="#806010">0</font>, <font color="#806010">3</font>)<font color="#303030">299 </font> .Add(volumeSlider, <font color="#806010">1</font>, <font color="#806010">3</font>)<font color="#303030">300 </font> )<font color="#303030">301 </font> .AddGlue()<font color="#303030">302 </font> .Add(divider)<font color="#303030">303 </font> .AddGlue()<font color="#303030">304 </font> .Add(playButton)<font color="#303030">305 </font> .AddGlue()<font color="#303030">306 </font> .SetInsets(<font color="#806010">5</font>, <font color="#806010">5</font>, <font color="#806010">5</font>, <font color="#806010">5</font>)<font color="#303030">307 </font> );<font color="#303030">308 </font>}</pre><p>The only significant changes in the first section of the methodwhere the views are created is the removal of the various manual layoutrelated method calls, like <span class="geshifilter"><code class="geshifilter-cpp">playButton<span style="color: rgb(0, 0, 64);">-</span><span style="color: rgb(0, 0, 64);">&</span>gt<span style="color: rgb(0, 128, 128);">;</span>ResizeToPreferred<span style="color: rgb(0, 128, 0);">(</span><span style="color: rgb(0, 128, 0);">)</span><span style="color: rgb(0, 128, 128);">;</span></code></span>,which was originally on line 269. There have been a few additions togive the layout system some hints on how we want things laid out. Forexample an unlimited width and max height of 1 is set up for thedivider BBox, so it stays looking like a divider. In addition thevolumeLabel is set up so it aligns left and fills up all the spaceavailable. This keeps it aligned with the labels for the BMenuFieldsabove it.</p><p>Next we have the real "meat" of the layout code which starts on line284. The first thing I do is set a base layout. In this case I havedecided to use a sort of "dummy" horizontal group layout so that I canlater use the group layout builder to create the vertical layout Ireally want. It seems to be a quirk of the layout system that you haveto have a layout manager set up in the window before you start addingother views that are managed by the layout system. I probably couldhave created the main vertical group layout outside of the builder andmade that the root layout, but I don't think the code would have lookedas nice.</p><p>Speaking of the layout builders, they were created specifically foruses like the above, with each method returning an instance of thebuilder allowing essentially unlimited method chaining. With the rightindentation it can look quite nice and becomes a good represention ofhow the GUI is structured. Hence why I like to use them. Currentlythere is a GridLayoutBuilder, GroupLayoutBuilder, andSplitLayoutBuilder.</p><div style="border: 1px solid rgb(170, 170, 170); padding: 5px; float: right; width: 500px; margin-left: 40px;"> <img src="laying_it_all_out_part_1_files/midiplayer_after.png"> <div style="margin-top: 10px;"> <strong>Figure 3.</strong> The new layout-based MidiPlayer GUI at default (size 12) and size 18 fonts. </div></div><p>On line 286 we have an AddChild() call with the call to the layoutbuilders inside of it. The first argument for the BGroupLayoutBuilderis the orientation of the group layout and the second argument is thespacing used between the layout items. This gives the views containedwithin the layout a little breathing room so they don't look allcrammed together. Once we have the group layout builder we can startadding views to it with the Add() method, and the first thing added isthe scope view. Then we have the middle section which we want managedby a grid layout, hence the call to the grid layout builder. Thearguments to BGridLayoutBuilder are also for spacing, in this case thehorizontal and vertical spacing, respectively.</p><p>On line 289 we start adding views to the grid layout by addingsomething called glue. What is glue? It is basically a filler thattakes up space in the layout so that the views we care about arealigned properly. In this case I want the showScope checkbox alignedwith the menus of the menu fields below it. More glue is used below inthe vertical group layout to provide some space between the gridlayout, the divider, the play button and the bottom of the window. Thiskeeps things looking nice and also helps us maintain the look of theoriginal MidiPlayer GUI.</p><p>The other arguments to the Add() method for the BGridLayoutBuilderis the column and row we want the given view to appear in. So from thisit can be seen that the glue is in column 0, row 0, the showScopecheckbox is in column 1, row 0, the reverb menu label is in column 0,row 1, etc. Speaking of the reverb menu item, we can see that there arespecial methods in the BMenuField class to produce separate layoutitems for the one view. This is an interesting aspect of the layoutsystem in that views that consist of different components can actuallyhave their separate sections managed individually by the layout system.For another example of this look at the code for the ActivityMonitor,which uses this technique for the graph and legend of the main activityview.</p><p>The final call to the group layout builder is SetInsets(), whichbasically is used to put some padding around the edge of the layout, inthe order of left, top, right, and bottom. Five pixels seems to be apretty standard choice for the insets. I could have used 8 pixels whichwould have been like what the original GUI had, but I think 5 is fine.</p><p>There were a few other code changes needed to get the final GUIshown in Figure 3. First the needed headers were added. Second theconstructor for the MidiPlayer window needed theB_AUTO_UPDATE_SIZE_LIMITS so that it gets resized automatically by thelayout system:</p><pre><font color="#303030"> 41 </font>MidiPlayerWindow::MidiPlayerWindow()<font color="#303030"> 42 </font> : BWindow(BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">1</font>, <font color="#806010">1</font>), <font color="#3080a0">"MidiPlayer"</font>, B_TITLED_WINDOW,<font color="#303030"> 43 </font> B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)</pre><p>Third the methods used to build the menu fields needed to be changedto use the simple layout system friendly contructor. Also any manuallylayout code was removed. So for example the CreateReverbMenu() waschanged so that this:</p><pre><font color="#303030">230 </font> reverbMenu = <font color="#506888">new</font> BMenuField(<font color="#303030">231 </font> BRect(<font color="#806010">0</font>, <font color="#806010">0</font>, <font color="#806010">128</font>, <font color="#806010">17</font>), <font color="#3080a0">"reverbMenu"</font>, <font color="#3080a0">"Reverb:"</font>, reverbPopUp,<font color="#303030">232 </font> B_FOLLOW_LEFT | B_FOLLOW_TOP);<font color="#303030">233 </font><font color="#303030">234 </font> reverbMenu->SetDivider(<font color="#806010">55</font>);<font color="#303030">235 </font> reverbMenu->ResizeToPreferred();</pre><p>became this:</p><pre><font color="#303030">235 </font> reverbMenu = <font color="#506888">new</font> BMenuField(<font color="#3080a0">"Reverb:"</font>, reverbPopUp, <font color="#3080a0">NULL</font>);</pre><p>A similar change was made for the CreateInputMenu() method.</p><p>Finally the constructor for the ScopeView was changed to make it abit wider to accomodate a size 18 font. This was the "cheap" way to doit but in this case it works fine. The "proper" way would be to add themethods needed by the layout system to tell the layout system what theminimum, preferred and maximum sizes would be for that view. For thisarticle I did not want to cover that but will probably go into it in afuture article on the layout system.</p><p>To see all of this updated code take a look at the MidiPlayersources which are in the Haiku repository at src/apps/midiplayer. Tosee the previous code go back to before revision 26408 when I submittedthese changes.</p><h3>Conclusion</h3><p>To get more ideas and tips on how to use the layout system untilmore documentation is written take a look at Ingo's test applicationfor the layout system, called LayoutTest1. The source for this is attests/kits/interface/layout/LayoutTest1.cpp and it can be tested inHaiku by adding the following line to your UserBuildConfig file:</p><p></p><pre>AddFilesToHaikuImage home config bin : LayoutTest1 ;</pre><p>It can then be run either from Tracker from /boot/home/config/bin orby running it from Terminal. The code also has various examples of howto build a GUI with the layout system, sometimes using builders andsometimes not, depending on what is appropriate.</p><p>In addition the code for all the layout classes is in the HaikuInterface Kit, so for those of you who really want to dig into it, takea look at the Interface Kit headers in headers/os/interface and theimplementation in src/kits/interface and src/kits/interface/layouter.</p><p>Finally a warning: because these classes are new and untested fromthe perspective of an API, they are considered a private API and fornow should only be used inside Haiku core code, such as the includedapplications or preference applets. This is because the API mightchange or need to be tweaked and we would not want to break otherpeople's code (we can fix broken code inside the Haiku repositoryourselves.) So just keep that in mind and use the layout system classesat the risk of having your code broken.</p></div> </div></div> </div><!-- <div class="terms"> Array </div> --> <div class="links"> <ul class="links inline"><li class="comment_add first last"><span class="comment-node-item"><a href="http://www.haiku-os.org/comment/reply/2220#comment-form" title="Share your thoughts and opinions related to this posting.">Add new comment</a></span></li></ul> </div> </div><!-- /#node-2220 --><div id="comments" class="block rounded-block"> <div class="rounded-outside"> <div class="rounded-inside"> <p class="rounded-topspace"></p> <div class="comments-block-icon pngfix"></div> <h2 class="comments">Comments</h2> <a id="comment-9401"></a><!-- start comment.tpl.php --><div class="comment odd clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9401" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/bdifferent" title="View user profile.">BDifferent</a></span> - <span class="comment-date">2008-07-15 08:58</span> </div> <div class="content"> <p>Hi Ryan,</p><p>thank you for this helpful introduction!<br>I am looking forward to the next part of your tutorial.</p><p>Greetings<br>Finn</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9401">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9401?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-9403"></a><!-- start comment.tpl.php --><div class="comment even clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9403" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/bipolar" title="View user profile.">BiPolar</a></span> - <span class="comment-date">2008-07-15 13:14</span> </div> <div class="content"> <p>Nice article, indeed. Already looking forward for the rest!<br>Thank you very much Ryan.</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9403">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9403?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-9410"></a><!-- start comment.tpl.php --><div class="comment odd clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9410" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/mauro" title="View user profile.">Mauro</a></span> - <span class="comment-date">2008-07-16 13:24</span> </div> <div class="content"> <p>Nice howto!</p><p>The layout system is a very welcome addition to the API!<br>Thanks for laying out how to use it.</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9410">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9410?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-9543"></a><!-- start comment.tpl.php --><div class="comment even clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9543" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/nutela" title="View user profile.">nutela</a></span> - <span class="comment-date">2008-08-07 09:24</span> </div> <div class="content"> <p>Not a mention of the layout solver which was donated to Haiku? Or am I mixing things up?</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9543">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9543?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-9550"></a><!-- start comment.tpl.php --><div class="comment odd clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9550" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/humdinger" title="View user profile.">Humdinger</a></span> - <span class="comment-date">2008-08-07 17:50</span> </div> <div class="content"> <p>Do you mean ALM? I quote from the article:</p><p><cite>"ALM stands for Auckland Layout Model, which is a new kindof layout invented by Christof at The University of Auckland. Moreinformation about ALM can be read on its SourceForge project page. Isuspect I will dig into this layout more in the future and may dedicatean entire article to it."</cite></p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9550">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9550?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-9554"></a><!-- start comment.tpl.php --><div class="comment even clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-9554" class="active">Re: Laying It All Out, Part 1</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/nutela" title="View user profile.">nutela</a></span> - <span class="comment-date">2008-08-08 10:43</span> </div> <div class="content"> <p>Yes could be, it was a linear solver IIRC, it came up in one of the Haiku the mailing lists.</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/9554">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/9554?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-12247"></a><!-- start comment.tpl.php --><div class="comment odd clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-12247" class="active">i hope the api will change!!!!</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/paradoxon" title="View user profile.">Paradoxon</a></span> - <span class="comment-date">2009-09-15 07:28</span> </div> <div class="content"> <p>Reallyhelpfull tutorial because without this tutorial its unbelievable hardto understand this api. Also with this tutorial it made my sooo mad.</p><p>In my oppinon the layout api is not really BeOS/Haiku like.</p><p>It took me 2 days just to bring my Config dialog to the layoutsystem and the layoutstuff never acted like expected.</p><p>And the most big problem is this the limitation that the Window andall added views down to the one you want to layout, need to have alayout added!! So now my Config dialog have more layout code in it likebefore.<br>It makes really no sence when you just cant add a layoutet View to a other View wich isnt layouted.</p><p>Nice example of good working layout and api is the java layoutsystem. (No need of Layoutitems no need of two different concepts likelayoutmanager class and layout class what the heck is the sencetherefore???? except design patterns... ) It works just on every "View"in Java. </p><p>I think haiku missed a real opportunity ... at least for me.</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/12247">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/12247?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --><a id="comment-12680"></a><!-- start comment.tpl.php --><div class="comment even comment-by-author clear-block"> <h3 class="title"><a href="http://www.haiku-os.org/documents/dev/laying_it_all_out_part_1#comment-12680" class="active">Re: i hope the api will change!!!!</a></h3> <div class="submitted"> by <span class="comment-name"><a href="http://www.haiku-os.org/user/leavengood" title="View user profile.">leavengood</a></span> - <span class="comment-date">2009-09-28 21:51</span> </div> <div class="content"> <div class="quote-msg"><div class="quote-author"><em>Paradoxon</em> wrote:</div><p>Nice example of good working layout and api is the java layoutsystem. (No need of Layoutitems no need of two different concepts likelayoutmanager class and layout class what the heck is the sencetherefore???? except design patterns... ) It works just on every "View"in Java.</p></div><p>Java does in fact have layout managers and their API is just ascomplicated as ours. As far I know every Java window has a defaultlayout manager (BorderLayout) which is why it seems like it just works.Haiku cannot have the layout system on by default because of the BeOScompatibility and because some people may want to do manual layout.</p><p>Also a lot of the design of Haiku's layout API comes from Qt, which most people seem to find to be a good API.</p><p>With that said, the Haiku layout API is not perfect and in additionit is experimental and may change in the future. If you have morespecific feedback as to what could be improved, please do tell.</p> </div> <div class="links"> <ul class="links"><li class="comment_reply first"><a href="http://www.haiku-os.org/comment/reply/2220/12680">reply</a></li><li class="quote last"><a href="http://www.haiku-os.org/comment/reply/2220/12680?quote=1#comment-form" title="Quote this post in your reply.">quote</a></li></ul> </div> </div><!-- /end comment.tpl.php --> <p class="rounded-bottomspace"></p> </div> </div> <div class="rounded-block-bottom-left"></div> <div class="rounded-block-bottom-right"></div></div> </div> </div><!-- /content-inner --> </div><!-- /content --> </div><!-- /content-wrapper --> </div><!-- /main-wrapper --> <div id="footer" class="clearfix"> <p>Copyright 2001 - 2009 Haiku Inc. — Haiku and the Haiku logo are trademarks of <a href="http://www.haiku-os.org/about/haiku_inc">Haiku Inc.</a></p><p class="icon-feed"><a href="http://www.haiku-os.org/rss.xml">Latest News</a> | <a href="http://www.haiku-os.org/blog/feed">Haiku Blog-O-Sphere</a> | <a href="http://www.haiku-os.org/aggregator/rss/4">Development Aggregator</a></p> </div><!-- /footer --> </div><!-- /main --> </div><!-- /page --> <script type="text/javascript" src="laying_it_all_out_part_1_files/googleanalytics.js"></script><script type="text/javascript"><!--//--><![CDATA[//><!--var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));//--><!]]></script><script src="laying_it_all_out_part_1_files/ga.js" type="text/javascript"></script><script type="text/javascript"><!--//--><![CDATA[//><!--try{var pageTracker = _gat._getTracker("UA-3091150-1");pageTracker._trackPageview();} catch(err) {}//--><!]]></script><div id="legal-notice">Theme provided by <a target="_blank" class="ext" href="http://www.acquia.com/">Acquia, Inc.</a><span class="ext"></span> under GPL license from TopNotchThemes <a target="_blank" class="ext" href="http://www.topnotchthemes.com/">Drupal themes</a><span class="ext"></span></div> <div id="overlay" style="display: none;"></div> <div id="lightbox" style="display: none;"> <div style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="outerImageContainer"><div id="modalContainer" style="padding: 10px; display: none;"></div><div id="frameContainer" style="padding: 10px; display: none;"></div><div id="imageContainer" style="padding: 10px; display: none;"><img id="lightboxImage"><div id="hoverNav"><a style="padding-top: 10px;" id="prevLink" href="#"></a><a style="padding-top: 10px;" id="nextLink" href="#"></a></div></div><div id="loading"><a href="#" id="loadingLink"></a></div></div> <div style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="imageDataContainer" class="clearfix"> <div id="imageData"><div id="frameHoverNav"><a style="padding-top: 10px;" id="framePrevLink" href="#"></a><a style="padding-top: 10px;" id="frameNextLink" href="#"></a></div><div id="imageDetails"><span id="caption"></span><span id="numberDisplay"></span></div><div id="bottomNav"><a style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" id="bottomNavClose" href="#"></a><a id="bottomNavZoom" href="#"></a><a id="bottomNavZoomOut" href="#"></a><a id="lightshowPause" href="#" style="display: none;"></a><a id="lightshowPlay" href="#" style="display: none;"></a></div></div> </div> </div></body></html>