Problems with class

Mac OSX specific forum
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Problems with class

Post by Wolfram »

How can find out or verify whats wrong in these class setup?
I mean why is the callback not triggered?

Code: Select all

ImportC ""
  class_addMethod(Class.I, Selector.I, *Callback, Types.P-ASCII)
  objc_allocateClassPair(ModelClass.I, NewClassName.P-ASCII, ExtraBytes.I)
  objc_registerClassPair(NewClass.I)
  object_setClass(ObjectToModify.I, NewClass.I)
  sel_registerName(MethodName.P-ASCII)
EndImport

Global Window_0, Slider


;sliderType
#NSLinearSlider   =0
#NSCircularSlider =1



ProcedureC drawKnob(obj, sel, x.f, y.f, w.f, h.f, View.i, d1.d,d2.d,d3.d,d4.d, x_.d, y_.d, w_.d, h_.d)
  
  Protected rect.NSRect, radius.CGFloat = 8.0
;   CocoaMessage(0,0,"lockFocus")
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    rect\origin\x = x_
    rect\origin\y = y_
    rect\size\width = w_
    rect\size\height = h_
  CompilerElse
    rect\origin\x = x
    rect\origin\y = y
    rect\size\width = 100
    rect\size\height = 100
  CompilerEndIf
  
    Debug "Knob"
;   CocoaMessage(0, CocoaMessage(0, 0, "NSColor brownColor"), "setFill")
;   CocoaMessage(0, CocoaMessage(0, 0, "NSBezierPath bezierPathWithOvalInRect:@", @rect), "fill")
  
EndProcedure


