[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Applying image filters

Code: Select all

Procedure ApplyImageFilter(Image, Filter)
  If IsImage(Image)
    Protected CIImage, Rep = CocoaMessage(0, CocoaMessage(0, ImageID(Image), "representations"), "objectAtIndex:", 0)
    If CocoaMessage(0, Rep, "isKindOfClass:", CocoaMessage(0, 0, "NSBitmapImageRep class"))
      CIImage = CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "CIImage alloc"), "initWithBitmapImageRep:", Rep), "autorelease")
    Else
      CIImage = CocoaMessage(0, 0, "CIImage imageWithData:", CocoaMessage(0, ImageID(Image), "TIFFRepresentation"))
    EndIf
    Protected ImageRect.NSRect\size\width = ImageWidth(Image) : imageRect\size\height = ImageHeight(Image)
    Protected Delta.CGFloat = 1
    CocoaMessage(0, Filter, "setValue:", CIImage, "forKey:$", @"inputImage")
    CocoaMessage(@CIImage, Filter, "valueForKey:$", @"outputImage")
    StartDrawing(ImageOutput(Image))
    CocoaMessage(0, CIImage, "drawInRect:@", @ImageRect, "fromRect:@", @ImageRect, "operation:", #NSCompositeCopy, "fraction:@", @Delta)
    StopDrawing()
  EndIf
EndProcedure

Procedure ColorControlsFilter(Saturation.f = 1.0, Brightness.f = 0.0, Contrast.f = 1.0)
  Protected Filter = CocoaMessage(0, 0, "CIFilter filterWithName:$", @"CIColorControls")
  CocoaMessage(0, Filter, "setDefaults")
  CocoaMessage(0, Filter, "setValue:", CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Saturation), "forKey:$", @"inputSaturation")
  CocoaMessage(0, Filter, "setValue:", CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Brightness), "forKey:$", @"inputBrightness")
  CocoaMessage(0, Filter, "setValue:", CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Contrast), "forKey:$", @"inputContrast")
  ProcedureReturn Filter
EndProcedure

Procedure GaussianBlurFilter(Radius.f = 2.0)
  Protected Filter = CocoaMessage(0, 0, "CIFilter filterWithName:$", @"CIGaussianBlur")
  CocoaMessage(0, Filter, "setDefaults")
  CocoaMessage(0, Filter, "setValue:", CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Radius), "forKey:$", @"inputRadius")
  ProcedureReturn Filter
EndProcedure

Procedure MonochromeFilter(Red.CGFloat, Green.CGFloat, Blue.CGFloat)
  Protected Filter = CocoaMessage(0, 0, "CIFilter filterWithName:$", @"CIColorMonochrome")
  CocoaMessage(0, Filter, "setDefaults")
  Color = CocoaMessage(0, 0, "CIColor colorWithRed:@", @Red, "green:@", @Green, "blue:@", @Blue)
  CocoaMessage(0, Filter, "setValue:", Color, "forKey:$", @"inputColor")
  ProcedureReturn Filter
EndProcedure



UsePNGImageDecoder()

