Silverfrost Forums

Welcome to our forums

Image Bar (%ib) buttons.

22 Jan 2008 12:54 #2685

It would be nice if there was an equivalent to ADJUST_IB_SIZES@ that allowed the positions of the buttons - ADJUST_IB_SIZES@ just changes their widths. Maybe ADJUST_IB_POSITIONS@ ? Failing this, can anyone advise me how to separate them into groups?

I have tried putting an inactive (STATUS_CONTROL = 3), narrow, button between active buttons (the callback intentionally does nothing), and this works, but a blank flat area would be nicer. If I draw a bitmap that looks like a separator (for example, with a colon or solidus), then to see it, the button has to be clickable.

I tried initially to space out the groups of image bar buttons using multiple %ib format codes on the same line. The problem is that when the window they are in is resized, all groups but the leftmost scoot off behind the leftmost group (the groups are 1 row deep, with several buttons in each group, as in:

xxx xxxx xxx in a line under the menu bar

… and it doesn’t seem to help putting them in a box (%ob … %cb) ).

Next, when a particular button is inactive (STATUS_CONTROL = 3) it appears as a grey rectangle. This isn’t particularly attractive, so I have concluded that it is better to arrange for the callback to do nothing rather than to “grey out” the image bar button if it isn’t supposed to be active.

Wouldn’t it be more logical if a raised image bar button was simply not pressable? I suppose that this would require more STATUS_CONTROL options. Here’s my list of what %ib buttons might need to look like in their “greyed” state:

  1. Button doesn’t show at all, isn’t pressable, and acts as a separator
  2. Button stays up always, isn’t pressable (greyed equivalent to status_control = 4)
  3. Button shows the image as greyed out (i.e. as if [flat] were to be selected) but does nothing if clicked.
  4. Button shows the bitmap (i.e. as if [coloured] were to be selected) but does nothing if clicked.

Perhaps c. and d. are the same as b. depending on what is selected in the [] in %ib[] - nothing, flat or coloured.

Or have I simply missed something listed in the chm or enh files?

Eddie

22 Jan 2008 1:32 #2686

I do not have time at the moment to check this out but there is an undocumented feature that may do the trick. Try putting %se between the groups...

winio@('%se', DEPTH) double precision DEPTH

%se is designed to function with %ib and %bx, in order to provide a grey line as a separator between buttons, this allows grouping of buttons. DEPTH is measured as a fraction of the character height and this amount is added to the height, one half above and one half below the buttons. Typically the same value as that specified with %bx but it can differ.There is no limit to how many times %se can be specified, however if it’s specified at the beginning it simply provides a space and no line.

24 Jan 2008 10:49 #2696

Thanks Paul, that's a really useful suggestion. I'll try it.

On the basis of further investigation, I see that my bitmaps weren't drawn in a way that meets the full requirements of %ib. Indeed, as I drew them in CorelDraw, and asked for them to be antialiased (which normally makes a better job of conversion of a vector image to bitmap), and CorelDRAW anti-aliased the edges, they were far from ideal.

A certain amount of trial and error has demonstrated (to me at least) that %ib works best for some very simple shapes - it can then automatically generate a reasonable greyed-out equivalent. However, unless the 1-pixel complete border is present, it assumes that the greyed out image is a simple dark grey rectangle. If the image is faily straighforward (for example, the 3 circles for Mickey Mouse) then the greyed out image is still recognizable. However, if the bitmap is carefully-crafted, and antialiased round the edges for maximum legibility at small size, then the greyed-out shape may not be so recognizable.

Eddie

25 Jan 2008 10:31 #2704

Hmmm... %se is obviously designed for vertical %ib toolbars, not horizontal ones (I suppose'depth' is a giveaway). If one divides a long horizontal %ib into 3 shorter ones with a %se in between each, then any window resize drives the two rightmost %ib arrays scurrying behind the leftmost - something that happens if one simply uses 'blanks' to space out the button bars. The depth variable creates an odd effect in the spacer.