Procedure OpenWindow_0(x = 0, y = 0, width = 74, height = 140)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Slider = TrackBarGadget(#PB_Any, 20, 45, 32, 34, 1, 127, #PB_TrackBar_Vertical)
  
  SliderCell = CocoaMessage(0, GadgetID(Slider), "cell")
  CocoaMessage(0, SliderCell, "setSliderType:", #NSCircularSlider)
  CocoaMessage(0, SliderCell, "setNumberOfTickMarks:", 10)
  

  CustomSliderCell = objc_allocateClassPair_(CocoaMessage(0, SliderCell, "class"), "CustomSliderCell", 0)
  
 ;I think here is my problem
  ; ----- Set callback for drawing the knob
  class_addMethod_(CustomSliderCell, sel_registerName_("drawInteriorWithFrame:inView:"),
                   @drawKnob(), "v@:{CGRect={CGPoint=dd}{CGSize=dd}}v")
  
  objc_registerClassPair_(CustomSliderCell)
  object_setClass_(SliderCell, CustomSliderCell)
  
  
EndProcedure


Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case #PB_Menu_Quit
          ProcedureReturn #False
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case Slider
;           drawBarInside()
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure

OpenWindow_0()

Repeat
  event = WaitWindowEvent()
Until Window_0_Events(event) = #False

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

Re: Problems with class

Post by Shardik »

Wolfram wrote:How can find out or verify whats wrong in these class setup?
I mean why is the callback not triggered?
The callback is triggered correctly but you have defined the callback to be triggered if the interior of the circular slider has to be repainted. And you are missing in your callback the function call to redraw the knob after having painted the interior of the circular slider. I have modified your example and tested it successfully on OS X 10.9.5 (Mavericks) with PB 5.42 x86 and x64):

Code: Select all

ImportC ""
  class_addMethod(Class.I, Selector.I, *Callback, Types.P-ASCII)
  objc_allocateClassPair(ModelClass.I, NewClassName.P-ASCII, ExtraBytes.I)
  objc_registerClassPair(NewClass.I)
  object_setClass(ObjectToModify.I, NewClass.I)
  sel_registerName(MethodName.P-ASCII)
EndImport

#NSCircularSlider = 1


ProcedureC drawInterior(Obj, Sel, x.f, y.f, w.f, h.f, View.i, d1.d, d2.d, d3.d,
  d4.d, x_.d, y_.d, w_.d, h_.d)
  Protected Rect.NSRect

  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    Rect\origin\x = x_
    Rect\origin\y = y_
    Rect\size\width = w_
    Rect\size\height = h_
  CompilerElse
    Rect\origin\x = x
    Rect\origin\y = y
    Rect\size\width = h
    Rect\size\height = w
  CompilerEndIf

  ; ----- Draw the interior of the circular slider 
  CocoaMessage(0, CocoaMessage(0, 0, "NSColor yellowColor"), "setFill")
  CocoaMessage(0, CocoaMessage(0, 0, "NSBezierPath bezierPathWithOvalInRect:@", @Rect),
    "fill")

  ; ----- Draw default knob
  CocoaMessage(0, View, "lockFocus")
  CocoaMessage(0, Obj, "drawKnob")
  CocoaMessage(0, View, "unlockFocus")
EndProcedure


Procedure OpenWindow_0(x = 0, y = 0, width = 74, height = 53)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Slider = TrackBarGadget(#PB_Any, 20, 10, 32, 32, 0, 10)

  SliderCell = CocoaMessage(0, GadgetID(Slider), "cell")
  CocoaMessage(0, SliderCell, "setSliderType:", #NSCircularSlider)
  CocoaMessage(0, SliderCell, "setNumberOfTickMarks:", 10)

  ; ----- Subclass the slider cell
  CustomSliderCell = objc_allocateClassPair_(CocoaMessage(0, SliderCell, "class"),
    "CustomSliderCell", 0)
  objc_registerClassPair_(CustomSliderCell)
  object_setClass_(SliderCell, CustomSliderCell)

  ; ----- Set callback for drawing the interior of the circular slider
  class_addMethod_(CustomSliderCell,
    sel_registerName_("drawInteriorWithFrame:inView:"),
    @drawInterior(), "v@:{CGRect={CGPoint=dd}{CGSize=dd}}v")
EndProcedure


OpenWindow_0()

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

Re: Problems with class

Post by Wolfram »

Hi, no thats not my problem.
In my example I should get a debugger output and your example does not work on my mac also.

I'm on OSX 10.7. Do you have any idea why it does not work here?
This is happened on circular slider only. On a normal vertical slider it works.
macOS Catalina 10.15.7
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Problems with class

Post by Shardik »

Wolfram wrote:I'm on OSX 10.7. Do you have any idea why it does not work here?
I can confirm that it doesn't work on OS X 10.6.8 (Snow Leopard) and OS X 10.7.5 (Lion) but I have no clue why.

But I have put together another example which doesn't subclass the slider cell but subclasses the modified TrackBarGadget. This second example works on Snow Leopard, Lion and Mavericks although in Snow Leopard and Lion you have to do a click onto the circular slider at first to make the knob visible (afterwards it will stay visible). On Mavericks the knob is visible from the beginning.

Code: Select all

EnableExplicit

#NSCircularSlider = 1

Define CustomSliderClass.I
Define SliderCell.I

ProcedureC DrawRect(Object.I, Selector.I, x.F, y.F, w.F, h.F,
  d1.D, d2.D, d3.D, d4.D, x_.D, y_.D, w_.D, h_.D)
  Shared SliderCell.I

  Protected Rect.NSRect

  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    Rect\origin\x = x_
    Rect\origin\y = y_
    Rect\size\width = w_
    Rect\size\height = h_
  CompilerElse
    Rect\origin\x = x
    Rect\origin\y = y
    Rect\size\width = h
    Rect\size\height = w
  CompilerEndIf

  ; ----- Draw circular slider 
  CocoaMessage(0, CocoaMessage(0, 0, "NSColor yellowColor"), "setFill")
  CocoaMessage(0, CocoaMessage(0, 0,
    "NSBezierPath bezierPathWithOvalInRect:@", @Rect), "fill")

  ; ----- Draw default knob
  CocoaMessage(0, GadgetID(0), "lockFocus")
  CocoaMessage(0, SliderCell, "drawKnob")
  CocoaMessage(0, GadgetID(0), "unlockFocus")
EndProcedure

OpenWindow(0, 270, 100, 74, 53, "")
TrackBarGadget(0, 20, 10, 32, 32, 0, 10)

; ----- Convert TrackBarGadget to circular slider
SliderCell = CocoaMessage(0, GadgetID(0), "cell")
CocoaMessage(0, SliderCell, "setSliderType:", #NSCircularSlider)
CocoaMessage(0, SliderCell, "setNumberOfTickMarks:", 10)

; ----- Subclass the circular slider
CustomSliderClass = objc_allocateClassPair_(CocoaMessage(0,
  GadgetID(0), "class"), "CustomSliderClass", 0)
objc_registerClassPair_(CustomSliderClass)
object_setClass_(GadgetID(0), CustomSliderClass)

; ----- Set callback for drawing the circular slider
class_addMethod_(CustomSliderClass,
  sel_registerName_("drawRect:"),
  @drawRect(), "v@:{CGRect={CGPoint=dd}{CGSize=dd}}")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        Debug GetGadgetState(0)
      EndIf
  EndSelect
ForEver
Post Reply