{"id":761,"date":"2011-05-18T20:20:01","date_gmt":"2011-05-19T01:20:01","guid":{"rendered":"http:\/\/anvil-of-time.com\/wordpress\/?p=761"},"modified":"2021-03-10T20:19:22","modified_gmt":"2021-03-11T01:19:22","slug":"powerbuilder-treeview-like-tooltips-for-datawindows","status":"publish","type":"post","link":"https:\/\/anvil-of-time.com\/powerbuilder\/powerbuilder-treeview-like-tooltips-for-datawindows\/","title":{"rendered":"PowerBuilder &#8211; Treeview like Tooltips for Datawindows"},"content":{"rendered":"<p>The treeview control has a very neat piece of functionality built in called Tooltips. When this property is checked your application will automatically display all the text on a treeview item if it is cut off by the edge of the control when the mouse pointer goes over that row. If the row text is not cut off, no tip, if it is, a tip displays. The following is an implementation of this type of functionality for datawindows. Although it is geared more towards grid type datawindows it could be used on others as well. This code is done in PB11.5, which has a tooltip property on datawindow columns, but the basic ideas can be adapted to earlier versions without this.<\/p>\n<p>The code is available here within an <a href=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/dwbubblehelp.zip\">Archive File<\/a> which also includes exports of the objects. Basically you will need to define the &#8216;mousemove&#8217; event on your datawindow control (mapped to pbm_dwnmousemove) along with an string instance variable that tracks which row\/column combination the mouse pointer is over. The instance variable is very important since it prevents the code from constantly being executed when the user keeps the pointer on the same row\/column. Within the mouse move the position and width of the datawindow object column being pointed to is compared to the width of the datawindow control and the position of the horizontal scrollbar. Left and Right positioning of the column is also taken into consideration. If the text in the pointed at column is not completely within the control, it it placed into the Tooltip Text of the column. All columns have Tooltips enabled so once the Tip text has a value, the tip appears.<\/p>\n<p>The code to derive the text and determine its length is encapsulated in an non visual object and uses a variety of API calls.<\/p>\n<p>The sample application datawindow has columns of all Edit types as well as a couple of computed columns. One periodic issue is with dropdown datawindows and listboxed which have &#8216;Display all columns&#8217; on. Another is with the &#8216;Always show arrow&#8217; option which sometimes keeps the tooltip coming on even though all the text is visible.<\/p>\n<p>Sample Screenshots:<br \/>\n<a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-01.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-763 size-full\" title=\"Left side bubblehelp\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-01.png\" alt=\"\" width=\"563\" height=\"304\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-01.png 563w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-01-300x161.png 300w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-01-150x80.png 150w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><br \/>\nThis shows the bubblehelp for a Checkbox column. If the column has three states the text will show either &#8216;On&#8217;, &#8216;Off&#8217;, or &#8216;Other&#8217;.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-02.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-764 size-full\" title=\"Bubblehelp on left side of datawindow conrol\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-02.png\" alt=\"\" width=\"563\" height=\"304\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-02.png 563w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-02-300x161.png 300w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-02-150x80.png 150w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><br \/>\nThis shows the right side of the datawindow control with no bubblehelp.<\/p>\n<p><a href=\"http:\/\/anvil-of-time.com\/wordpress\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-03.png\"><img loading=\"lazy\" class=\"aligncenter wp-image-765 size-full\" title=\"Bubblehelp on right of datawindow control\" src=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-03.png\" alt=\"\" width=\"571\" height=\"304\" srcset=\"https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-03.png 571w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-03-300x159.png 300w, https:\/\/anvil-of-time.com\/wp-content\/uploads\/2011\/05\/DW-bubblehelp-03-150x79.png 150w\" sizes=\"(max-width: 571px) 100vw, 571px\" \/><\/a><br \/>\nThis shows the bubblehelp on a computed column.<\/p>\n<p>At the bottom of the sample application are text boxes which display various position and size information which was useful in creating the checking logic. Since this is a grid datawindow you can re-order the columns as you wish. Also note the datawindow conrol can be resized which makes testing easier.<\/p>\n<p>Code from mousemove event<\/p>\n<pre name=\"code\" class=\"VB\">\/\/ listview tooltips functionality for datawindow\n\/\/\n\/\/ check to see if datawindow column text is cut off by either the size of the datawindow\n\/\/ control or the position of the horizontal scrollbar\n\/\/ if the text is cut off, put the text into the tooltip for the datawindow column so it\n\/\/ will display.\nLong    ll_hScrollPos, ll_width\nLong    ll_colX, ll_colW, ll_colXW, ll_textwidth\ndatawindow ldw\nstring ls_mod, ls_value, ls_err, ls_checkname, ls_oldcolname, ls_alignment\ns_dwbubble lstr_bubble\n\nldw = THIS\nIF  row &gt; 0 AND dwo.name &lt;&gt; &#039;datawindow&#039; THEN\n\tls_checkname = (dwo.Name  + &#039;\/&#039; + string(row))\n\t\/\/ only do this if mouse moved to new row\/column since last time\n\tIF(is_curcol &lt;&gt; ls_checkname) THEN\n\t\tIF Len(is_curcol) &gt; 0 THEN \/\/ blank out previous tip\n\t\t\tls_oldcolname = Left(is_curcol, Pos(is_curcol,&#039;\/&#039;) - 1)\n\t\t\tls_mod = ls_oldcolname + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\tls_err = this.modify(ls_mod)\n\t\tEND IF\n\t\tll_width = w_dwbubblehelp.dw_1.width\n\t\tll_hScrollPos = Long( THIS.Describe(&quot;DataWindow.HorizontalScrollPosition&quot;) )\n\t\tls_mod = dwo.name + &#039;.x&#039;\n\t\tll_colX = Long( THIS.Describe(ls_mod) )\n\t\tls_mod = dwo.name + &#039;.width&#039;\n\t\tll_colW = Long( this.Describe(ls_mod) )\n\t\tll_colXW = ll_colX + ll_colW\n\t\tIF ll_colXW &lt; ll_hScrollPos THEN\n\t\t\t \/\/ &quot;Not visible&quot;\n\t\tELSE\n\t\t\t IF ( ll_colX &lt; ll_hScrollPos ) AND ( ll_colXW &gt; ll_hScrollPos ) THEN\n\t\t\t\t \/\/ Partially Visible Left \n\t\t\t\t \/\/ get the text value and its length\n\t\t\t\tlstr_bubble = idw.uf_get_width_of_data(row, dwo.name, ldw, iw_parent)\n\t\t\t\tll_textwidth = lstr_bubble.i_width\n\t\t\t\tls_value = lstr_bubble.s_value\n\t\t\t\tls_mod = dwo.name + &#039;.Alignment&#039;\n\t\t\t\tls_alignment = this.describe(ls_mod)\n\t\t\t\tIF ls_alignment = &#039;1&#039; THEN \/\/ right alighment\n\t\t\t\t\tIF ll_textwidth &gt; ll_colw THEN \/\/ text wider than column\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSEIF ll_colXW - ll_textwidth &lt;  ll_hScrollPos THEN \n\t\t\t\t\t\t \/\/ text cut off by datawindow control or scrollbar\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSE\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tEND IF\n\t\t\t\tELSE \/\/ other alignments\n\t\t\t\t\tIF ll_textwidth &gt; ll_colw THEN\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSEIF ll_textwidth &gt; (ll_colXW - (ll_width + ll_hScrollPos)) THEN\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSE\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tEND IF\n\t\t\t\tEND IF\n\t\t\t\t  \n\t\t\tELSEIF (ll_colXW &gt;  ll_hScrollPos) AND (ll_colXW &gt; (ll_width + ll_hScrollPos) ) THEN \n\t\t\t\t\/\/ Partially Visible Right \n\t\t\t\t\/\/ get the text value and its length\n\t\t\t\tlstr_bubble = idw.uf_get_width_of_data(row, dwo.name, ldw, iw_parent)\n\t\t\t\tll_textwidth = lstr_bubble.i_width\n\t\t\t\tls_value = lstr_bubble.s_value\n\t\t\t\tls_mod = dwo.name + &#039;.Alignment&#039;\n\t\t\t\tls_alignment = this.describe(ls_mod)\n\t\t\t\tIF ls_alignment = &#039;0&#039; THEN \/\/ left alighment\n\t\t\t\t\tIF ll_textwidth &gt; ll_colw THEN \/\/ text wider than column\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSEIF ll_width + ll_hScrollPos - ll_colX &lt; ll_textwidth + Round((ll_textwidth \/ 10), 0) THEN  \n\t\t\t\t\t\t\/\/ text cut off by datawindow control or scrollbar\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSE\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tEND IF\n\t\t\t\tELSE\n\t\t\t\t\tIF ll_textwidth &gt; ll_colw THEN \/\/ text wider than column width\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSEIF ll_textwidth &gt; (ll_colW - (ll_width + ll_hScrollPos)) THEN \n\t\t\t\t\t\t\/\/ text cut off by datawindow control or scrollbar\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&#039; + ls_value + &#039;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tELSE\n\t\t\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t\t\tEND IF\n\t\t\t\tEND IF\n\t\t\t ELSE\n\t\t\t\t\/\/ &quot;Visible&quot;\t\t\t\n\t\t\t\t\/\/ this could be modifed for grid columns resized smaller than text value\n\t\t\t\tls_mod = dwo.name + &#039;.Tooltip.Tip = &quot;&quot;&#039;\n\t\t\t\tls_err = this.modify(ls_mod)\n\t\t\t END IF\n\t\tEND IF\n\tEND IF\t\n\tis_curcol = dwo.Name + &#039;\/&#039; + string(row)\nEND IF<\/pre>\n<p>Thanks to Adam Simmonds for his assistance on this.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The treeview control has a very neat piece of functionality built in called Tooltips. When this property is checked your application will automatically display all the text on a treeview item if it is cut off by the edge of the control when the mouse pointer goes over that row. If the row text is&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":[21,12,16,42],"_links":{"self":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/761"}],"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=761"}],"version-history":[{"count":9,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/761\/revisions"}],"predecessor-version":[{"id":1950,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/761\/revisions\/1950"}],"wp:attachment":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/media?parent=761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/categories?post=761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/tags?post=761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}