Image as container background?

Mac OSX specific forum
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Image as container background?

Post by Poshu »

I know how to apply an image as a container background on windows, is it possible to do the same thing on osx?

I *suppose* it should have something to do with CocoaMessage(0, ContainerID, "setBackgroundColor:", CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0))), since pb's container is a subclassed NSBox, but I can't get it to work.
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Image as container background?

Post by Poshu »

aaaaand answered myself (next time, try a few more minutes before asking)

Code: Select all

CocoaMessage(0,gadget,"setFillColor:",CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0)))
It might serves someone ;3
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Image as container background?

Post by Shardik »

Too late...
But you also should have given us the hint that your code only works if the ContainerGadget (NSBox) has a BoxType of NSBoxCustom and a BorderType of NSLineBorder... :wink:

Update: Oh sorry, BoxType NSBoxCustom is PB's default... :oops:
I found several Objective-C examples where the authors fell into that trap !
NSBox Class Reference for setFillColor: wrote:Special Considerations

Functional only when the receiver’s box type (boxType) is NSBoxCustom and its border type (borderType) is NSLineBorder.
I have now tested this on Snow Leopard and Mavericks: the BorderType doesn't matter (0..3 all work) but the BoxType has indeed to be NSBoxCustom...

This is a working code example:

Code: Select all

#NSBoxCustom = 4
#NSLineBorder = 1

UseJPEGImageDecoder()

