{"id":1409,"date":"2012-06-27T18:14:22","date_gmt":"2012-06-27T23:14:22","guid":{"rendered":"http:\/\/anvil-of-time.com\/wordpress\/?p=1409"},"modified":"2021-03-11T12:32:43","modified_gmt":"2021-03-11T17:32:43","slug":"powerbuilder-gotcha-grid-datawindows-with-picture-controls","status":"publish","type":"post","link":"https:\/\/anvil-of-time.com\/powerbuilder\/powerbuilder-gotcha-grid-datawindows-with-picture-controls\/","title":{"rendered":"PowerBuilder &#8216;Gotcha&#8217; &#8211; Grid Datawindows with Picture Controls"},"content":{"rendered":"<p>So I&#8217;m working on a &#8216;dashboard&#8217; style datawindow in an application which shows a grid of data along with some graphics so the user can easily see changes\/important stuff. There are a number of reasons to use a grid datawindow for this, especially since they can easily be changed by the user to suit their particular tastes and preferences. Since the individual columns can be resized by the user, I can&#8217;t use the &#8216;display as bitmap&#8217; option on a column to display my graphics since they can be resized which screws up the image on the datawindow. Fine, I&#8217;ll use picture objects placed on the individual columns and then use expressions to control the positioning of them automatically. Gee, isn&#8217;t PowerBuilder great?<\/p>\n<p>Now in my particular situation I have a series of picture objects placed on a column with the value of the column itself determining which of them is visible. This is standard stuff achieved via an expression on the visual property of the picture objects . The next thing to do is to set the X position on the picture objects based on the column it is placed upon; I&#8217;d like the position of the picture to change dynamically as the column itself changes due to the user dragging the column to a different position or if they make it larger\/smaller in width. So far, so good &#8211; I&#8217;m starting to count my chickens&#8230;<\/p>\n<p>I fire up the app and &#8216;<a href=\"http:\/\/www.sadtrombone.com\/\" target=\"_blank\" rel=\"noopener\">wha, wha, wha, wha, whaaaa&#8230;<\/a>&#8216;.<\/p>\n<p>Here is the application when I launch it.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid000.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1415 size-full\" title=\"grid000\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid000.png\" alt=\"\" width=\"309\" height=\"560\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid000.png 309w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid000-165x300.png 165w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid000-82x150.png 82w\" sizes=\"(max-width: 309px) 100vw, 309px\" \/><\/a><\/p>\n<p>Looks fine, my visible expressions are correct.<\/p>\n<p>I resize the Mood column to make it larger and&#8230;<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid001.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1416 size-full\" title=\"grid001\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001.png\" alt=\"\" width=\"303\" height=\"303\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001.png 303w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001-150x150.png 150w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001-300x300.png 300w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001-100x100.png 100w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid001-120x120.png 120w\" sizes=\"(max-width: 303px) 100vw, 303px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid002.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1417 size-full\" title=\"grid002\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid002.png\" alt=\"\" width=\"129\" height=\"213\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid002.png 129w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid002-90x150.png 90w\" sizes=\"(max-width: 129px) 100vw, 129px\" \/><\/a><\/p>\n<p>Something&#8217;s not working as expected.<\/p>\n<p>Okay, lets try re-arranging the columns by dragging Name after Mood.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid003.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1418 size-full\" title=\"grid003\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid003.png\" alt=\"\" width=\"299\" height=\"313\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid003.png 299w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid003-286x300.png 286w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid003-143x150.png 143w\" sizes=\"(max-width: 299px) 100vw, 299px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid004.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1419 size-full\" title=\"grid004\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid004.png\" alt=\"\" width=\"257\" height=\"215\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid004.png 257w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid004-150x125.png 150w\" sizes=\"(max-width: 257px) 100vw, 257px\" \/><\/a><\/p>\n<p>Well this sucks, grrrr&#8230;.<\/p>\n<p>What happens if I make the Mood column smaller?<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid005.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1420 size-full\" title=\"grid005\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid005.png\" alt=\"\" width=\"218\" height=\"279\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid005.png 218w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid005-117x150.png 117w\" sizes=\"(max-width: 218px) 100vw, 218px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid006.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1421 size-full\" title=\"grid006\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid006.png\" alt=\"\" width=\"100\" height=\"217\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid006.png 100w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid006-69x150.png 69w\" sizes=\"(max-width: 100px) 100vw, 100px\" \/><\/a><\/p>\n<p>Sigh.<br \/>\nOkay boss, when is the deadline for this?<\/p>\n<p>First let&#8217;s tackle the positioning issue. To make the expressions on the pictures work correctly, each has to be unique. So these expressions will not work:<\/p>\n<pre name=\"code\" class=\"VB\">long(describe(&quot;custmood.X&quot;)) + 100\nlong(describe(&quot;custmood.X&quot;)) + 100\nlong(describe(&quot;custmood.X&quot;)) + 100<\/pre>\n<p>These are the X position expression for my three picture objects on the datawindow column. To make them unique I change them to:<\/p>\n<pre name=\"code\" class=\"VB\">long(describe(&quot;custmood.X&quot;)) + 100 \/\/ p_1.X\nlong(describe(&quot;custmood.X&quot;)) + 100 + 0 \/\/ p_2.X\nlong(describe(&quot;custmood.X&quot;)) + 100 * 1 \/\/ p_3.X<\/pre>\n<p>Note also that &#8216;+ 100&#8217; is different from &#8216;+100&#8217; as far as this goes<\/p>\n<p>Now when I run the app and I change the order of the columns in the grid I get:<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid012.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1427 size-full\" title=\"grid012\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid012.png\" alt=\"\" width=\"235\" height=\"230\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid012.png 235w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid012-150x146.png 150w\" sizes=\"(max-width: 235px) 100vw, 235px\" \/><\/a><\/p>\n<p>Moving Name to after Mood.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid013.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1410 size-full\" title=\"grid013\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid013.png\" alt=\"\" width=\"211\" height=\"214\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid013.png 211w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid013-147x150.png 147w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid013-100x100.png 100w\" sizes=\"(max-width: 211px) 100vw, 211px\" \/><\/a><br \/>\nCool<\/p>\n<p>One thing of note. If you are going to use a Modify to change the X position expressions at runtime rather than within the datawindow definition, each of the &#8216;New&#8217; expressions must be different from those in the original. Thanks to my manager Robert Sisk for this tidbit.<\/p>\n<p>The second issue is a bit trickier and is one I&#8217;ve encountered at various times in my PB career. You can look and look and look online for answers to this and find either nothing or many suggestions which don&#8217;t work too well. Often you are faced with preventing the user from resizing the column which eliminates one of the main reasons you choose the grid datawindow in the first place.<\/p>\n<p>Since we are dealing with controls which we have created in the datawindow painter to be the size we want them to be when they appear to the user, all we have to do is capture their widths and then re-apply them once the user has resized the columns on the datawindow. However, we have to create a user event on the datawindow to do this since there is no standard event which is triggered when the user resizes a grid column.<\/p>\n<p>First define an instance variable to hold the modify information on the picture objects for the datawindow.<br \/>\nNext capture the initial values of the widths of the picture objects once the window opens; a &#8216;post open&#8217; style event is good for this. If your application dynamically changes these for some reason during run time, you will have to reset this after the change so the property is set to the correct value.<br \/>\nDefine a user event on the datawindow in question which will perform the modify on the picture objects.<br \/>\nDefine a user event mapped to pbm_dwnlbuttonup which will post the first user event. This event is triggered when a user releases the left mouse button on the datawindow (which happens when the are finished resizing the column).<\/p>\n<pre name=\"code\" class=\"VB\">\/\/instance var and postopen event\ntype variables\nstring is_picture_widths\nend variables\n\nevent we_postopen();\/\/ triggered from open of window\nstring ls_objects, ls_object, ls_type\nlong ll_col_pos, ll_col_start, ll_len\n\/\/ load picture settings to instance variable\nls_objects = dw_1.Object.DataWindow.Objects\n\/\/ go through tab separated list\nll_col_pos = pos(ls_objects, &#039;~t&#039;)\nll_col_start = 1\nll_len = len(ls_objects)\nDO WHILE ll_col_start &lt; ll_len\n\tls_object = mid(ls_objects, ll_col_start, ll_col_pos - ll_col_start)\n\tls_type = dw_1.describe(ls_object + &#039;.type&#039;)\n\tIF  ls_type = &#039;bitmap&#039; then \/\/only concerned about bitmaps (picture objects)\n\t\tis_picture_widths += ls_object + &#039;.width = &#039; + dw_1.describe(ls_object + &#039;.width&#039;) + &#039;~r&#039;\n\tEND IF\t\t\t\t\t\n\tll_col_start = ll_col_pos + 1\n\tll_col_pos = pos(ls_objects, &#039;~t&#039;, ll_col_start)\n\tIF ll_col_pos = 0 then\n\t\tll_col_pos = ll_len + 1\n\tEND IF\nLOOP\nend event\n\nevent ue_lbuttonup;\/\/ call event to resize pictures if needed, mapped to PBM_DWNLBUTTONUP on datawindow\nthis.setredraw(FALSE)\nthis.event post ue_checkmodified()\nend event\n\nevent ue_checkmodified();\/\/ posted from ue_lbuttonup\nstring ls_mess\n\nIF this.object.datawindow.syntax.modified = &quot;yes&quot; THEN\n\tls_mess = modify(is_picture_widths) \/\/ re apply the picture widths\n\tIF Len(ls_mess) &gt; 0 THEN\n\t\t\/\/ error condition\n\tEND IF\nEND IF\nsetredraw(true) \/\/was set to false in calling event\nend event<\/pre>\n<p>So now when run the application we get this.<\/p>\n<p>Resize the column with the picture controls<br \/>\n<a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid008.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1423 size-full\" title=\"grid008\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid008.png\" alt=\"\" width=\"291\" height=\"310\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid008.png 291w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid008-281x300.png 281w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid008-140x150.png 140w\" sizes=\"(max-width: 291px) 100vw, 291px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid009.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1424 size-full\" title=\"grid009\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid009.png\" alt=\"\" width=\"170\" height=\"221\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid009.png 170w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid009-115x150.png 115w\" sizes=\"(max-width: 170px) 100vw, 170px\" \/><\/a><\/p>\n<p>Now make it smaller.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid010.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1425 size-full\" title=\"grid010\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid010.png\" alt=\"\" width=\"121\" height=\"249\" \/><\/a><\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid011.png\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-1426\" title=\"grid011\" src=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid011.png\" alt=\"\" width=\"92\" height=\"221\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid011.png 92w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid011-62x150.png 62w\" sizes=\"(max-width: 92px) 100vw, 92px\" \/><\/a><\/p>\n<p>Ahhhh, all is good again.<\/p>\n<p>I&#8217;ve attached a <a href=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/gridbitmaps.zip\">sample application<\/a> (PB12.5.1) demonstrating how the resizing does not work and how it can be corrected. Exports of the objects are included as well if you need to create your own version. When running the example, first resize\/reposition the columns after the window opens. This will show the problems with the picture objects. When you click on the &#8216;Modify Bitmap X Expressions&#8217; button the changes in the X position expressions for the picture objects will be displayed in the multi line edit control.<br \/>\n<a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2012\/06\/grid007.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-1422 size-full\" title=\"grid007\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid007.png\" alt=\"\" width=\"307\" height=\"521\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid007.png 307w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid007-176x300.png 176w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2012\/06\/grid007-88x150.png 88w\" sizes=\"(max-width: 307px) 100vw, 307px\" \/><\/a><\/p>\n<p>The &#8216;Reset DWO&#8217; button resets the datawindow object if you need to.<br \/>\n<a style=\"display: none;\" href=\"http:\/\/www.codeproject.com\" rel=\"tag\">CodeProject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>So I&#8217;m working on a &#8216;dashboard&#8217; style datawindow in an application which shows a grid of data along with some graphics so the user can easily see changes\/important stuff. There are a number of reasons to use a grid datawindow for this, especially since they can easily be changed by the user to suit their&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,10],"tags":[37,21,12,16],"_links":{"self":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/1409"}],"collection":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/comments?post=1409"}],"version-history":[{"count":9,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/1409\/revisions"}],"predecessor-version":[{"id":2044,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/1409\/revisions\/2044"}],"wp:attachment":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/media?parent=1409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/categories?post=1409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/tags?post=1409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}