[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

In addition to the tricks by wilbert and fsw, some more window fullscreen switches and a procedure to get window fullscreen state:

Code: Select all

;--[ Window fullscreen procedures ]----------------------------------------------------------------

Procedure EnableWindowFullscreenGadget(window)
    NewCollectionBehaviour = CocoaMessage(0, WindowID(window), "collectionBehavior") | $80
    CocoaMessage(0, WindowID(window), "setCollectionBehavior:", NewCollectionBehaviour)
EndProcedure

Procedure ToggleWindowFullscreen(window)
    CocoaMessage(0, WindowID(window), "toggleFullScreen:")
EndProcedure

Procedure EnterWindowFullscreen(window)
    CocoaMessage(0, WindowID(window), "enterFullScreenMode:")
EndProcedure

Procedure ExitWindowFullscreen(window)
    CocoaMessage(0, WindowID(window), "exitFullScreenMode:")
EndProcedure

Procedure IsWindowFullscreen(window)
    #NSFullScreenWindowMask = 1 << 14
    ProcedureReturn Bool( CocoaMessage(0, WindowID(window), "styleMask") & #NSFullScreenWindowMask )
EndProcedure

;--------------------------------------------------------------------------------------------------


Procedure.s BoolToYesNo(bool)
    If bool : ProcedureReturn "Yes" : Else : ProcedureReturn "No" : EndIf
EndProcedure

Macro UpdateText()
    SetGadgetText(4, "Fullscreen: " + BoolToYesNo(IsWindowFullscreen(0)) )
EndMacro

#WinFlags = #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_Invisible

If OpenWindow(0, 0, 0, 220, 175, "Fullscreen Switch", #WinFlags)
    WindowBounds(0, 220, 175, #PB_Ignore, #PB_Ignore)
    
    EnableWindowFullscreenGadget(0)
    
    ;AddKeyboardShortcut(0,#PB_Shortcut_Control|#PB_Shortcut_Command|#PB_Shortcut_F,1) ; not required when using a menu
    
    CreateMenu(0,0)
    MenuTitle("View")
    MenuItem(1, "Toggle Fullscreen"  +Chr(9)+"Ctrl+Cmd+F") ; Standard OS X menu switch = Ctrl + Cmd + F
    
    ButtonGadget(0,10, 10,200,25,"Exit")
    ButtonGadget(1,10, 40,200,25,"Toggle fullscreen")
    ButtonGadget(2,10, 70,200,25,"Enter fullscreen")
    ButtonGadget(3,10,100,200,25,"Exit fullscreen")
    TextGadget  (4,10,140,200,25,"",#PB_Text_Center)
    
    HideWindow(0,#False)
    
    EnterWindowFullscreen(0)
    
    UpdateText()
    
    Repeat
        Select WaitWindowEvent()
            Case #PB_Event_CloseWindow
                End
            Case #PB_Event_Gadget
                Select EventGadget()
                    Case 0 : End
                    Case 1 : ToggleWindowFullscreen(0) : UpdateText()  ; Toggle fullscreen mode
                    Case 2 : EnterWindowFullscreen(0)  : UpdateText()  ; Enter  fullscreen mode
                    Case 3 : ExitWindowFullscreen(0)   : UpdateText()  ; Exit   fullscreen mode
                EndSelect
            Case #PB_Event_Menu
                Select EventMenu()
                    Case -1 : End
                    Case  1 : ToggleWindowFullscreen(0) : UpdateText() ; "Toggle fullscreen" menu update
                EndSelect
            Case #PB_Event_SizeWindow
                UpdateText()                                           ; Update fullscreen mode after resize
                                                                       ; ( catches fullscreen window button clicks )
        EndSelect
    ForEver  
EndIf
Ctrl+Cmd+F is used as default in most Mac OS X applications to toggle fullscreen mode.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

Some functions for getting name and size for PB's gadget fonts, etc.:

Code: Select all

EnableExplicit


Procedure.s PeekNSString(string)
    ;
    ; converts NSString to PB string
    ;
    #NSASCIIStringEncoding   = 1
    #NSUTF8StringEncoding    = 4
    #NSUnicodeStringEncoding = 10
    
    Protected result.s, length, *buffer
    If string
        length = CocoaMessage(0,string,"length")
        If length
            length + 1
            length * SizeOf(Character)
            *buffer = AllocateMemory(length)
            If *buffer
                CompilerIf #PB_Compiler_Unicode
                    CocoaMessage(0,string,"getCString:@",@*buffer,"maxLength:@",@length,"encoding:",#NSUnicodeStringEncoding)
                    result = PeekS(*buffer,-1,#PB_Unicode)
                CompilerElse
                    CocoaMessage(0,string,"getCString:@",@*buffer,"maxLength:@",@length,"encoding:",#NSASCIIStringEncoding)
                    result = PeekS(*buffer,-1,#PB_Ascii)
                CompilerEndIf
                FreeMemory(*buffer)
            EndIf
        EndIf
    EndIf
    ProcedureReturn result
EndProcedure


Procedure.s GetFontName(FontID)
    ;
    ; returns the font name of FontID
    ;
    Protected name.s, string
    If FontID
        string = CocoaMessage(0,FontID,"displayName") ; "familyName" and "fontName" for internal use
                                                      ; use "displayName" for the real name
        If string
            ProcedureReturn PeekNSString(string)
        EndIf
    EndIf
EndProcedure



Procedure.s GetDefaultFontName()
    ;
    ; returns the font name used for ButtonGadget()
    ;
    ; call at program start to get the default font name for PB gadgets
    ;
    Protected name.s
    Protected win = OpenWindow(#PB_Any,0,0,0,0,"",#PB_Window_Invisible)
    If win
        Protected btn = ButtonGadget(#PB_Any,0,0,0,0,"text") ; alternative: TextGadget()
        If btn
            name = GetFontName( GetGadgetFont(btn) )
            FreeGadget(btn)
        EndIf
        CloseWindow(win)
    EndIf
    ProcedureReturn name
EndProcedure


Procedure.CGFloat GetFontSize(FontID)
    ;
    ; returns the font size of FontID
    ;
    Protected pointSize.CGFloat = 0.0
    If FontID
        CocoaMessage(@pointSize,FontID,"pointSize")
    EndIf
    ProcedureReturn pointSize
EndProcedure


Procedure.CGFloat GetDefaultFontSize()
    ;
    ; returns the font size used for ButtonGadget()
    ;
    ; call at program start to get the default font size for PB gadgets
    ;
    Protected size.CGFloat = 0.0
    Protected win = OpenWindow(#PB_Any,0,0,0,0,"",#PB_Window_Invisible)
    If win
        Protected btn = ButtonGadget(#PB_Any,0,0,0,0,"text") ; alternative: TextGadget()
        If btn
            size = GetFontSize( GetGadgetFont(btn) )
            FreeGadget(btn)
        EndIf
        CloseWindow(win)
    EndIf
    ProcedureReturn size
EndProcedure


Procedure IsFontFixedPitch(FontID)
    ;
    ; returns true if FontID is a monospaced font
    ;
    If FontID
        ProcedureReturn CocoaMessage(0,FontID,"isFixedPitch")
    EndIf
EndProcedure


Procedure.CGFloat GetSystemFontSize()
    ;
    ; returns Mac OS X default system font size
    ;
    Protected size.CGFLoat = 0.0
    CocoaMessage(@size,0,"NSFont systemFontSize")
    ProcedureReturn size
EndProcedure


Procedure.CGFloat GetSmallSystemFontSize()
    ;
    ; returns Mac OS X default small system font size
    ;
    Protected size.CGFLoat = 0.0
    CocoaMessage(@size,0,"NSFont smallSystemFontSize")
    ProcedureReturn size
EndProcedure


Procedure.CGFloat GetLabelFontSize()
    ;
    ; returns Mac OS X default font size used for labels (TextGadget in PB)
    ;
    Protected size.CGFLoat = 0.0
    CocoaMessage(@size,0,"NSFont labelFontSize")
    ProcedureReturn size
EndProcedure



Debug "Default PB font:"
Debug GetDefaultFontName()
Debug GetDefaultFontSize()


Debug "System font sizes:"
Debug GetSystemFontSize()
Debug GetSmallSystemFontSize()
Debug GetLabelFontSize()
Output:

Code: Select all

Default PB font:
Lucida Grande
12.0
System font sizes:
13.0
11.0
10.0
PB 5.20 beta 7 x86 & x64, Unicode & ASCII mode, tetsted on Mac OS X 10.8.4
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

@Danilo, your PeekNSString procedure works fine.
I'm wondering if there's any specific reason you did it this way compared to the way some previous examples did it

Code: Select all

Procedure.s PeekNSString(string)
  ProcedureReturn PeekS(CocoaMessage(0, string, "UTF8String"), -1, #PB_UTF8)
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

wilbert wrote:@Danilo, your PeekNSString procedure works fine.
I'm wondering if there's any specific reason you did it this way compared to the way some previous examples did it

Code: Select all

Procedure.s PeekNSString(string)
  ProcedureReturn PeekS(CocoaMessage(0, string, "UTF8String"), -1, #PB_UTF8)
EndProcedure
I just overlooked the "UTF8String" method in the API docs, only found "getCString". Checked again now, NSString::UTF8String is in the docs (at the very end),
so it is probably better to use your shorter and faster procedure. Thanks! :)

EDIT:
BTW, do we need to free the Mac OS X string pointer (NSString *) with "release" or "autorelease", or does the
garbage collector do this at program end? If we want to free object resources before program end, should we
call "release" or "autorelease" from NSObject?
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

Get default user language/locale settings:

Code: Select all

;
; get default user language/locale settings
;
; http://www.purebasic.fr/english/viewtopic.php?f=19&t=50795&start=137
;
;
; The language code is based on the ISO 639-x/IETF BCP 47 standard. ISO 639-1 defines two-character codes, such as “en” And “fr”,
; for the world’s most commonly used languages.
; If a two-letter ISO 639-1 code is not available, then ISO 639-2 three-letter identifiers are accepted as well,
; for example “haw” For Hawaiian. For more details, see http://www.loc.gov/standards/iso639-2/php/English_list.php
;
EnableExplicit

Macro release(object)
    CocoaMessage(0,object,"release")
EndMacro

Macro autorelease(object)
    CocoaMessage(0,object,"autorelease")
EndMacro


Procedure.s GetDefaultLanguage()
    Protected result.s, NSUserDefaults_defs, NSArray_languages, NSString_preferredLang
    
    NSUserDefaults_defs = CocoaMessage(0,0,"NSUserDefaults standardUserDefaults")
    If NSUserDefaults_defs
        NSArray_languages   = CocoaMessage(0,NSUserDefaults_defs,"objectForKey:$",@"AppleLanguages")
        If NSArray_languages
            NSString_preferredLang = CocoaMessage(0,NSArray_languages,"objectAtIndex:",0)
            If NSString_preferredLang
                result = PeekS(CocoaMessage(0, NSString_preferredLang, "UTF8String"), -1, #PB_UTF8)
                autorelease(NSString_preferredLang)
            EndIf
            autorelease(NSArray_languages)
        EndIf
        autorelease(NSUserDefaults_defs)
    EndIf
    ProcedureReturn result
EndProcedure

Procedure.s GetUserLocale()
    Protected result.s, NSUserDefaults_defs, NSString_locale

    NSUserDefaults_defs = CocoaMessage(0,0,"NSUserDefaults standardUserDefaults")
    If NSUserDefaults_defs
        NSString_locale  = CocoaMessage(0,NSUserDefaults_defs,"objectForKey:$",@"AppleLocale")
        If NSString_locale
            result = PeekS(CocoaMessage(0, NSString_locale, "UTF8String"), -1, #PB_UTF8)
            autorelease(NSString_locale)
        EndIf
        autorelease(NSUserDefaults_defs)
    EndIf
    ProcedureReturn result
EndProcedure


Procedure.s GetUserLanguage()
    ;
    ; by Shardik
    ;
    ; http://www.purebasic.fr/english/viewtopic.php?f=3&t=55750&start=3
    ;
    Protected result.s, CurrentLocale, LanguageCode, string
    CurrentLocale = CocoaMessage(0, 0, "NSLocale currentLocale")
    If CurrentLocale
        LanguageCode = CocoaMessage(0, CurrentLocale, "objectForKey:$", @"kCFLocaleLanguageCodeKey")
        If LanguageCode
            string = CocoaMessage(0, CurrentLocale, "displayNameForKey:$", @"kCFLocaleLanguageCodeKey", "value:", LanguageCode)
            If string
                result = PeekS(CocoaMessage(0, string, "UTF8String"), -1, #PB_UTF8)
                autorelease(string)
            EndIf
            autorelease(LanguageCode)
        EndIf
        autorelease(CurrentLocale)
    EndIf
    ProcedureReturn result
EndProcedure


Procedure.s GetUserLanguageIdentifier()
    ;
    ; by Shardik
    ;
    ; http://www.purebasic.fr/english/viewtopic.php?f=3&t=55750&start=3
    ;
    Protected result.s, CurrentLocale, LanguageCode, string
    CurrentLocale = CocoaMessage(0, 0, "NSLocale currentLocale")
    If CurrentLocale
        LanguageCode = CocoaMessage(0, CurrentLocale, "objectForKey:$", @"kCFLocaleIdentifierKey")
        If LanguageCode
            string = CocoaMessage(0, CurrentLocale, "displayNameForKey:$", @"kCFLocaleIdentifierKey", "value:", LanguageCode)
            If string
                result = PeekS(CocoaMessage(0, string, "UTF8String"), -1, #PB_UTF8)
                autorelease(string)
            EndIf
            autorelease(LanguageCode)
        EndIf
        autorelease(CurrentLocale)
    EndIf
    ProcedureReturn result
EndProcedure

Debug "GetDefaultLanguage:        "+GetDefaultLanguage()
Debug "GetUserLocale:             "+GetUserLocale()
Debug "GetUserLanguage:           "+GetUserLanguage()
Debug "GetUserLanguageIdentifier: "+GetUserLanguageIdentifier()
Output:

Code: Select all

GetDefaultLanguage:        de
GetUserLocale:             de_DE
GetUserLanguage:           Deutsch
GetUserLanguageIdentifier: Deutsch (Deutschland)
Mac OS X API docs wrote:The language code is based on the ISO 639-x/IETF BCP 47 standard. ISO 639-1 defines two-character codes, such as “en” And “fr”,
for the world’s most commonly used languages.
If a two-letter ISO 639-1 code is not available, then ISO 639-2 three-letter identifiers are accepted as well,
for example “haw” For Hawaiian. For more details, see http://www.loc.gov/standards/iso639-2/php/English_list.php
Last edited by Danilo on Fri Aug 02, 2013 7:26 pm, edited 2 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Danilo wrote:
wilbert wrote:@Danilo, your PeekNSString procedure works fine.
I'm wondering if there's any specific reason you did it this way compared to the way some previous examples did it

Code: Select all

Procedure.s PeekNSString(string)
  ProcedureReturn PeekS(CocoaMessage(0, string, "UTF8String"), -1, #PB_UTF8)
EndProcedure
I just overlooked the "UTF8String" method in the API docs, only found "getCString". Checked again now, NSString::UTF8String is in the docs (at the very end),
so it is probably better to use your shorter and faster procedure. Thanks! :)

EDIT:
BTW, do we need to free the Mac OS X string pointer (NSString *) with "release" or "autorelease", or does the
garbage collector do this at program end? If we want to free object resources before program end, should we
call "release" or "autorelease" from NSObject?
The returned UTF8 string is automatically freed just like an object marked for autorelease (this means on (Wait)WindowEvent ) .
Usually you only need to free objects yourself that you created using alloc or new.
Last edited by wilbert on Fri Aug 02, 2013 12:24 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

wilbert wrote:The returned UTF8 string is automatically freed just like an object marked for autorelease (this means on (Wait)WindowEvent ) .
Thank you for this information!
Fred
Administrator
Administrator
Posts: 18192
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Fred »

wilbert wrote:Usually you only need to free objects yourself that you created using alloc or new.
or copy
User avatar
Shardik
Addict
Addict
Posts: 2059
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Get the number of currently visible rows in a ListIconGadget taking into account when a horizontal scrollbar is displayed (try to increase the window width: the horizontal scrollbar will be removed and the number of visible rows in the window title will be updated!):

Code: Select all

EnableExplicit

Procedure.I GetVisibleRows(ListIconID.I)
  Protected ContentView.I
  Protected EnclosingScrollView.I
  Protected VisibleRange.NSRange
  Protected VisibleRect.NSRect

  ; ----- Get scroll view inside of ListIconGadget
  EnclosingScrollView = CocoaMessage(0, GadgetID(ListIconID), "enclosingScrollView")
  
  If EnclosingScrollView
    ContentView = CocoaMessage(0, EnclosingScrollView, "contentView")
    ; ----- Get visible area
    ;       (automatically subtract horizontal scrollbar if shown) 
    CocoaMessage(@VisibleRect, ContentView, "documentVisibleRect")
    ; ----- Subtract border width
    If CocoaMessage(0, EnclosingScrollView, "borderType") > 0
      VisibleRect\size\height - 5
    EndIf
    ; ----- Get number of rows visible
    CocoaMessage(@VisibleRange, GadgetID(ListIconID), "rowsInRect:@", @VisibleRect)
    ProcedureReturn Int(VisibleRange\length)
  EndIf
EndProcedure

Define i.I

OpenWindow(0, 200, 100, 300, 95, "Get visible rows", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
WindowBounds(0, WindowWidth(0), WindowHeight(0), WindowWidth(0) + 4, 500)
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Column 1", 130)
AddGadgetColumn(0, 1, "Column 2", 130)

For i = 1 To 20
  AddGadgetItem(0, -1, "Row " + Str(i) + ", Column 1" + #LF$ + "Row " + Str(i) + ", Column 2")
Next i

; -----Wait until ListIconGadget is initialized
While WindowEvent() : Wend

SetWindowTitle(0, "Visible rows: " + Str(GetVisibleRows(0)))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_SizeWindow
      ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 20, WindowHeight(0) - 20)
      SetWindowTitle(0, "Visible rows: " + Str(GetVisibleRows(0)))
  EndSelect
ForEver
Update: In the procedure GetVisibleRows() I had to change one occurrence of GadgetID(0) to GadgetID(ListIconID).
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

Open Terminal and start console applications/scripts and shell commands (in new Terminal TAB):

Code: Select all

Procedure.s AppleScript(Script.s)
    ;
    ; by wilbert
    ;
    ; http://www.purebasic.fr/english/viewtopic.php?p=393553#p393553
    ;
    Protected retVal.s, strVal, numItems, i
    Protected aScript = CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSAppleScript alloc"), "initWithSource:$", @Script), "autorelease")
    Protected eventDesc = CocoaMessage(0, aScript, "executeAndReturnError:", #nil)
    If eventDesc
        numItems = CocoaMessage(0, eventDesc, "numberOfItems")
        If numItems
            For i = 1 To numItems
                strVal = CocoaMessage(0, CocoaMessage(0, eventDesc, "descriptorAtIndex:", i), "stringValue")
                If strVal
                    retVal + PeekS(CocoaMessage(0, strVal, "UTF8String"), -1, #PB_UTF8)
                    If i <> numItems : retVal + #LF$ : EndIf
                EndIf
            Next
        Else
            strVal = CocoaMessage(0, eventDesc, "stringValue")
            If strVal : retVal = PeekS(CocoaMessage(0, strVal, "UTF8String"), -1, #PB_UTF8) : EndIf
        EndIf
    EndIf
    ProcedureReturn retVal 
EndProcedure



Procedure RunProgramInTerminal(program$,commandline$="",directory$="")
    If commandline$ : commandline$ = " "+commandline$ : EndIf
    If directory$   : directory$   = "cd \"+#DQUOTE$+directory$+"\"+#DQUOTE$+"; " : EndIf
    AppleScript("tell application "+#DQUOTE$+"Terminal"+#DQUOTE$+#CR$+
                "   activate"+#CR$+                                                                                                                          ; activate
                "   do script "+#DQUOTE$+directory$+"\"+#DQUOTE$+program$+"\"+#DQUOTE$+commandline$+#DQUOTE$+" in front window"+#CR$+                        ; run script
                "   activate"+#CR$+                                                                                                                          ; activate
                "end tell")
EndProcedure

Procedure RunProgramInNewTerminalTab(program$,commandline$="",directory$="")
    If commandline$ : commandline$ = " "+commandline$ : EndIf
    If directory$   : directory$   = "cd \"+#DQUOTE$+directory$+"\"+#DQUOTE$+"; " : EndIf
    AppleScript("tell application "+#DQUOTE$+"Terminal"+#DQUOTE$+#CR$+
                "   activate"+#CR$+                                                                                                                           ; activate
                "   tell application "+#DQUOTE$+"System Events"+#DQUOTE$+" To keystroke "+#DQUOTE$+"t"+#DQUOTE$+" using {command down}"+#CR$+"activate"+#CR$+ ; send CMD+t (new TAB)
                "   tell application "+#DQUOTE$+"System Events"+#DQUOTE$+" To keystroke "+#DQUOTE$+"k"+#DQUOTE$+" using {command down}"+#CR$+"activate"+#CR$+ ; send CMD+k (clear screen)
                "   do script "+#DQUOTE$+directory$+"\"+#DQUOTE$+program$+"\"+#DQUOTE$+commandline$+#DQUOTE$+" in front window"+#CR$+                         ; run script
                "   activate"+#CR$+                                                                                                                           ; activate
                "end tell")
EndProcedure


If ProgramParameter(0)=""
    RunProgramInNewTerminalTab("ls", "-l", #PB_Compiler_Home+"compilers/")      ; list contents of PB/compilers/ directory
    RunProgramInNewTerminalTab(#PB_Compiler_Home+"compilers/nasm", "-h")        ; nasm help
    RunProgramInNewTerminalTab(#PB_Compiler_Home+"compilers/pbcompiler", "-h")  ; pbcompiler help
    RunProgramInNewTerminalTab("ping", "127.0.0.1")                             ; ping                -> CTRL+C to quit
    RunProgramInNewTerminalTab("top")                                           ; list open processes -> CTRL+C to quit
    RunProgramInNewTerminalTab(ProgramFilename(),"-")                           ; run self
Else
    If OpenConsole()
        PrintN("Hello from PureBasic console application!")
    EndIf
EndIf
I would like the PureBasic IDE to start console programs like this, by opening a new Terminal TAB and running my compiled console app in it. :)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Danilo »

Another way of running console programs by using temporary bash scripts.
Opens a new console window each time, unfortunately ignoring your default console style.

Code: Select all

EnableExplicit

Global NewList _RunConsoleProgram_TempFileNames.s()

Procedure RegisterTemporaryFilename(filename$)
    LastElement( _RunConsoleProgram_TempFileNames() )
    If AddElement( _RunConsoleProgram_TempFileNames() )
        _RunConsoleProgram_TempFileNames() = filename$
    EndIf
EndProcedure

Procedure DeleteTemporaryFiles()
    Protected count
    ForEach _RunConsoleProgram_TempFileNames()
        While DeleteFile(_RunConsoleProgram_TempFileNames(),#PB_FileSystem_Force)=0 And count < 50
            count + 1
            Delay(20)
        Wend
    Next
EndProcedure

Procedure.s GetTemporaryFilename()
    Protected i, filename$ = GetTemporaryDirectory()+"tmp_"
    For i = 0 To 20
        filename$ + Chr('A'+Random(25))
    Next
    If FileSize(filename$) = -1   ; If file does not exist, return the generated filename
        ProcedureReturn filename$
    Else                          ; Else: generate a new name
        ProcedureReturn GetTemporaryFilename()
    EndIf
EndProcedure

Procedure RunConsoleProgram(program$, argument$="", workingDirectory$="")
    Protected file, filename$ = GetTemporaryFilename()
    file = CreateFile(#PB_Any,filename$)
    If file
        WriteStringN(file,"#!/bin/bash")
        If workingDirectory$
            WriteStringN(file,"cd "+#DQUOTE$+workingDirectory$+#DQUOTE$)
        EndIf
        If argument$ : argument$ = " "+argument$ : EndIf
        WriteStringN(file,"clear")
        WriteStringN(file,#DQUOTE$+program$+#DQUOTE$+argument$)
        WriteStringN(file,"")
        CloseFile(file)
        SetFileAttributes(filename$,GetFileAttributes(filename$)|#PB_FileSystem_ExecUser)
        RunProgram("open","-a "+#DQUOTE$+"Terminal.app"+#DQUOTE$+" "+#DQUOTE$+filename$+#DQUOTE$,workingDirectory$,#PB_Program_Wait)
        RegisterTemporaryFilename(filename$)
    EndIf
EndProcedure


If ProgramParameter(0)=""
    RunConsoleProgram("ls", "-l", #PB_Compiler_Home+"compilers/")      ; list contents of PB/compilers/ directory
    RunConsoleProgram(#PB_Compiler_Home+"compilers/nasm", "-h")        ; nasm help
    RunConsoleProgram(#PB_Compiler_Home+"compilers/pbcompiler", "-h")  ; pbcompiler help
    RunConsoleProgram("ping", "127.0.0.1")                             ; ping                -> CTRL+C to quit
    RunConsoleProgram("top")                                           ; list open processes -> CTRL+C to quit
    RunConsoleProgram(ProgramFilename(),"-")
    
    Delay(1000)             ; wait some time before deleting the temporary scripts:
                            ; It is important to give Terminal some time for (first time) start-up!
                            ; Deleting the files before Terminal started correctly, will display
                            ; error message at the console because the script can't be found anymore.

    DeleteTemporaryFiles()  ; now delete the temporary files
Else
    If OpenConsole()
        EnableGraphicalConsole(#True)
        ClearConsole()
        ConsoleLocate(0,0)
        ;PrintN(ProgramParameter(0))
        PrintN("Hello from PureBasic console application!")
        CloseConsole()
    EndIf
EndIf
Shouldn't the PureBasic IDE run programs like this after compiling, if 'Console' is used as executable format?
User avatar
Shardik
Addict
Addict
Posts: 2059
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Change cursor hovering over HyperLinkGadget (the names of all available system cursors are listed in the data section of this posting):

Code: Select all

EnableExplicit

Procedure ChangeHoverCursor(HyperLinkID.I, CursorName.S)
  Protected AttributeDictionary.I
  Protected MutableAttributeDictionary.I
  Protected NewCursor.I
  
  AttributeDictionary = CocoaMessage(0, GadgetID(HyperLinkID),
    "linkTextAttributes")
  
  If AttributeDictionary
    If CocoaMessage(0, AttributeDictionary, "valueForKey:$", @"NSCursor")
      NewCursor = CocoaMessage(0, 0, "NSCursor " + CursorName)
      
      If NewCursor
        MutableAttributeDictionary = CocoaMessage(0, AttributeDictionary,
          "mutableCopyWithZone:", 0)
        
        If MutableAttributeDictionary
          CocoaMessage(0, MutableAttributeDictionary, "setValue:", NewCursor,
            "forKey:$", @"NSCursor")
          CocoaMessage(0, GadgetID(HyperLinkID), "setLinkTextAttributes:",
            MutableAttributeDictionary)
          CocoaMessage(0, MutableAttributeDictionary, "release")
        EndIf
      EndIf
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 270, 100, 200, 80, "HyperlinkGadgets")
HyperLinkGadget(0, 25, 20, 160, 15, "Default HyperLink cursor", $FF0000, #PB_HyperLink_Underline)
HyperLinkGadget(1, 20, 45, 160, 15, "Modified HyperLink cursor", $FF0000, #PB_HyperLink_Underline)

ChangeHoverCursor(1, "dragLinkCursor")

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
User avatar
Shardik
Addict
Addict
Posts: 2059
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Change several properties of a ToolBar:

Code: Select all

OpenWindow(0, 270, 100, 300, 200, "Change ToolBar properties")

FrameGadget(0, 10, 10, WindowWidth(0) - 20, 50, "Toolbar height:")
OptionGadget(1, 20, GadgetY(0) + 20, 120, 20, "Regular: 24x24")
OptionGadget(2, 160, GadgetY(0) + 20, 120, 20, "Small: 16x16")
SetGadgetState(2, #True)

FrameGadget(3, 10, GadgetY(0) + 60, WindowWidth(0) - 20, 50, "Display:")
OptionGadget(4, 20, GadgetY(3) + 20, 120, 20, "Icon+Label")
OptionGadget(5, 115, GadgetY(3) + 20, 120, 20, "Icon only")
OptionGadget(6, 200, GadgetY(3) + 20, 120, 20, "Label only")
SetGadgetState(5, #True)

CheckBoxGadget(7, 18, GadgetY(3) + 65, WindowWidth(0) - 20, 20,
  "Separator between toolbar and window")
SetGadgetState(7, #True)

CheckBoxGadget(8, 18, GadgetY(7) + 25, WindowWidth(0) - 20, 20,
  "Hide toolbar")

CreateImage(0, 16, 16)

StartDrawing(ImageOutput(0))
  Box(0, 0, 16, 16, $FF0000)
  Box(4, 4, 8, 8, $FFFF)
StopDrawing()

CreateToolBar(0, WindowID(0))
ToolBarImageButton(0, ImageID(0))

; ----- Get item object of ToolBar button and set label to "Demo"
ItemArray = CocoaMessage(0, ToolBarID(0), "items")
Item = CocoaMessage(0, ItemArray, "objectAtIndex:", 0)
CocoaMessage(0, Item, "setLabel:$", @"Demo")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      EventGadget = EventGadget()

      Select EventGadget
        Case 1 To 2
          CocoaMessage(0, ToolBarID(0), "setSizeMode:", EventGadget)
        Case 4 To 6
          CocoaMessage(0, ToolBarID(0), "setDisplayMode:", EventGadget - 3)
        Case 7
          CocoaMessage(0, ToolBarID(0), "setShowsBaselineSeparator:",
            GetGadgetState(7))
        Case 8
          CocoaMessage(0, ToolBarID(0), "setVisible:", GetGadgetState(8) ! 1)
      EndSelect
  EndSelect
ForEver
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

ahh, back to the big toolbar icons!

Thanks Shardik. ..and that was so easy!

Nice example with a couple of other toolbar options too. :)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

Oh, I almost forgot.

wilbert sent me this example of how to select text in an EditorGadget. It can't get much easier than that!

Code: Select all

Range.NSRange

If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EditorGadget(0, 8, 8, 306, 133)
  SetGadgetText(0, "This is a test string to test if selecting" + #CRLF$ + "specific areas will work")
  
  Range\location = 5
  Range\length = 10
  CocoaMessage(0, GadgetID(0), "setSelectedRange:@", @Range)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Since I had several lines in my EditorGadget I used this method to get to the correct position in the text. Here I am searching each line until I find the text then use the selection code. I suppose I could have used GetGadgetText() for all the text in the gadget and searched that way. That might be more direct but that wasn't what I needed to do in this instance. (parsing text as I read from file)

Code: Select all

    offset=1
    For lne=0 To CountGadgetItems(1)-2
        offset+Len(GetGadgetItemText(1,lne))
    Next
    
    selb=FindString(First$,searchfor$,1) : sele=Len(searchfor$)
    Range\location = selb + offset
    Range\length = sele
    CocoaMessage(0, GadgetID(1), "setSelectedRange:@", @Range)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Post Reply