If LoadImage(0, #PB_Compiler_Home + "Examples/3D/Data/Textures/Clouds.jpg")
  OpenWindow(0, 270, 100, 300, 300, "Container with background image")
  ContainerGadget(0, 10, 10, 280, 280)

  ; ----- When setting a background image for an NSBox (ContainerGadget) the
  ;       BoxType has to be #NSBoxCustom and the BorderType #NSLineBorder !
  CocoaMessage(0, GadgetID(0), "setBoxType:", #NSBoxCustom)
  CocoaMessage(0, GadgetID(0), "setBorderType:", #NSLineBorder)
  ; ----- Set image as background image of ContainerGadget
  CocoaMessage(0, GadgetID(0), "setFillColor:",
    CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0)))

  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Re: Image as container background?

Post by Wolfram »

can you also give a example for setCornerRadius:

Thanks
macOS Catalina 10.15.7
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Image as container background?

Post by Danilo »

Wolfram wrote:can you also give a example for setCornerRadius:

Code: Select all

  CocoaMessage(0, GadgetID(0), "setBoxType:"   , #NSBoxCustom)
  CocoaMessage(0, GadgetID(0), "setBorderType:", #NSLineBorder)

  radius.f = 20.0
  CocoaMessage(0,GadgetID(0),"setCornerRadius:@",@radius)
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Image as container background?

Post by Danilo »

BTW, the background image for container gadget has also a problem when the window
is resize-able.

I wanted to set a pattern image as window background:

Code: Select all

Procedure SetWindowBackgroundPattern(win,imageID)
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
        CocoaMessage(@color,0,"NSColor colorWithPatternImage:",imageID)
        If color
            CocoaMessage(0,WindowID(win),"setBackgroundColor:",color) ; note: pattern begins at the bottom
            CocoaMessage(0,WindowID(win),"update")                    ;       of the window (not good with
            ProcedureReturn color                                     ;       resize-able windows)
        EndIf
    CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
        brush = CreatePatternBrush_(imageID)
        If brush
            SetClassLongPtr_(WindowID(win),#GCL_HBRBACKGROUND,brush)
            InvalidateRect_(WindowID(win),0,#True)
            UpdateWindow_(WindowID(win))
            ProcedureReturn brush
        EndIf
    CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
    CompilerElse
        CompilerError "Unknown Platform for SetWindowBackgroundImage()"
    CompilerEndIf
EndProcedure


CreateImage(1,25,25,24)
If StartDrawing(ImageOutput(1))
    Box(0,0,OutputWidth()  ,OutputHeight()  ,RGB(0,0,0))
    Box(2,2,OutputWidth()-4,OutputHeight()-4,RGB(64,64,64))
    StopDrawing()
EndIf

CreateImage(2,50,50,24)
If StartDrawing(ImageOutput(2))
        For i = 0 To 50 Step 10
            Box(0,i  ,OutputWidth(),5,RGB(180,180,180))
            Box(0,i+5,OutputWidth(),5,RGB(192,192,192))
        Next i
    StopDrawing()
EndIf

CreateImage(3,10,10,24)
If StartDrawing(ImageOutput(3))
    Box(0,0,OutputWidth(),OutputHeight(),RGB(192,192,192))
    Box(OutputWidth()-2,OutputHeight()-2,2,2,RGB(64,64,64))
    StopDrawing()
EndIf


If OpenWindow(1,0,0,800,600,"Window Background Image",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)

    SetWindowBackgroundPattern(1,ImageID(3))
    
    For i = 1 To 10
        ButtonGadget(#PB_Any, 25, 10+i*30, 150, 25, "Button "+Str(i))
    Next i
    
    
    OpenWindow(2,WindowX(1)+WindowWidth(1)-100,WindowY(1)+100,200,150,"Tool Window 1",#PB_Window_Tool|#PB_Window_SizeGadget|#PB_Window_Invisible,WindowID(1))    
    SetWindowBackgroundPattern(2,ImageID(2))
    ButtonGadget(#PB_Any,10,10,180,25,"Button")
    
    OpenWindow(3,WindowX(1)+WindowWidth(1)-150,WindowY(1)+300,300,150,"Tool Window 2",#PB_Window_Tool|#PB_Window_SizeGadget|#PB_Window_Invisible,WindowID(1))    
    SetWindowBackgroundPattern(3,ImageID(1))
    ButtonGadget(#PB_Any,10,10,180,25,"Button")
    
    
    HideWindow(1,0)
    HideWindow(2,0)
    HideWindow(3,0)
    
    
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Works fine with fixed size windows, but on MacOSX the background is scrolling
when you resize the window. It happens because the pattern drawing begins
at the bottom of the window.

Thought now using a container could fix this, but it doesn't. Even more weird,
the container background pattern scrolls just by resizing the window, not
the container itself!

Code: Select all

Procedure SetContainerBackgroundPattern(containerGadget,imageID)
        CocoaMessage(@color,0,"NSColor colorWithPatternImage:",imageID)
        If color
            CocoaMessage(0,GadgetID(containerGadget),"setFillColor:",color)
            ProcedureReturn color
        EndIf
EndProcedure


CreateImage(1,25,25,24)
If StartDrawing(ImageOutput(1))
    Box(0,0,OutputWidth()  ,OutputHeight()  ,RGB(0,0,0))
    Box(2,2,OutputWidth()-4,OutputHeight()-4,RGB(64,64,64))
    StopDrawing()
EndIf

CreateImage(2,50,50,24)
If StartDrawing(ImageOutput(2))
        For i = 0 To 50 Step 10
            Box(0,i  ,OutputWidth(),5,RGB(180,180,180))
            Box(0,i+5,OutputWidth(),5,RGB(192,192,192))
        Next i
    StopDrawing()
EndIf

CreateImage(3,10,10,24)
If StartDrawing(ImageOutput(3))
    Box(0,0,OutputWidth(),OutputHeight(),RGB(192,192,192))
    Box(OutputWidth()-2,OutputHeight()-2,2,2,RGB(64,64,64))
    StopDrawing()
EndIf


If OpenWindow(1,0,0,800,600,"Window Background Image",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
    c1 = ContainerGadget(#PB_Any,0,0,800,600)
    SetContainerBackgroundPattern(c1,ImageID(3))
    
    For i = 1 To 10
        ButtonGadget(#PB_Any, 25, 10+i*30, 150, 25, "Button "+Str(i))
    Next i
    
    
    OpenWindow(2,WindowX(1)+WindowWidth(1)-100,WindowY(1)+100,200,150,"Tool Window 1",#PB_Window_Tool|#PB_Window_SizeGadget|#PB_Window_Invisible,WindowID(1))    
    c2 = ContainerGadget(#PB_Any,0,0,200,150)
    SetContainerBackgroundPattern(c2,ImageID(2))
    ButtonGadget(#PB_Any,10,10,180,25,"Button")
    
    OpenWindow(3,WindowX(1)+WindowWidth(1)-150,WindowY(1)+300,300,150,"Tool Window 2",#PB_Window_Tool|#PB_Window_SizeGadget|#PB_Window_Invisible,WindowID(1))    
    c3 = ContainerGadget(#PB_Any,0,0,300,150)
    SetContainerBackgroundPattern(c3,ImageID(1))
    ButtonGadget(#PB_Any,10,10,180,25,"Button")
    
    
    HideWindow(1,0)
    HideWindow(2,0)
    HideWindow(3,0)
    
    
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Nice for fixed windows, but for resize-able windows this is not useable as is.
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Image as container background?

Post by Poshu »

even with my fixed window, I get some strange results and I've got to shuffle my image to display it in one piece...
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Image as container background?

Post by wilbert »

Danilo wrote:Thought now using a container could fix this, but it doesn't. Even more weird,
the container background pattern scrolls just by resizing the window, not
the container itself!
The documentation of colorWithPatternImage: states The image is tiled starting at the bottom of the window. The image is not scaled.
Although inconvenient, the behavior as you describe it is to be expected.
Maybe you could use setPatternPhase: from the NSGraphicsContext class.
Windows (x64)
Raspberry Pi OS (Arm64)
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Re: Image as container background?

Post by Wolfram »

Danilo wrote:
Wolfram wrote:can you also give a example for setCornerRadius:

Code: Select all

  CocoaMessage(0, GadgetID(0), "setBoxType:"   , #NSBoxCustom)
  CocoaMessage(0, GadgetID(0), "setBorderType:", #NSLineBorder)

  radius.f = 20.0
  CocoaMessage(0,GadgetID(0),"setCornerRadius:@",@radius)
Hi Danilo,

can you explain me why there is a @ behind the "setCornerRadius: "?

Thanks
macOS Catalina 10.15.7
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Image as container background?

Post by Shardik »

Wolfram wrote:Hi Danilo,

can you explain me why there is a @ behind the "setCornerRadius: "?

Thanks
Although I am not Danilo, I try to answer your question... :wink:

In his posting [PB Cocoa] Methods, Tips & Tricks wilbert describes the syntax of CocoaMessage() and also states:
wilbert wrote:When non integer values have to be passed, they can be passed by reference by adding a @ after a colon character.
The PureBasic help for CocoaMessage states:
PureBasic help for CocoaMessage wrote:Method$
The method to call on the object, usually followed by a semicolon (':'). If the method needs a structure as parameter, '@' needs to be appended after the semicolon.
So if you pass a parameter which is not an integer variable (in Danilo's example a float variable) you have to use @ after the semicolon of the method name and @ in front of the following variable name.
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Re: Image as container background?

Post by Poshu »

wilbert wrote:The documentation of colorWithPatternImage: states The image is tiled starting at the bottom of the window. The image is not scaled.
Although inconvenient, the behavior as you describe it is to be expected.
Maybe you could use setPatternPhase: from the NSGraphicsContext class.
Any additional information on that? I have no clue where to start.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Image as container background?

Post by wilbert »

Poshu wrote:Any additional information on that? I have no clue where to start.
I don't get it working that way. An alternative is to change the pattern when the window resizes.
The drawback of this, is that you have to re-set the color of all objects that use the pattern each time the window size changes.

Code: Select all

Global PatternImage.i = CreateImage(#PB_Any, 32, 32, 32, RGB(140, 140, 140))
Global PatternImageAdjusted.i = CopyImage(PatternImage, #PB_Any)

StartDrawing(ImageOutput(PatternImage))
Circle(16, 16, 10, RGB(120, 120, 120))
StopDrawing()


Procedure SizeWindowHandler()
  Protected.i h, w, y
  
  w = EventWindow()
  h = ImageHeight(PatternImage)
  y = WindowHeight(w) % h

  StartDrawing(ImageOutput(PatternImageAdjusted))
  DrawImage(ImageID(PatternImage), 0, -y)
  DrawImage(ImageID(PatternImage), 0, h-y)
  StopDrawing()
  CocoaMessage(0, WindowID(w), "setBackgroundColor:", CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(PatternImageAdjusted)))
  
EndProcedure


OpenWindow(0, 100, 100, 200, 200, "Resize test", #PB_Window_SizeGadget | #PB_Window_SystemMenu)

BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
SizeWindowHandler()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply