Converting text viewport position to graphics units?

Discussions related to mouse, keyboard, fonts and Graphical User Interface
MrHiggins
Posts: 19
Joined: Wed 28 Jul 2021, 13:29

Converting text viewport position to graphics units?

Post by MrHiggins »

Hi,

When working with WINLIB5 what is the best way of aligning the text position in the viewport to the graphics position? For example creating an edit box and aligning some text to the left or above of it?

I've come up with these to help me:-

Code: Select all

      
      DEF FN_get_x_char_to_pixel(X%) = X% * @char.x%
      DEF FN_get_y_char_to_pixel(Y%) = Y% * @char.y%
Just wondering what others think on this area or if the code above makes sense or could be done better?
DDRM

Re: Converting text viewport position to graphics units?

Post by DDRM »

Hi MrHiggins,

A few things that may help:
1) There are 2 graphics units per pixel, in each direction. You can get the dimensions in pixels with @size.x% and y%
2) Graphics coordinates have their origin at the bottom left (with positive Y being up), while text coordinates (and Windows commands, such as those used under the hood in Winlib5) have their origin at the top left (with positive Y being down).
3) Commands being passed to Windows are usually in pixels, not graphics units.
4) The size of a character cell depends on the mode - as you have already found, you can access them with @char.x% and y%

If you've got specific queries, come back, and I'll see if I can work out a formula...

Best wishes,

David
MrHiggins
Posts: 19
Joined: Wed 28 Jul 2021, 13:29

Re: Converting text viewport position to graphics units?

Post by MrHiggins »

Hi David,

For my example I'm specifically interested in converting the text view port row and column position to pixel x and y to be used with WINLIB5 controls. This is to make it easier to line up textboxes with the text.

I think my functions are correct but I have a feeling I could be missing something.

Many Thanks for the helping 👍
User avatar
hellomike
Posts: 184
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Converting text viewport position to graphics units?

Post by hellomike »

Hi,

What I understand from you is that you want to convert a simple TAB(X%, Y%) into the actual pixel position.

Note that positioning a character using TAB(X%, Y%), Y% is going from top to bottom. TAB(0, 0) will be the 1st character position of the top (text)line.
The coordinate default origin for (0 , 0) though is at the left, bottom pixel.

Also, as David mentioned, for each pixel, the BBCBASIC coordinate system use two units so be aware that @char.x% etc is all in pixels, not coordinates.

Therefor your functions for should be more like:

Code: Select all

DEF FN_get_x_char_to_coord(X%) = (X% * @char.x%) * 2
DEF FN_get_y_char_to_coord(Y%) = (@size.y% - Y% * @char.y%) * 2
I didn't test them though.

Regards,
Mike
MrHiggins
Posts: 19
Joined: Wed 28 Jul 2021, 13:29

Re: Converting text viewport position to graphics units?

Post by MrHiggins »

Thanks for the code Mike, that will be useful for working with BBC Basics inbuilt graphics operations and using in reference to text position.

I'm interested in pixels for usage with win api methods rather than the BBC Basic graphic units. So in the case of winapi the origin is at top left of screen going down which matches the text row and column origin. I think my original code works for that where first row and column start from 0 going up.

I'm starting to think using the dlgedit for working with the controls like editboxes and static text labels will be easier rather than trying to align the win controls to the text in bbc basic and constantly running, stopping, and updating the code until it looks correct.
DDRM

Re: Converting text viewport position to graphics units?

Post by DDRM »

This is probably blindingly obvious to you, but may help others less experienced...

For what it's worth, when I'm laying out multiple widgets I often define a set of pseudo-constants, which can be multiplied as needed, so, for example, the third widget down in the second column might be at something like:

leftmarg% + widg_width% + hspace%, topspace% + 2*widg_ht% + 2*vspace%

That way all the spacings in the layout will be consistent, and it's easy to change a given value (such as the horizontal spacing) and everything will update consistently.

You could, of course, embed that in a function/procedure which takes the required position within the grid and returns the equivalent pixel coordinates. If you wrapped that in a "point" structure you might simply be able to pass it directly to the Windows command...

Best wishes,

D
MrHiggins
Posts: 19
Joined: Wed 28 Jul 2021, 13:29

Re: Converting text viewport position to graphics units?

Post by MrHiggins »

DDRM I had been starting to do something similar to that, I will adapt it in my code and see how it goes.

Thanks everyone for the help
MrHiggins
Posts: 19
Joined: Wed 28 Jul 2021, 13:29

Re: Converting text viewport position to graphics units?

Post by MrHiggins »

I came up with this little test program using the information @DDRM gave. It creates a load of buttons in a grid on the main window. Sharing this if it is of interest to anyone else out there.

Code: Select all

      
      INSTALL @lib$ + "WINLIB5"
      MODE 0 : OFF
      COLOUR 1 + 128
      COLOUR 0
      CLS
      :
      TopMargin% = 5
      LeftMargin% = 5
      HSpace% = 1
      VSpace% = 5
      WidgetWidth% = 100
      WidgetHeight% = 25
      :
      FOR X% = 0 TO 5
        FOR Y% = 0 TO 18
          B% = FN_button("X " + STR$(X%) + " Y " + STR$(Y%), \
          \              FN_ui_column_to_x(LeftMargin%, WidgetWidth%, HSpace%, X%), \
          \              FN_ui_row_to_y(TopMargin%, WidgetHeight%, VSpace%, Y%),\
          \              WidgetWidth%, WidgetHeight%, 101, 0)
        NEXT
      NEXT
      :
      REPEAT : WAIT 1 : UNTIL FALSE
      :
      REM These methods let you layout out ui widgets in a columns and rows.
      DEF FN_ui_column_to_x(leftmargin%, width%, hspace%, I%) = leftmargin% + I% * width% + I% * hspace%
      DEF FN_ui_row_to_y(topmargin%, height%, vspace%, I%) = topmargin% + I% * height% + I% * vspace%