intuited (better get yourself a hot drink before tucking into this
),
Thanks for posting back your findings, they were most interesting to read. Sorry for the slow response, I have little time at the moment but managed to have brief look into this. I had a play around with your code and here is my observations. The code at bottom is your but I have chopped it up a fair bit. I have a spreadsheet document with literally just one text label control named "size label".
so although the form is laid out in pixels, in order to interact with the lower-level shape layer, the coordinates and sizes need to be translated into whatever unit of measurement is in use at that level. this, as well as and in light of the fact that it's necessary to set the size of a control at least twice, raises a number of design and technical questions, none of which I've found the answer to in any documentation.
1) You only need to change the size in one place - the shape. As you can see from my code below, when the shape size is changed, this propagates to the control. In other words, the calls to SetOutputSize(), SetPosSize() are not necessary (I have wrapped the call to Shape.Setsize() in Ctrl.GetOutputSize() and Ctrl.GetPosSize() which you can uncomment to verify this).
2) I was originally testing with a TextBox and TextLabel and found that the sizes from Ctrl.GetOutputSize() and Ctrl.GetPosSize() were slightly different but this was realted to the TextBox control having a '3D look' set. Just thought I'd mention that as an aside.
3) The unit scaling in general is the most perplexing component here, as you discovered. You are correct that the
shape size units are in 100ths of mm (or 1000ths of cm as you said). The mystery to me is the units of the control, but I shall get to that soon.
Just briefly, I think you did the right thing in how you scaled between the two units. However that bit you did about trying to add one pixel by using a mod function on the ratio is unnecessary, and indeed created an error. What you are actually doing there is simply adding one to the ratio, because your code effectively says: 'if the ratio is not an integer, add one to it'. It's highly unlikely to be an integer so one is always added. I seem to always get width ratio of 26.536, and a height ratio of 27.879 (which become 27.536 and 28.879 if you add one). That addition of one results in the label I am testing with, which is about 9cm wide, results in about an extra 0.3cm. Hence the following:
although the edit box ends up having a margin on the left but not the right side of the text that it contains.
The fact that is on the left, and not right, is probably related to control's text alignment property. I would just get the rid of that operation, and if necessary (and it's not on the control I am testing on) add one to the height and width of the PreferredSize before multiplying it by the ratio to get the shape's size.
So back to control's units of measurement. Figuring out exactly what is going on here is something I am stuck on and have no more time at the moment although I am very curious. What I did find is that the call to
GetView() 'returns the size of the object in device units'. Unfortunately a call to getGraphics() returns NULL, because no device is set.
However it's obvious some object is using a device that is scaling these controls in some way. For example, if I make my control 10cm by 10cm (right click on the control and select 'position and size'), and give it a colored background, I can see visually that it is not a square. It is higher than it is wider, and I get the following results:
Shape.Width = 10000
Shape.Height = 10000
Control.Width = 359 (WidthRatio = 27.855)
Control.Height = 376 (HeightRatio = 26.596))
All I can confirm is that device units are indeed pixels (I cut an image of the control and measured it in GIMP), but why they are being scaled as they are I am not sure.
I was recently mucking around with the graphics exporter, in order to make a whole page of an Impress document export as a jpeg. This is where I first came across shapes using 100ths of mm. And in that process I had the page's shape, and using the size from that I could use a ratio of 0.0378 to convert that to pixels (or 26.455 for pixels to 100ths of a mm as we are doing here), both horizontally and vertically. That was because:
OOo uses, 1440 twips per inch, which equals 56.7 twips per mm,
The functions TwipsPerPixelX() and TwipsPerPixelY() (both of which return 15 on my system),
Shape is in 100ths of a mm,
Therefore,
PixelsWidth = (1/15) * 56.7 * (ShapeSize.Width/100) [ (pixels/
twips) * (
twips/
mm) * ((
mm*
100)/
100) = pixels ]
PixelsWidth = 0.0378 * ShapeSize.Width
So yeh, why Calc (which is what I am using) has slightly odd display ratios I am not sure...
Code: Select all
Sub TestResizing (Event as Object)
oDoc = ThisComponent
Controller = ThisComponent.GetCurrentController()
If NOT GlobalScope.BasicLibraries.isLibraryLoaded( "Tools" ) Then GlobalScope.BasicLibraries.loadLibrary( "Tools" )
labelModel = getControlModel( oDoc.Sheets(0), "size label")
labelCtl = Controller.GetControl( labelModel )
labelShape = GetControlShape( oDoc.Sheets(0), "size label" )
labelPreferredSize = labelCtl.PreferredSize
'the shape size is sometimes very different from the control size.
' although this is undocumented it seems to be because the shape size is measured physical dimension units and not pixels.
ShapeHeightRatio = labelShape.Size.Height / labelCtl.Size.Height
ShapeWidthRatio = labelShape.Size.Width / labelCtl.Size.Width
labelPreferredSize.Height = labelPreferredSize.Height * ShapeHeightRatio
labelPreferredSize.Width = labelPreferredSize.Width * ShapeWidthRatio
'-----------------------------------------------------------
'labelSize = labelCtl.getPosSize()
'labelOutputSize = labelCtl.getOutputSize()
'-----------------------------------------------------------
labelShape.SizeProtect = False
labelShape.SetSize(labelPreferredSize)
'-----------------------------------------------------------
'labelSize = labelCtl.getPosSize()
'labelOutputSize = labelCtl.getOutputSize()
'-----------------------------------------------------------
End Sub