E

26 Jan 2008 3:07 #2705

Have you tried experimenting with %ib for the first group of buttons, then %bm for a vertical bar bitmap and then a new %ib for the next group of buttons?

Alternatively you could start off with a text item (a pipe symbol say) for the vertical bar.

26 Jan 2008 3:32 #2706

%se appears to work well enough in the following sample...

WINAPP
  INTEGER winio@,i
  i=winio@('%ca[Image bar]%sy[3d]&')
  i=winio@('%bd&',0.0D0,0.0D0,0.5D0,1.0D0)
  i=winio@('%mn[File[Exit]]&','EXIT')
  i=winio@('%3ib[flat]&','cut/Cut',4,'CONTINUE','copy/Copy',4,'CONTINUE','paste/Paste',4,'CONTINUE')
  i=winio@('%se&',0.0D0)
  i=winio@('%3ib[flat]&','cut/Cut',4,'CONTINUE','copy/Copy',4,'CONTINUE', 'paste/Paste',4,'CONTINUE')
  i=winio@('%ff%gr[black]',300,200)
  
  END

  RESOURCES
  cut BITMAP cut.bmp
  copy BITMAP copy.bmp
  paste BITMAP paste.bmp
27 Jan 2008 6:30 #2707

Paul,

In reply to both of your posts, yes, I have tried dividing the image-bar into two with all manner of separators: characters, text, blanks, %gr regions etc etc. Yes, also, the code you posted works fine.

Now add a %ww, and a %pv for the %gr ... and what happens when you resize the window?

Answer: the rightmost %ib moves as the window is resized. If the resize is smaller, then the mobile %ib buttons scoot off and hide behind the leftmost (fixed) %ib content.

You don't get this behaviour if all the image buttons are defined in the same %ib format code, although this can make for a very complicated winio@ statement! It does mean also that the %se can't be usefully employed, and that the only effective separator is an inactive button.

Of course, anything can be used to divide up the buttons into groups in a fixed size window.

What about my suggestion of ADJUST_IB_POSITIONS@ ?

Best regards

Eddie

28 Jan 2008 7:45 #2708

After I switched off my PC I had a hunch that maybe %ap would do the trick. It does - for a fixed size window.

'Absolute Position' is also a bit of a misnomer. Absolute in x - yes, but when applied to the groups of %ib controls, y is relative to the first group.

Eddie

28 Jan 2008 8:32 #2709

I have not had time to think through your suggestion about 'Absolute Position'. It is not clear to me what you are asking for.

Regarding the unwanted movement of the second group of buttons, I could run some tests on this. You could try using %ob (without a border) in order to group the two sets of buttons in one box.

28 Jan 2008 2:13 #2711

Hi Paul,

Already tried the %ob - %cb. It moves with the righthand group(s) of %ib buttons.

Assuming that you meant my suggestion regarding 'adjust_ib_positions@', it is just this.

After one has created a set of %ib buttons, it is possible to call adjust_ib_widths@ (ixw, iyw, istatus) with istatus = 0 - which loads ixw and iyw with the width and height info for each button. One can then call adjust_ib_widths@ (ixw, iyw, istatus) a second time, this time with istatus NOT = 0, and with some revised values in ixw and iyw in order to change the width &/or height of the buttons.

My suggestion is to create a similar subroutine that returns the coordinates of the top left corner of each button - say in arrays jxw, jyw.

If one wanted a gap (say between buttons 3 and 4 of a 6-button group), one might add the necessary extra to jxw(4), (5) and (6), then call the routine with istatus NOT = 0, to set those coords. This would end up with an %ib containing 'gaps' - in this case between buttons 3 & 4.

I'm guessing now, but I imagine that the %ib group would still behave as a single entity during a window resize.

Regards

Eddie

29 Jan 2008 12:48 #2712

I have tried a few experiments but failed to get the desired effect with the current functionality of ClearWin+.

