Silverfrost Forums

Welcome to our forums

Ganged buttons

6 Jul 2016 6:23 #17749

The following code represents a trivial example of ganging some radio buttons.

WINAPP
PROGRAM p
  USE clrwin, ONLY: winio@
  INTEGER, PARAMETER :: n=3
  INTEGER, DIMENSION(n) :: irbs
  CHARACTER(LEN=1), DIMENSION(n) :: crbs= (/'A','B','C'/)
  INTEGER :: iw

  irbs(1)=1
  irbs(2:)=0
  iw=winio@('%3`ga&',irbs(1),irbs(2),irbs(3))
  DO i=1,n
     iw=winio@('%nl%rb@&',crbs(i),irbs(i))
  END DO
  iw=winio@('%ff')

END PROGRAM p

Although everything works, the format of line 11 is proving to be very restrictive. If line 11 could be changed so that the argument to %ga is an array I think it would become much more flexible. For example, it would be very helpful if line 11 could be written as:

iw=winio@('%3`ga&',irbs(1:n))

In this format it would be easier to convert the code above to a subroutine that would gang a set of n buttons where n is passed as an argument. (The '3' after the % sign could easily be coded to the correct number, of course.) Right now my subroutine has to look something like the following:

SELECT CASE (n)
   CASE (2)
     iw=winio@('%2`ga&',irbs(1),irbs(2))
   CASE (3)
     iw=winio@('%3`ga&',irbs(1),irbs(2),irbs(3))
   CASE (4)
     iw=winio@('%4`ga&',irbs(1),irbs(2),irbs(3),irbs(4))
     ...

Would it be possible to get %ga to accept an array argument instead of individual scalars? Or am I missing a more obvious way to do this?

7 Jul 2016 6:50 #17750

OK. This has been added via a tilda modifier so that you will be able to write...

WINAPP 
PROGRAM p 
  INTEGER, PARAMETER :: n=3 
  INTEGER, DIMENSION(n) :: irbs 
  CHARACTER(LEN=1), DIMENSION(n) :: crbs = (/'A','B','C'/) 
  INTEGER :: iw,winio@ 
  irbs = 0
  irbs(1)=1 
  iw=winio@('%3`~ga&',irbs) 
  DO i=1,n 
     iw=winio@('%nl%rb@&',crbs(i),irbs(i)) 
  END DO 
  iw=winio@('%ff') 
END PROGRAM p 
8 Jul 2016 2:02 #17755

That is a very helpful addition, and one might say an 'obvious' one to implement.

The job would be complete if the N in %Nga was also allowed to be defined as a parameter.

I often find it useful to have all the state codes in an integer array, for example grey codes.

9 Jul 2016 12:10 #17760

Of course you can already do this in a slightly devious way

WINAPP 
PROGRAM p 
  INTEGER, PARAMETER :: n=3 
  INTEGER, DIMENSION(n) :: irbs 
  CHARACTER(LEN=1), DIMENSION(n) :: crbs = (/'A','B','C'/) 
  INTEGER :: iw,winio@ 
  irbs = 0 
  irbs(1)=1 
  do I=2,n
    iw=winio@('%2`ga&',irbs(I-1),irbs(I)) 
  enddo
  DO i=1,n 
     iw=winio@('%nl%rb@&',crbs(i),irbs(i)) 
  END DO 
  iw=winio@('%ff') 
END PROGRAM p 

As it says in the documentation 'However, it is unusual for a variable to appear in more than one %ga format for a given window. If it does then there must only be one variable that is common and the effect is to merge the two gang sets. If the grave accent is used on one of the gangs then it must be used on both.' Ian

9 Jul 2016 12:24 #17761

Good idea there, Ian, and I have to say that to conform to a Windows style guide, all radio buttons should be present at all times, with the inactive ones greyed out. That simplifies dialog box layout.

Eddie

9 Jul 2016 3:13 #17765

This is the code. The * is already available. The ~ will be in the next release. As a general principle these sizes (after % and before the two letter format code) can be replaced by * provided an extra argument (or two for .) is supplied at the corresponding point.

WINAPP 
PROGRAM p 
  INTEGER, PARAMETER :: n=3 
  INTEGER, DIMENSION(n) :: irbs 
  CHARACTER(LEN=1), DIMENSION(n) :: crbs = (/'A','B','C'/) 
  INTEGER :: iw,winio@ 
  irbs = 0 
  irbs(1)=1 
  iw=winio@('%*`~ga&',n,irbs) 
  DO i=1,n 
     iw=winio@('%nl%rb@&',crbs(i),irbs(i)) 
  END DO 
  iw=winio@('%ff') 
END PROGRAM p
9 Jul 2016 3:15 #17766

I should have realised that from previous posts.

9 Jul 2016 5:49 #17768

This is great. Thanks to all.

16 Jul 2016 5:50 #17798

The character '' in the code '%`~ga&'.

24 Aug 2016 4:52 #17900

Thanks again for setting that up, Paul. Would it be possible to do something similar with %*ps?

24 Aug 2016 5:55 #17901

It should work already. This is a general feature that should work whenever one or two integers come before the two letter format code.

28 Aug 2016 9:39 #17924

Sorry - I should have been clearer. I meant would it be possible to get %*ps to accept an array as its argument?

29 Aug 2016 8:19 #17927

OK. I have now added a tilda modifier to %ps for the next release.

21 Apr 2017 9:16 #19449

... I am finding this enhancement so useful, I would like to ask Paul to do even more work! Could you do something similar for %Ntl, Paul; i.e., allow the list of tab positions to be an array? The * for N seems to work already.

22 Apr 2017 6:01 #19450

I have made a note of this request.

22 Apr 2017 10:44 #19453

A tilda modifier has now been added to %tl for the next release.

27 Apr 2017 3:36 #19469

Regarding Paul's comment about the * modifier in:

  iw=winio@('%*`~ga&',n,irbs)

I find that this works ok with FTN95, but I get the following ClearWin+ error message when using a third-party compiler: winio@ failed to match format length. Is that perhaps because it is not implemented in the 64-bit version?

27 Apr 2017 6:20 #19472

Not exactly. It has been implemented in clearwin64.dll but it might not work for third-party compilers.

ClearWin+ has an alternative calling mechanism for winio$ and third-party compilers because winio$ and winio@ can take a variable list of arguments. FTN95 passes information about this list but third-party compilers don't. So for third-party compilers, ClearWin+ peeks into the format string in order to work out the argument list before going on to process it in the normal way.

It is possible that the process of peeking needs to be fixed. I will make a note of this.

27 Apr 2017 7:00 #19474

I have had a quick look and I can't see anything wrong here. Can you provide a short program that illustrates the failure?

7 May 2017 3:29 #19587

Here is an example using the * modifier with %tl that crashes with Nagfor, but works in FTN95:

Program p
  Use clrwin$, Only: winio$
  Integer :: iw
!
  iw = winio$('%ca@&', 'Test')
  iw = winio$('%*tl&', 1, 5)
  iw = winio$('A%taB')
End Program p
Please login to reply.