[SOLVED] NSAlert as a sheet: How to handle the result?

Mac OSX specific forum
ergrull0
User
User
Posts: 23
Joined: Sat Mar 08, 2014 4:45 pm

[SOLVED] NSAlert as a sheet: How to handle the result?

Post by ergrull0 »

Hello guys! I would like to implement a NSAlert and showing it as a sheet but I'm stuck at this point. Take a look at this example:

Code: Select all

OpenWindow(0, 0, 0, 480, 320, "AlertSheet Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 180, 25, "Test sheet!")
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Alert = CocoaMessage(0, CocoaMessage(0, 0, "NSAlert new"), "autorelease")
      CocoaMessage(0, Alert, "addButtonWithTitle:$", @"OK")
      CocoaMessage(0, Alert, "addButtonWithTitle:$", @"Cancel")
      CocoaMessage(0, Alert, "setMessageText:$", @"This is a message")
      CocoaMessage(0, Alert, "setInformativeText:$", @"This is an informative text")
      CocoaMessage(0, 
                   Alert, 
                   "beginSheetModalForWindow:",  WindowID(0), 
                   "modalDelegate:", 0, ; <====== What to put here instead of 0?
                   "didEndSelector:", 0, ; <======  here?
                   "contextInfo:", 0); <========== and here?      
      
  EndSelect
ForEver
The sheet opens and closes but I don't know how to handle the result to know which button has been pressed. Any clue?

Thanks!
Last edited by ergrull0 on Sat Mar 22, 2014 1:49 pm, edited 1 time in total.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: NSAlert as a sheet: How to handle the result?

Post by Shardik »

Code: Select all

EnableExplicit

#NSAlertFirstButtonReturn  = 1000
#NSAlertSecondButtonReturn = 1001

ImportC ""
  sel_registerName(MethodName.P-UTF8)
  class_addMethod(Class.I, Selector.I, Implementation.I, Types.P-UTF8)
EndImport

Define Alert.I
Define AppDelegate.I
Define Selector.I

ProcedureC AlertCallback(Object.I, Selector.I, Alert.I, ButtonType.I, ContextInfo.I)
  Select ButtonType
    Case #NSAlertFirstButtonReturn
      Debug "OK button was selected"
    Case #NSAlertSecondButtonReturn
      Debug "Cancel button was selected"
  EndSelect
EndProcedure

Procedure DefineAlert()
  Shared Alert.I
  Shared Selector.I
  Shared AppDelegate.I

  Alert = CocoaMessage(0, 0, "NSAlert new")
  AppDelegate = CocoaMessage(0,
    CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
  Selector = sel_registerName("alert:returnCode:contextInfo")
  class_addMethod(CocoaMessage(0, AppDelegate, "class"),
    Selector, @AlertCallback(), "v@:@@@")
  CocoaMessage(0, Alert, "setDelegate:", AppDelegate)
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"OK")
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"Cancel")
  CocoaMessage(0, Alert, "setMessageText:$", @"This is a message")
  CocoaMessage(0, Alert, "setInformativeText:$", @"This is an informative text")
EndProcedure

OpenWindow(0, 270, 100, 480, 320, "AlertSheet Test")
ButtonGadget(0, 10, 10, 180, 25, "Test sheet!")

DefineAlert()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        CocoaMessage(0, Alert,
          "beginSheetModalForWindow:", WindowID(0),
          "modalDelegate:", AppDelegate,
          "didEndSelector:", Selector,
          "contextInfo:", 0)
      EndIf
  EndSelect
ForEver
ergrull0
User
User
Posts: 23
Joined: Sat Mar 08, 2014 4:45 pm

Re: NSAlert as a sheet: How to handle the result?

Post by ergrull0 »

Shardik wrote:

Code: Select all

...
You're amazing!!! Thanks again! :mrgreen:
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: NSAlert as a sheet: How to handle the result?

Post by Shardik »

One small update:

It seems that PureBasic 5.21 still contains a bug in pseudotype P-UTF8 because the pseudotype conversion into UTF-8 throws an invalid memory error when using the PB x86 compiler in ASCII and Unicode mode. The PB x64 compiler works alright. Therefore I had to add the procedure ConvertToUTF8() as a workaround to circumvent the P-UTF8 conversion problems in compiling x86 code. Here I have posted a bug report.

Code: Select all

EnableExplicit

#NSAlertFirstButtonReturn  = 1000
#NSAlertSecondButtonReturn = 1001

ImportC ""
  sel_registerName(MethodName.S)
  class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
EndImport

Define Alert.I
Define AppDelegate.I
Define Selector.I