Given that %se is undocumented I can fix it so that it is anchored during a %pv resize. I can include this in the next release which hopefully will take place quite soon.

30 Jan 2008 7:57 #2717

Hmmm ... I thought I posted a reaction to this suggestion!

The idea of anchoring %se seems to me a good one, and as %se is undocumented, shouldn't cause any incompatabilities. I can't think of any reason why one would prefer the existing behaviour. Any chance of %se[flat] producting simply grey space?

clearwin_info@('BUTTON_NUMBER') returns the button number that caused the window to close (usual reason, a callback function returning zero). This button number is relative to the %ib format that contained the button. If one has multiple %ib formats (and it is difficult to imagine using %se without at least two %ib formats), there is no way of separating out which one 'did the deed' - that is, without maintaining a separate tracking system.

winio@ returns zero when a callback for %ib returns zero, so in any case, one needs such a separate tracking system to differentiate it from closure via clicking on the Close button top right of the caption bar.

Regards

Eddie

30 Jan 2008 12:10 #2718

I will see if [flat] can be implemented easily.

Changing the return from clearwin_info@('BUTTON_NUMBER') could break existing code but it may be a simple matter to provide an absolute number under a new clearwin_info@ parameter.

In the meantime, how about setting a marker on callbacks for the two %ib controls. The marker would be used to indicate which group was clicked on last.

30 Jan 2008 8:18 #2719

Hi Paul,

The returned button number isn't a problem for me, as I have no code that relies on looking for the button number, I was just trying to outguess other folks' potential problems,

Eddie

4 Feb 2008 9:44 #2734

A chance discovery ....

With %bx, groups of %ib buttons ARE locked in position, and simply a couple of blanks act as padding to separate them into groups. Without a %bx, all but the the leftmost group move on a window resize.

This is sufficiently different to %tb, where groups of buttons are *always *locked (whether or not you have a %bx) to have confused me for ages.

Perhaps the simplest solution is to put this in the documentation ...

Regards

Eddie

4 Feb 2008 10:24 #2738

OK thanks.

4 May 2008 11:15 #3144

Eddie,

I have recently had a battle with the positioning of window controls and so I've modified Paul's code a little to show positioning of %ib controls using GET_WINDOW_LOCATION@ & MOVE_WINDOW@.

A couple of problems to overcome first. The get_window_location@ actually returns the position of a control relative to the top left corner of the window, but the move_window@ is relative to the first pixel under the caption bar and to the right of the LH border. These of course vary with text size and windows style (standard or XP for example). It there is a %mn then it is the first pixel below the menu.

What I did, and there is probably a better way was to construct a dummy window on startup, which places a caption and a menu, followed by an %rd control. Using a %sc callback, which returns 0, closing the dummy window, I position the %rd to 0,0 and get its position. Add 1 to the x & y positions and use this as the offset from the top of the overall window. Subsequently the get_real_control_location routine simply subtracts these from the get_window_location@ positions to get a location relative to the first usable space. This can then be used to set the %ib or any other control to a new location. After a window resize, the overall window size could be adjusted to account for any dramatic repositioning of controls that you have carried out.

I know it is a bit long winded, but it might help.

Paul, Is there any way to get the locations relative to the same point that move_window@ uses?

Regards

Ian

WINAPP 
  include <windows.ins>

  INTEGER i,iresize,iget_offsets,imove_ib2
  external iresize,iget_offsets,imove_ib2
  common/window_things/ihandle_window,ihandle_ib1,ihandle_ib2,ihandle_tt 
  common/window_offset/ixoffset,iyoffset
!dummy window
  i=winio@('%ca[dummy]&')
  i=winio@('%mn[File[Exit]]&','EXIT')                  !include this line only if real window is to contain a menu
  i=winio@('%rd%lc%sc',i,ihandle_window,iget_offsets)