If OpenWindow(0, 0, 0, 180, 100, "CIFilter example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  If LoadImage(0, #PB_Compiler_Home + "Examples/3D/Data/Textures/Caisse.png")
    ApplyImageFilter(0, MonochromeFilter(1.0, 0.7, 0.3))
    ApplyImageFilter(0, GaussianBlurFilter(1.0))
    ImageGadget(0,  10, 10, 64, 64, ImageID(0))
  EndIf
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Programmatically scroll row or column into visible part of ListIconGadget:

Code: Select all

EnableExplicit

#NumberOfColumns = 10
#NumberOfRows    = 10

Define ColumnIndex.I
Define RowIndex.I
Define RowText.S
Define SelectedGadget.I

OpenWindow(0, 200, 100, 346, 200, "ListIcon Example")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, 90, "Column 1", 100, #PB_ListIcon_GridLines)

For ColumnIndex = 2 To #NumberOfColumns
  AddGadgetColumn(0, ColumnIndex - 1, "Column " + Str(ColumnIndex), 100)
Next ColumnIndex

For RowIndex = 1 To #NumberOfRows
  RowText = ""

  For ColumnIndex = 1 To #NumberOfColumns
    RowText + "Row " + Str(RowIndex) + ", Col " + Str(ColumnIndex)

    If ColumnIndex < #NumberOfColumns
      RowText + #LF$
    EndIf
  Next ColumnIndex

  AddGadgetItem(0, -1, RowText)
Next RowIndex

SetGadgetState(0, -1)

SpinGadget(1, 80, GadgetY(0) + GadgetHeight(0) + 60, 45, 20, 1, #NumberOfRows, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState(1, 1)
SpinGadget(2, 220, GadgetY(0) + GadgetHeight(0) + 60, 45, 20, 1, #NumberOfColumns, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState(2, 1)
TextGadget(3, 30, GadgetY(0) + GadgetHeight(0) + 20, 130, 40, "Scroll row into visible area:", #PB_Text_Center)
TextGadget(4, 170, GadgetY(0) + GadgetHeight(0) + 20, 140, 40, "Scroll column into visible area:", #PB_Text_Center)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          CocoaMessage(0, GadgetID(0), "scrollRowToVisible:", GetGadgetState(1) - 1)
        Case 2
          CocoaMessage(0, GadgetID(0), "scrollColumnToVisible:", GetGadgetState(2) - 1)
      EndSelect
  EndSelect
ForEver
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

Thanks Shardik!
Programmatically scroll row or column into visible part of ListIconGadget:
Works fine on ListViewGadget too! I can use this... :)
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

WilliamL wrote:Thanks Shardik!
Programmatically scroll row or column into visible part of ListIconGadget:
Works fine on ListViewGadget too! I can use this... :)
ExplorerListGadget, ListIconGadget and ListViewGadget are all three built upon the same Cocoa class (NSTableView).
That's why you can use some tips & tricks for all three of them.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

So... is this the easiest (shortest) way to get a right-click from a Button and a ListView gadget?

Code: Select all

#NSFlagsChanged       = 12
#NSControlKeyMask    = 1 << 18

Global sharedApplication = CocoaMessage(0, 0, "NSApplication sharedApplication")
Define currentEvent, type, modifierFlags


If OpenWindow(0, 0, 0, 320, 170, "Test modifierFlags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
    ListViewGadget(0, 10, 10, 300, 100)
    For type=1 To 5
        AddGadgetItem(0, -1, "line "+Str(type))
    Next
    
    ButtonGadget(1, 10,120, 100,  25, "Button",#PB_Button_Default)
  
  Repeat
    Event = WaitWindowEvent() ; comes first in loop

    currentEvent = CocoaMessage(0, sharedApplication, "currentEvent")
    If currentEvent
        type = CocoaMessage(0, currentEvent, "type")
        If type = #NSFlagsChanged
            modifierFlags = CocoaMessage(0, currentEvent, "modifierFlags") 
        EndIf
    EndIf
   
    If Event = #PB_Event_Gadget
      Select EventGadget()
        Case 1
          If modifierFlags & #NSControlKeyMask
              SetGadgetItemText(0, 0, "Right-click button") ; "Ctrl key is pressed")
          Else
              SetGadgetItemText(0, 0, "Left-click button")
          EndIf
      Case 0
          lne=GetGadgetState(0)
          If modifierFlags & #NSControlKeyMask
              SetGadgetItemText(0, 0, "Right-click on line "+Str(lne)) ; "Ctrl key is pressed")
          Else
              SetGadgetItemText(0, 0, "Left-click on line "+Str(lne))
          EndIf
        EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
EndIf
[edited per wilbert's suggestion below]
Last edited by WilliamL on Sun Oct 21, 2012 9:31 pm, edited 1 time in total.
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

@William, do you need to detect ctrl + left button click or really the right mouse button ?
The problem with the right mouse button is that it doesn't generate a #PB_Event_Gadget so you would need to get the mouse coordinates and check if the gadget is underneath that coordinates.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

Yep, you're right wilbert. I have to laugh, I've used the ctrl+trackpad click for so long that I forgot about the actual right button! Well, I'm not going to hash out all the possibilities of the right button, I was just asking if this code was optimal for what it does. I'll be ctrl+left clicking for quite a while yet. :)

(I'd still like a right-click event for the ListView gadget)
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

WilliamL wrote:I was just asking if this code was optimal for what it does.
Your code works fine.
I found out it's better to put Event = WaitWindowEvent() before the code that gets currentEvent instead afterwards so maybe you can change the order of those.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Turn TrackBarGadget into a fixed size circular slider.

Code: Select all

If OpenWindow(0, 0, 0, 200, 100, "TrackBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  TrackBarGadget(0, 10, 10, 36, 36, 0, 12)
  Cell = CocoaMessage(0, GadgetID(0), "cell")
  CocoaMessage(0, Cell, "setSliderType:", 1); circular slider
  CocoaMessage(0, Cell, "setNumberOfTickMarks:", 12)
  CocoaMessage(0, Cell, "setAllowsTickMarkValuesOnly:", #YES)
  
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget
      If EventGadget() = 0
        Debug GetGadgetState(0)
      EndIf
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by grabiller »

Hey wilbert,

I'm looking for a way to create and attach a OpenGL context to any PB window (including gadget 'windows').

I have it working on Windows and Linux, using respectively WGL and GLX, and I had this code for Carbon/AGL:
http://www.purebasic.fr/french/viewtopi ... 725#p94725

How would I do the same (including the swap buffer command) with Cocoa windows ?

From what I understand I would have to use CGL (Core OpenGL) knowing that Cocoa classes supporting OpenGL and AGL are built on top of CGL. But then which one should I use ?

It seems CGL functions are relatively in line with WGL and GLX, but so is AGL, so I'm a bit lost for Mac OSX. Why the need of AGL having CGL ?

Anyway, I would love to see a working example on how to setup a OpenGL context from any PB window, then be able to use standard OpenGL functions on it.
guy rabiller | radfac founder / ceo | raafal.org
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

grabiller wrote:I'm looking for a way to create and attach a OpenGL context to any PB window (including gadget 'windows').
Doesn't OpenWindowedScreen() do that ?
http://www.purebasic.fr/english/viewtop ... 12&t=49583
Another way might be using the NSOpenGLView class but that seems kind of complicated so if OpenWindowedScreen would provide a context that would be an easier solution.
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by grabiller »

AGL is 32 bit only.

We are allowed to only one WindowedScreen, not sure why, so this is useless to me as I'll need several 'viewports'.

Yet I have no control on how the OpenGL context is created.

I think there is a way to use CGL (Core GL) directly without the need to use Cocoa NS views and messaging system.

I'll investigate.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

List all available printers:

Code: Select all

PrinterArray = CocoaMessage(0, 0, "NSPrinter printerNames")

If PrinterArray
  NumberOfPrinters = CocoaMessage(0, PrinterArray, "count")

  For i = 0 To NumberOfPrinters - 1
    PrinterNames$ + PeekS(CocoaMessage(0, CocoaMessage(0, PrinterArray, "objectAtIndex:", i), "UTF8String"), -1, #PB_UTF8) + #CR$
  Next i

  MessageRequester("Available Printers:", PrinterNames$)
EndIf
Get current page settings:

Code: Select all

#NSPortraitOrientation  = 0
#NSLandscapeOrientation = 1

Define BottomMargin.CGFloat
Define LeftMargin.CGFloat
Define PageSettings.S
Define RightMargin.CGFloat
Define TopMargin.CGFloat

PrintInfo = CocoaMessage(0, 0, "NSPrintInfo sharedPrintInfo")

PageSettings + "Paper name: " + PeekS(CocoaMessage(0, CocoaMessage(0, PrintInfo, "localizedPaperName"), "UTF8String"), -1, #PB_UTF8) + #CR$

If CocoaMessage(0, PrintInfo, "orientation") = #NSPortraitOrientation
  PageSettings + "Orientation: portrait" + #CR$
Else
  PageSettings + "Orientation: landscape" + #CR$
EndIf

CocoaMessage(@LeftMargin, PrintInfo, "leftMargin")
PageSettings + "Left margin: " + StrF(LeftMargin, 1) + #CR$
CocoaMessage(@RightMargin, PrintInfo, "rightMargin")
PageSettings + "Right margin: " + StrF(RightMargin, 1) + #CR$
CocoaMessage(@TopMargin, PrintInfo, "topMargin")
PageSettings + "Top margin: " + StrF(TopMargin, 1) + #CR$
CocoaMessage(@BottomMargin, PrintInfo, "bottomMargin")
PageSettings + "Bottom margin: " + StrF(BottomMargin, 1) + #CR$

MessageRequester("Current page settings:", PageSettings)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Display all available system cursors:

Code: Select all

EnableExplicit

Define CursorName.S
Define i.I
Define NewCursor.I
Define NumCursors.I

NewList CursorName.S()

OpenWindow(0, 200, 100, 300, 100, "Display all available system cursors")
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
ButtonGadget(0, WindowWidth(0) / 2 - 80, 30, 160, 25, "Change cursor")

If OSVersion() < #PB_OS_MacOSX_10_3
  NumCursors = 2
ElseIf OSVersion() < #PB_OS_MacOSX_10_5
  NumCursors = 13
ElseIf OSVersion() < #PB_OS_MacOSX_10_6
  NumCursors = 14
ElseIf OSVersion() < #PB_OS_MacOSX_10_7
  NumCursors = 17
Else
  NumCursors = 18
EndIf

For i = 1 To NumCursors
  AddElement(CursorName())
  Read.S CursorName()
Next i

FirstElement(CursorName())
StatusBarText(0, 0, "Current cursor: " + CursorName(), #PB_StatusBar_Center)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        If NextElement(CursorName()) = 0
          FirstElement(CursorName())
        EndIf

        StatusBarText(0, 0, "Current cursor: " + CursorName())

        NewCursor = CocoaMessage(0, 0, "NSCursor " + CursorName())
        CocoaMessage(0, NewCursor, "set")
      EndIf
  EndSelect
ForEver

End

DataSection
  Data.S "arrowCursor"
  Data.S "IBeamCursor"
  Data.S "crosshairCursor"
  Data.S "closedHandCursor"
  Data.S "openHandCursor"
  Data.S "pointingHandCursor"
  Data.S "resizeLeftCursor"
  Data.S "resizeRightCursor"
  Data.S "resizeLeftRightCursor"
  Data.S "resizeUpCursor"
  Data.S "resizeDownCursor"
  Data.S "resizeUpDownCursor"
  Data.S "disappearingItemCursor"
  Data.S "operationNotAllowedCursor"
  Data.S "dragLinkCursor"
  Data.S "dragCopyCursor"
  Data.S "contextualMenuCursor"
  Data.S "IBeamCursorForVerticalLayout"
EndDataSection
Update: I have added 4 additional system cursors and changed the code to display correctly the available system cursors from OS X 10.0 to 10.8. These are the number of available system cursors for the different OS X versions:

Code: Select all

10.0-10.2:  2
10.3-10.4: 13
10.5     : 14
10.6     : 17
10.7-10.8: 18
It's always better to take a look into the header files (NSCursor.h) than into the reference manuals... :wink:
Last edited by Shardik on Tue Nov 13, 2012 11:56 pm, edited 1 time in total.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

Good find Shardik!

I expected to see all the same cursors as with Carbon but I don't see the spinning ball or watch. I need something that looks like the computer is busy. Odd that those two aren't there. Maybe the NSObject is mainly for text input and those wouldn't be needed.

Sorry, you get a good api addition and I just want more. :wink:

https://developer.apple.com/library/mac ... rence.html
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
Post Reply