Setting wordwrap to auto in editor gadget

Mac OSX specific forum
localhero
New User
New User
Posts: 7
Joined: Tue Sep 05, 2006 12:12 pm
Location: UK

Setting wordwrap to auto in editor gadget

Post by localhero »

Here is my attempt to use Carbon API to set wordwrap to auto for an editorgadget.

Code: Select all

;OSX Wordwrap Test
;Uses Carbon API calls

;imported to purebasic using pbsoimporter
;wordwrap.pbl
  ;
  ;-framework Carbon
  ;GetControlProperty 6
  ;TXNSetTXNObjectControls 5
  
;-Init Variables
displaytext.s=""
status.l=0
Dim controlTag.l(0)
Dim controlData.b(0)

hWnd=OpenWindow(0, 100, 100, 450, 300, "OSX Wordwrap Test", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget)
If hWnd=0 Or CreateGadgetList(hWnd)=0:End:EndIf
EditorGadget(1, 10, 10, 430, 280, #PB_Editor_ReadOnly)

; this is the code that should set wordwrap to auto
If GetControlProperty_(GadgetID(1), 'PURE', 'TXOB', 4, 0, @TextObject.l) = 0 ;TextObject found
  controlTag(0) = 'wwrs'  ;kTXNWordWrapStateTag constant
  controlData(0) = false  ;kTXNAutoWrap constant
  status = TXNSetTXNObjectControls_(TextObject, false, 1, controlTag, controlData)
EndIf

; populate editorgadget with some text to test for auto wordwrap
For i=1 To 20
displaytext=displaytext+" this is a wordwrap test :"
Next
SetGadgetText(1, displaytext)

;main loop
Repeat 
 Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow 
End
It compiles without error but does not make the text wordwrap. What have I done wrong?
User avatar
michel51
Enthusiast
Enthusiast
Posts: 290
Joined: Mon Nov 21, 2005 10:21 pm
Location: Germany

Re: Setting wordwrap to auto in editor gadget

Post by michel51 »

localhero wrote:

Code: Select all


; this is the code that should set wordwrap to auto
If GetControlProperty_(GadgetID(1), 'PURE', 'TXOB', 4, 0, @TextObject.l) = 0 ;TextObject found
  controlTag(0) = 'wwrs'  ;kTXNWordWrapStateTag constant
  controlData(0) = false  ;kTXNAutoWrap constant
  status = TXNSetTXNObjectControls_(TextObject, false, 1, controlTag, controlData)
EndIf

Where do you have defined the "TextObject"??
I think the routine doesn't find the Textobject.

And an error: you have to write "controlData(0) = #FALSE", because that's the boolean. But the result is the same, no wrapping.

And a private question: On which place in the deep of the developer description you have found the "GetControlProprty" ? I've searched in vain.
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.21(x64), V 5.22beta
localhero
New User
New User
Posts: 7
Joined: Tue Sep 05, 2006 12:12 pm
Location: UK

Post by localhero »

Thanks for your reply michel51.

I found GetControlProperty in CarbonLib library reference here

http://developer.apple.com/documentatio ... rence.html

Fred gave the syntax for using GetControlProperty function to obtain a reference to the address of a text property in a previous post so I have used it here

http://www.purebasic.fr/english/viewtop ... carbon+api

I assumed that the parameter @TextObject.l actually defined the address of the textobject as a long and did not need to be defined elsewhere. I'll try defining it before the function call. I think I might need to add @ to TextObject in the TXNSetTXNObjectControls to pass the address of TextObject.

You are right in that the GetControlProperty does not find the textobject because instead of returning zero it returns error value -5604 which indicates 'not found'.

Here is the API for Get Control Property :
Obtains a piece of data that has been previously associated with a control.
OSStatus GetControlProperty (
ControlRef control,
OSType propertyCreator,
OSType propertyTag,
UInt32 bufferSize,
UInt32 * actualSize,
void * propertyBuffer
);

Parameters
control
A handle to the control whose associated data you wish to obtain.

propertyCreator
Your program’s signature, as registered through Apple Developer Technical Support. If your program is of a type that would not normally have a signature (for example, a plug-in), you should still register and use a signature in this case, even though your program’s file may not have the same creator code as the signature that you register. The ‘macs' property signature is reserved for the system and should not be used.

propertyTag
The application-defined code identifying the data.

bufferSize
A value specifying the size of the data to be obtained. If the size of the data is unknown, use the function GetControlPropertySize to get the data’s size. If the size specified in the bufferSize parameter does not match the actual size of the property, GetControlProperty only retrieves data up to the size specified or up to the actual size of the property, whichever is smaller, and an error is returned.

actualSize
On input, a pointer to an unsigned 32-bit integer. On return, this value is set to the actual size of the associated data. You may pass NULL for the actualSize parameter if you are not interested in this information.

propertyBuffer
On input, a pointer to a buffer. On return, this buffer contains a copy of the data that is associated with the specified control.

Return Value
A result code. See “Control Manager Result Codes”.

Discussion
You may use the function GetControlProperty to obtain a copy of data previously set by your application with the function SetControlProperty.

Availability
Available in Mac OS X v10.0 and later.
Declared In
Controls.h
[/quote]

localhero
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Setting wordwrap to auto in editor gadget

Post by Shardik »

This is a working solution for enabling word wrap (Mac OS X Snow Leopard and PB 4.50):

Code: Select all

ImportC ""
  GetControlProperty(Control, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ControlCount, ControlTags, ControlData)
EndImport

#noErr = 0

Dim ControlTag.L(0)
Dim ControlData.L(0)

OpenWindow(0, 50, 100, 450, 100, "MacOS X Word Wrap Test", #PB_Window_SystemMenu)
EditorGadget(0, 10, 10, 430, 80)

Result = GetControlProperty(GadgetID(0), 'PURE', 'TXOB', 4, 0, @TXNObject)

If Result = #noErr
  ControlTag(0) = 'wwrs' ; kTXNWordWrapStateTag
  ControlData(0) = 0     ; kTXNAutoWrap
  TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf

For i = 1 To 5
  Text$ = Text$ + "This is a word wrap test - "
Next i

SetGadgetText(0, Text$)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
jamirokwai
Enthusiast
Enthusiast
Posts: 772
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: Setting wordwrap to auto in editor gadget

Post by jamirokwai »

Hiya,

as the snippet above is not Unicode-safe, I added a compiler-directive:
This is my WordWrap-Enabling-Procedure (TM) :-) The 'wwrs' e.g. are simply converted to numbers.
You may probably use the code only, where the 'PURE'-things are converted to integers.

Thanks to localhero, Shardik and the others!
Procedure Editor_Word_Wrap(Gadget)
#noErr = 0
Dim ControlTag.l(0)
Dim ControlData.l(0)
CompilerIf #PB_Compiler_Unicode = 0
Result = GetControlProperty(GadgetID(Gadget), 'PURE', 'TXOB', 4, 0, @TXNObject)
If Result = #noErr
ControlTag(0) = 'wwrs' ; kTXNWordWrapStateTag
ControlData(0) = 0 ; kTXNAutoWrap
TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf
CompilerElse
Result = GetControlProperty(GadgetID(Gadget), 1347768901, 1415073602, 4, 0, @TXNObject)
If Result = #noErr
ControlTag(0) = 2004316787 ; kTXNWordWrapStateTag
ControlData(0) = 0 ; kTXNAutoWrap
TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf
CompilerEndIf

EndProcedure
Regards,
JamiroKwai
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Setting wordwrap to auto in editor gadget

Post by Shardik »

jamirokwai wrote:as the snippet above is not Unicode-safe, I added a compiler-directive:
You are right: my code example above does not work if you compile a
Unicode program by selecting "Compiler/Compiler Options..." in the IDE
menu and enable "Create unicode executable". The explanation is simple:
The tags are always 4 characters which are stored in ASCII mode as a long
integer (4 Bytes). Due to the little-endian format in which Intel processors
store values in memory, the characters are stored in reversed order:

Code: Select all

PropertyCreator.L = 'PURE'
Debug PeekS(@PropertyCreator, 4) ; Displays "ERUP"
When trying to compile the above code (or my previous code example) with
the option "Create unicode executable" you obtain this error message:
PureBasic wrote:Line 1: Overflow error: a 'long' value (.l) must be between
-2147483648 and +4294967295.
In unicode mode each character takes two bytes, so 4x2 are 8 bytes which
don't fit into a long integer (4 bytes). If you declare PropertyCreator as a
quad value (PropertyCreator.Q) then the above code snippet will again work
correctly. But the utilized API functions await long integers, so this is no
solution. Therefore jamirokwai's approach is the correct one if you need
code that has to work in ASCII and Unicode mode: instead of using a string
of 4 characters simply use the resulting long integer value. And you even
don't need to work with CompilerIf because the usage of a long integer
works in ASCII and Unicode mode.

I therefore adapted my previous code example in this way and as a further
goodie added the possibility to switch the current word wrap mode during
runtime:

Code: Select all

; ----- Works in ASCII and Unicode mode!

ImportC ""
  GetControlProperty(ControlRef, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNGetTXNObjectControls(TXNObject, ArrayItemCount, ControlTagsArray, ControlDataArray)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ArrayItemCount, ControlTagsArray, ControlDataArray)
EndImport

#kTXNWordWrapStateTag = 2004316787 ; 'wwrs'

Procedure ToggleWordWrapMode(EditorGadgetID)
  Protected ControlRef
  Protected TXNObject
  Protected PropertyCreator = 1347768901 ; 'PURE'
  Protected PropertyTag     = 1415073602 ; 'TXOB'

  Dim ControlTag(0)
  Dim ControlData(0)

  ControlRef = GadgetID(EditorGadgetID)
  ControlTag(0)  = #kTXNWordWrapStateTag 

  If GetControlProperty(GadgetID(EditorGadgetID), PropertyCreator, PropertyTag, 4, 0, @TXNObject) = 0
    If TXNGetTXNObjectControls(TXNObject, 1, @ControlTag(0), @ControlData(0)) = 0
      ControlData(0) ! 1
      TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
    EndIf
 EndIf
EndProcedure

OpenWindow(0, 200, 100, 450, 100, "MacOS X Word Wrap Test", #PB_Window_SystemMenu)
EditorGadget(0, 10, 10, 430, 55)
ButtonGadget(1, 160, 70, 140, 20, "Toggle Word Wrap")

For i = 1 To 5
  Text$ = Text$ + "This is a word wrap test - "
Next i

SetGadgetText(0, Text$)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        ToggleWordWrapMode(0)
      EndIf
  EndSelect
ForEver
For those using jamirokwai's above posted procedure in his previous posting:
The procedure won't work until you insert the following import statements
into your code

Code: Select all

ImportC ""
  GetControlProperty(Control, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ControlCount, ControlTags, ControlData)
EndImport
Post Reply