! real window
  i=winio@('%ca[Image bar]%ww%bg[btnface]%hw&',ihandle_window) 
  i=winio@('%bd&',0.0D0,0.0D0,0.5D0,1.0D0) 
  i=winio@('%mn[File[Exit]]&','EXIT') 
  i=winio@('%3ib[flat]&','cut/Cut',4,'CONTINUE','copy/Copy',4,'CONTINUE','paste/Paste',4,'CONTINUE') 
  i=winio@('%lc&',ihandle_ib1) 
  i=winio@('%se&',0.0D0) 
  i=winio@('%3ib[flat]&','cut/Cut',4,'CONTINUE','copy/Copy',4,'CONTINUE', 'paste/Paste',4,'CONTINUE') 
  i=winio@('%lc&',ihandle_ib2) 
  i=winio@('%ff%^tt[Move IB2]&',imove_ib2) 
  i=winio@('%lc&',ihandle_tt) 
  i=winio@('%ff%pv%^gr[black,user_resize]',300,200,iresize) 
  
  END 


  integer*4 function iresize()
  include <windows.ins>
  common/window_things/ihandle_window,ihandle_ib1,ihandle_ib2,ihandle_tt 
! get new position & size of overall window
  call get_real_control_location(ihandle_window,ix,iy,iw,ih)
  print *,'window',ix,iy,iw,ih
! get new position & size of first ib block
  call get_real_control_location(ihandle_ib1,ix,iy,iw,ih)
  print *,'ib 1  ',ix,iy,iw,ih
! get new position & size of second ib block
  call get_real_control_location(ihandle_ib2,ix,iy,iw,ih)
  print *,'ib 2  ',ix,iy,iw,ih
! get new position & size of text button
  call get_real_control_location(ihandle_tt,ix,iy,iw,ih)
  print *,'tt    ',ix,iy,iw,ih

  iresize = 1
  end

! get initial offsets using dummy window
  integer*4 function iget_offsets()
  include <windows.ins>
  common/window_things/ihandle_window,ihandle_ib1,ihandle_ib2,ihandle_tt 
  common/window_offset/ixoffset,iyoffset
! set the %rd pixel location to zero,zero
  call MOVE_WINDOW@( ihandle_window, 0,0)

  call GET_WINDOW_LOCATION@( ihandle_window, ixoffset, iyoffset, iw, ih)
  ixoffset = ixoffset + 1
  iyoffset = iyoffset + 1
  print *,ixoffset, iyoffset
  iget_offsets = 0
  end


! move the second %ib block
  integer*4 function imove_ib2()
  include <windows.ins>
  common/window_things/ihandle_window,ihandle_ib1,ihandle_ib2,ihandle_tt 
  common/window_offset/ixoffset,iyoffset
  call get_real_control_location(ihandle_ib2, ix, iy, iw, iw)
  ix = ix + 2
  call MOVE_WINDOW@( ihandle_ib2, ix, iy)
  imove_ib2 = 1
  end

!fix returned locations
  subroutine get_real_control_location(ihandle,ix,iy,iw,ih)
  include <windows.ins>
  common/window_offset/ixoffset,iyoffset
  call GET_WINDOW_LOCATION@( ihandle, ix, iy, iw,ih)
  ix = ix - ixoffset
  iy = iy - iyoffset
  end



  RESOURCES 
  cut BITMAP cut.bmp 
  copy BITMAP copy.bmp 
  paste BITMAP paste.bmp
12 May 2008 1:10 #3176

Hi Ian,

A very elegant solution, and very timely because of the post by Catherine Rees Lay in the other forum. Your code there isn't truncated.

I eventually discovered %bx, which locks the second %ib into a fixed position. If one puts i=winio@('%ib&',0.0D0) into your code, for instance, the coords of ib2 don't alter when the window is resized.

As written, if one resizes the window, so that ib2 scoots off behind ib1, so too does the %se separator, so presumably that needs to be resurrected in the right position too.

Regards

Eddie

Please login to reply.