Procedure.S ConvertToUTF8(String.S)
  Protected UTF8String.S = Space(StringByteLength(String))
  PokeS(@UTF8String, String, -1, #PB_UTF8)
  ProcedureReturn UTF8String
EndProcedure

ProcedureC AlertCallback(Object.I, Selector.I, Alert.I, ButtonType.I, ContextInfo.I)
  Select ButtonType
    Case #NSAlertFirstButtonReturn
      Debug "OK button was selected"
    Case #NSAlertSecondButtonReturn
      Debug "Cancel button was selected"
  EndSelect
EndProcedure

Procedure DefineAlert()
  Shared Alert.I
  Shared Selector.I
  Shared AppDelegate.I

  Alert = CocoaMessage(0, 0, "NSAlert new")
  AppDelegate = CocoaMessage(0,
    CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
  Selector = sel_registerName(ConvertToUTF8("alert:returnCode:contextInfo"))
  class_addMethod(CocoaMessage(0, AppDelegate, "class"),
    Selector, @AlertCallback(), ConvertToUTF8("v@:@@@"))
  CocoaMessage(0, Alert, "setDelegate:", AppDelegate)
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"OK")
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"Cancel")
  CocoaMessage(0, Alert, "setMessageText:$", @"This is a message")
  CocoaMessage(0, Alert, "setInformativeText:$", @"This is an informative text")
EndProcedure

OpenWindow(0, 270, 100, 480, 320, "AlertSheet Test")
ButtonGadget(0, 10, 10, 180, 25, "Test sheet!")

DefineAlert()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        CocoaMessage(0, Alert,
          "beginSheetModalForWindow:", WindowID(0),
          "modalDelegate:", AppDelegate,
          "didEndSelector:", Selector,
          "contextInfo:", 0)
      EndIf
  EndSelect
ForEver
ergrull0
User
User
Posts: 23
Joined: Sat Mar 08, 2014 4:45 pm

Re: [SOLVED] NSAlert as a sheet: How to handle the result?

Post by ergrull0 »

ok I've just finished a sort of include for creating NSAlert sheets on the fly and a test code for testing its implementation.

File: NSAlert.pbi

Code: Select all

EnableExplicit

;--- Custom NSAlert Event Definition
Enumeration 1000
  #NSAlert_Button_OK
  #NSAlert_Button_Cancel
EndEnumeration

#NSAlertFirstButtonReturn  = 1000
#NSAlertSecondButtonReturn = 1001

ImportC ""
  sel_registerName(MethodName.S)
  class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
EndImport

Define Alert.I
Define AppDelegate.I
Define Selector.I

Procedure.S ConvertToUTF8(String.S)
  Protected UTF8String.S = Space(StringByteLength(String))
  PokeS(@UTF8String, String, -1, #PB_UTF8)
  ProcedureReturn UTF8String
EndProcedure

ProcedureC AlertCallback(Object.I, Selector.I, Alert.I, ButtonType.I, ContextInfo.I)
  Select ButtonType
    Case #NSAlertFirstButtonReturn
      PostEvent(#NSAlert_Button_OK) ; Post the OK button event
    Case #NSAlertSecondButtonReturn
      PostEvent(#NSAlert_Button_Cancel) ; Post the Cancel button event
  EndSelect
EndProcedure

Procedure NSAlertBeginSheet(ParentWindow.I, Message.S, InformativeText.S)
  Shared Alert.I
  Shared Selector.I
  Shared AppDelegate.I
  
  Alert = CocoaMessage(0, 0, "NSAlert new")
  
  AppDelegate = CocoaMessage(0,CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
  
  Selector = sel_registerName(ConvertToUTF8("alert:returnCode:contextInfo"))
  
  class_addMethod(CocoaMessage(0, AppDelegate, "class"), Selector, @AlertCallback(), ConvertToUTF8("v@:@@@"))
  
  CocoaMessage(0, Alert, "setDelegate:", AppDelegate)
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"OK")
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"Cancel")
  CocoaMessage(0, Alert, "setMessageText:$", @Message)
  CocoaMessage(0, Alert, "setInformativeText:$", @InformativeText)
  
  CocoaMessage(0, Alert,
               "beginSheetModalForWindow:", WindowID(ParentWindow),
               "modalDelegate:", AppDelegate,
               "didEndSelector:", Selector,
               "contextInfo:", 0)
  
EndProcedure
File: test.pb

Code: Select all

IncludeFile("NSAlert.pbi")

Define MessageID.I

OpenWindow(0, 240, 100, 380, 40, "AlertSheet Test")
ButtonGadget(0, 10, 10, 180, 25, "First message")
ButtonGadget(1, 190, 10, 180, 25, "Second message")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          ;-Setting up the first alert
          MessageID = 0 
          NSAlertBeginSheet(0, "First message", "First informative text")
        Case 1
          ;-Setting up the second alert
          MessageID = 1
          NSAlertBeginSheet(0, "Second message", "Second informative text")
      EndSelect
    Case #NSAlert_Button_OK ;-Was the OK button pressed?
      Select MessageID
        Case 0
          Debug "You answered OK to the first message"
        Case 1
          Debug "You answered OK to the second message"
      EndSelect
    Case #NSAlert_Button_Cancel ;-Was the Cancel button pressed?
      Select MessageID
        Case 0
          Debug "You answered Cancel to the first message"
        Case 1
          Debug "You answered Cancel to the second message"
      EndSelect      
  EndSelect
ForEver
Tell me what you think and feel free to enhance it... :mrgreen:
Post Reply