Hello all !!!.
I have a View , really StaticText view. I am displaying a text on it. I want to set the width of the view in function of the text i'm displaying in. i use width: (text size * font pontSize) method on the view. but, the view don't adjust exactly to the text. it is a little wider . My question is: How can i adjust more exactly the size of the view. TIA Pablo |
Pablo,
> I have a View , really StaticText view. I am displaying a text on it. > I want to set the width of the view in function of the text i'm displaying > in. > i use width: (text size * font pontSize) method on the view. > but, the view don't adjust exactly to the text. > it is a little wider . > > My question is: How can i adjust more exactly the size of the view. The reason why your original attempt at resizing the view does not work correctly is becase #pointSize returns the *height* of the characters and not the width. The difficulty is that most fonts are "proportional", that is their characters are different widths (e.g. an M is bigger than an i). In order to find the width of a particular string you will have to ask for the text size of the whole string, as calculated by a Canvas using #textExtent:. Here's an example: "Build a shell with a text field in it" shell := ShellView new create. textEdit := shell addSubView: TextEdit new. shell show. "Now set the text edit contents" textEdit value: 'Hello, this is a line of text'. "Compute the size of the text string (note this is a Point)" size := textEdit canvas textExtent: textEdit value. "Display it" "Set the width of the text view to the width of the string" textEdit width: size x. Best Regards, Andy Bower Dolphin Support http://www.object-arts.com --- Visit the Dolphin Smalltalk WikiWeb http://www.object-arts.com/wiki/html/Dolphin/FrontPage.htm --- |
Thanks a lot Andy !!!
Pablo "Andy Bower" <[hidden email]> wrote in message news:98if7j$20l62$[hidden email]... > Pablo, > > > I have a View , really StaticText view. I am displaying a text on it. > > I want to set the width of the view in function of the text i'm displaying > > in. > > i use width: (text size * font pontSize) method on the view. > > but, the view don't adjust exactly to the text. > > it is a little wider . > > > > My question is: How can i adjust more exactly the size of the view. > > The reason why your original attempt at resizing the view does not work > correctly is becase #pointSize returns the *height* of the characters and > not the width. The difficulty is that most fonts are "proportional", that > their characters are different widths (e.g. an M is bigger than an i). In > order to find the width of a particular string you will have to ask for the > text size of the whole string, as calculated by a Canvas using #textExtent:. > Here's an example: > > "Build a shell with a text field in it" > shell := ShellView new create. > textEdit := shell addSubView: TextEdit new. > shell show. > > "Now set the text edit contents" > textEdit value: 'Hello, this is a line of text'. > > "Compute the size of the text string (note this is a Point)" > size := textEdit canvas textExtent: textEdit value. "Display it" > > "Set the width of the text view to the width of the string" > textEdit width: size x. > > Best Regards, > > Andy Bower > Dolphin Support > http://www.object-arts.com > > --- > Visit the Dolphin Smalltalk WikiWeb > http://www.object-arts.com/wiki/html/Dolphin/FrontPage.htm > --- > > |
In reply to this post by Andy Bower
Andy,
> shell := ShellView new create. > textEdit := shell addSubView: TextEdit new. > shell show. > textEdit value: 'Hello, this is a line of text'. > size := textEdit canvas textExtent: textEdit value. "Display it" > textEdit width: size x. I've just tried this on my machine here, and it results in the TextEdit being about 25% wider than it needs to be. It doesn't actually matter to me (since I don't use this technique) but it might be indicative of another place where Dolphin/Windows is not picking up the actual font in use ? -- chris |
Andy,
I try and found the same as Chris "Chris Uppal" <[hidden email]> wrote in message news:98nvkm$jk5$[hidden email]... > Andy, > > > shell := ShellView new create. > > textEdit := shell addSubView: TextEdit new. > > shell show. > > textEdit value: 'Hello, this is a line of text'. > > size := textEdit canvas textExtent: textEdit value. "Display it" > > textEdit width: size x. > > I've just tried this on my machine here, and it results in the TextEdit > being about 25% wider than it needs to be. > > It doesn't actually matter to me (since I don't use this technique) but > it might be indicative of another place where Dolphin/Windows is not > picking up the actual font in use ? > > -- chris > > |
"pablo digonzelli" <[hidden email]> wrote in message
news:98o6ks$2sbfp$[hidden email]... > Andy, > I try and found the same as Chris > > "Chris Uppal" <[hidden email]> wrote in message > news:98nvkm$jk5$[hidden email]... > > Andy, > > > > > shell := ShellView new create. > > > textEdit := shell addSubView: TextEdit new. > > > shell show. > > > textEdit value: 'Hello, this is a line of text'. > > > size := textEdit canvas textExtent: textEdit value. "Display it" > > > textEdit width: size x. There are two problems with this: 1) View>>canvas doesn't actually set the Font of the supplied Canvas to the actualFont of the view, so the calculated extent will be for the default system font. 2) The width needs to be the window width, not the client width, so width of the text needs to be adjusted (expanded) to allow for the adornment. shell := ShellView new create. shell layoutManager: FlowLayout new. t := shell addSubView: TextEdit new. t value: 'Hello, this is a line of text'. size := t canvas font: t actualFont; textExtent: t value. t extent: (t calcExtentFromClientExtent: size+2). t2 := shell addSubView: TextEdit new. t2 value: 'and this another'. size := t2 canvas font: t2 actualFont; textExtent: t2 value. t2 extent: (t2 calcExtentFromClientExtent: size+2). shell show Why is it necessary to add 2? Not sure, but then I was never very good with off-by-one errors, so off-by-two errors confuse me totally :-). Actually I vaguely remember something screwy about the Win32 API AdjustWindowRect (which underlies View>>calcExtentFromClientExtent:), so maybe its about time I went back to the API documentation. Is it a good idea for View>>canvas to answer a canvas that isn't configured with the font one has specified for the View (or that which it inherits)? Not sure, its always worked like that but I don't know the reason or whether it is deliberate or not. Regards Blair |
It is working OK
"Blair McGlashan" <[hidden email]> wrote in message news:98o9ph$2rsb7$[hidden email]... > "pablo digonzelli" <[hidden email]> wrote in message > news:98o6ks$2sbfp$[hidden email]... > > Andy, > > I try and found the same as Chris > > > > "Chris Uppal" <[hidden email]> wrote in message > > news:98nvkm$jk5$[hidden email]... > > > Andy, > > > > > > > shell := ShellView new create. > > > > textEdit := shell addSubView: TextEdit new. > > > > shell show. > > > > textEdit value: 'Hello, this is a line of text'. > > > > size := textEdit canvas textExtent: textEdit value. "Display it" > > > > textEdit width: size x. > > There are two problems with this: > 1) View>>canvas doesn't actually set the Font of the supplied Canvas to > actualFont of the view, so the calculated extent will be for the default > system font. > 2) The width needs to be the window width, not the client width, so width of > the text needs to be adjusted (expanded) to allow for the adornment. > > shell := ShellView new create. > > shell layoutManager: FlowLayout new. > > t := shell addSubView: TextEdit new. > > t value: 'Hello, this is a line of text'. > > size := t canvas font: t actualFont; textExtent: t value. > > t extent: (t calcExtentFromClientExtent: size+2). > > t2 := shell addSubView: TextEdit new. > > t2 value: 'and this another'. > > size := t2 canvas font: t2 actualFont; textExtent: t2 value. > > t2 extent: (t2 calcExtentFromClientExtent: size+2). > > shell show > > > Why is it necessary to add 2? Not sure, but then I was never very good > off-by-one errors, so off-by-two errors confuse me totally :-). Actually I > vaguely remember something screwy about the Win32 API AdjustWindowRect > (which underlies View>>calcExtentFromClientExtent:), so maybe its about time > I went back to the API documentation. > > Is it a good idea for View>>canvas to answer a canvas that isn't configured > with the font one has specified for the View (or that which it inherits)? > Not sure, its always worked like that but I don't know the reason or whether > it is deliberate or not. > > Regards > > Blair > > |
Pablo
You wrote in message news:98oeld$2rmu6$[hidden email]... > It is working OK > Certainly that is true for small fonts, but I looked into it a bit more (to see why that extra 2 pixels width was necessary) and this time I first engaged my brain and thought about what the extent needed to take account of: 1) EDIT controls seem to implicitly have space for a border. There is an reference to this in the MFC source code, which has a specialised implementation of their window rect. calculation method which passes WS_BORDER to AdjustWindowRectEx. We therefore need to override TextEdit>>calcRectangleFromClientRectangle: 2) EDIT controls have left and right margins (see MSDN help for EM_GETMARGINS). The control calculates these from the text metrics of the font specified for the control, although the precise algorithm is not specified. 3) The EDIT control allows for the 'external leading' font metric when calculating the base line. I looked more closely at the TextEdit class and found the #calculateExtent method, which appears to be intended to calculate the window extent required for the current text/font combination. However it doesn't correctly take account of the Font due to a bug in the way it accesses the font, and it also ignores the margins and external leading. I've attached a "fixed" version. If anyone can think of any further subtleties the calculation needs to account for, please let me know. If you file in the code below then the #calculateExtent method of TextEdit will answer what I think is the correct extent for the text currently in the control, regardless of the Font used. Note that #calculateExtent is a private method, but if you set the #usePreferredExtent: aspect of the control to true, then the public method #layoutExtent will answer the calculated extent. So revising my example code, and with the patch applied: shell := ShellView new create. shell layoutManager: FlowLayout new; height: 200. 2 timesRepeat: [ | t f | t := shell addSubView: TextEdit new. f := Font choose. t usePreferredExtent: true; font: f; value: f displayString. t extent: t layoutExtent]. shell show Its a shame that Microsoft don't document more clearly the calculation that an EDIT control uses to decide the formatting rectangle for text as if they did then trial and error wouldn't be necessary to discover it. On the other hand Smalltalk is ideal for trial and error experimentation, and it was fun! Regards Blair ------------------------ !TextEdit methodsFor! calcRectangleFromClientRectangle: aClientRectangle "Private - Given a client <Rectangle>, answer the required window rectangle that would be required to achieve this taking into account the current window styles etc. Implementation Note: We must override because of EDIT controls implicit border." | rect | rect := RECT fromRectangle: aClientRectangle. UserLibrary default adjustWindowRectEx: rect dwStyle: self baseStyle | WS_BORDER "implicit border" bMenu: false dwExStyle: self extendedStyle. ^rect asRectangle! ! !TextEdit categoriesFor: #calcRectangleFromClientRectangle:!geometry!private! ! !TextEdit methodsFor! calculateExtent "Private - Answer a calculated preferred extent for the receiver." | canvas extent leading margins | canvas := self canvas. canvas font: self actualFont. extent := canvas textExtent: self plainText. leading := canvas textMetrics tmExternalLeading. canvas free. margins := self margins. extent := extent + ((self margins first + self margins last)@leading). "Now adjust required client extent to window extent" ^self calcExtentFromClientExtent: extent ! ! !TextEdit categoriesFor: #calculateExtent!geometry!private! ! Win32Constants at: #EM_GETMARGINS put: 16rD4! !TextEdit methodsFor! margins "Private - Answer the left and right margins." | dword | dword := self sendMessage: EM_GETMARGINS. ^Array with: dword highWord with: dword lowWord! ! !TextEdit categoriesFor: #margins!constants!private! ! |
Free forum by Nabble | Edit this page |