Using Cooca Tips and tricks in real life

Mac OSX specific forum
madscientist
New User
New User
Posts: 4
Joined: Fri Aug 10, 2018 3:55 pm

Using Cooca Tips and tricks in real life

Post by madscientist »

I notice many of the examples, particularly those that use repainting methods , will not work where there is more then one object on the window

SetGadgetItemColor being a case in point , the workaround can only support a single instance of an icon list view and the icon list view needs to be forced to repaint to properly update the colours and I cant easily see how thats done in PB

fine for what it is, but its not a viable workaround in real life
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Using Cooca Tips and tricks in real life

Post by Shardik »

madscientist wrote:SetGadgetItemColor being a case in point , the workaround can only support a single instance of an icon list view and the icon list view needs to be forced to repaint to properly update the colours and I cant easily see how thats done in PB
With which workaround exactly do you have difficulties? I have posted an example for both a ListIconGadget and a ListViewGadget. It would have been nice if you would have posted at least a link to that example...

You are right that the posted SetGadgetItemColor() workaround for the ListIconGadget doesn't work with multiple ListIconGadgets. I try to keep my examples as easy as possible and implementing it for multiple ListIconGadgets would make the example more complex. I demonstrate the essential parts and hope that other users in this forum are able to adapt them to their needs. We are all programmers - aren't we?
madscientist wrote:fine for what it is, but its not a viable workaround in real life
Why you are whining and complaining about my workarounds? If you try to enhance them and have difficulties: why don't you send me a PM like other users in this forum have already done or open a thread like this one asking for help with your modified code example and not insulting my workarounds? I am always trying to help any interested user but I hesitate to help if somebody speaks of "not a viable workaround in real life" because he isn't able to enhance my code but doesn't even care to ask for help? By the way, I am using a similar workaround in production code (for a single large ListIconGadget) since May 2016 and I never experienced any difficulties!

Nevertheless, for all users needing the SetGadgetItemColor() workaround for multiple ListIconGadgets I have extended my workaround (tested successfully on MacOS 10.6.8 'Snow Leopard' with PB 5.62 x86 and on MacOS 10.13.6 'High Sierra' with PB 5.62 x86 and x64). As a solution I use the LinkedList ListIcon() with a CellColor array. For each call of SetGadgetItemColor() is now checked whether the ListIconGadget has an entry in the LinkedList ListIcon() and if not, a new entry with a new CellColor array will be added. Only the CellColor array of the respective ListIcon entry in the LinkedList will be modified.

Code: Select all

EnableExplicit

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define i.I
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define Selector.I = sel_registerName_("tableView:willDisplayCell:" +
  "forTableColumn:row:")

Structure CellColorEntry
  Object.I
  Array CellColor.Q(0, 0)
EndStructure

NewList ListIcon.CellColorEntry()

ProcedureC CellDisplayCallback(Object.I, Selector.I, TableView.I, Cell.I,
  *Column, Row.I)
  Shared ListIcon.CellColorEntry()

  Protected Alpha.CGFloat
  Protected BackColor.L
  Protected Blue.CGFloat
  Protected CellColor.Q
  Protected Column.I
  Protected FrontColor.L
  Protected Green.CGFloat
  Protected ListIconFound.I
  Protected Red.CGFloat

  ForEach ListIcon()
    If ListIcon()\Object = TableView
      ListIconFound = #True
      Break
    EndIf
  Next

  If ListIconFound = #True
    Column = Val(PeekS(CocoaMessage(0, CocoaMessage(0, *Column, "identifier"),
      "UTF8String"), -1, #PB_UTF8))
    CellColor = ListIcon()\CellColor(Row, Column)

    If CellColor = 0
      CocoaMessage(0, Cell, "setDrawsBackground:", #NO)
      CocoaMessage(0, Cell, 
        "setTextColor:", CocoaMessage(0, 0, "NSColor blackColor"))
    Else
      BackColor = CellColor & $FFFFFF

      If BackColor = 0
        CocoaMessage(0, Cell, "setDrawsBackground:", #NO)
      Else
        CocoaMessage(0, Cell, "setDrawsBackground:", #YES)
        Alpha = 1
        Red = Red(BackColor) / 255
        Green = Green(BackColor) / 255
        Blue = Blue(BackColor) / 255
        CocoaMessage(0, Cell, "setBackgroundColor:", CocoaMessage(0, 0,
          "NSColor colorWithDeviceRed:@", @Red,
          "green:@", @Green,
          "blue:@", @Blue,
          "alpha:@", @Alpha))
      EndIf

      FrontColor = (CellColor >> 32) & $FFFFFF

      If FrontColor = 0
        CocoaMessage(0, Cell, 
          "setTextColor:", CocoaMessage(0, 0, "NSColor blackColor"))
      Else
        Alpha = 1
        Red = Red(FrontColor) / 255
        Green = Green(FrontColor) / 255
        Blue = Blue(FrontColor) / 255
        CocoaMessage(0, Cell, "setTextColor:", CocoaMessage(0, 0,
          "NSColor colorWithDeviceRed:@", @Red,
          "green:@", @Green,
          "blue:@", @Blue,
          "alpha:@", @Alpha))
      EndIf
    EndIf
  EndIf
EndProcedure

Procedure SetGadgetItemColorEx(GadgetID.I, Row.I, ColorType.I, Color.I,
  Column.I)
  Shared ListIcon.CellColorEntry()

  Protected CellColor.Q
  Protected ColumnCount.I
  Protected ListIconFound.I
  Protected RowCount.I

  If ListSize(ListIcon()) > 0
    ForEach ListIcon()
      If ListIcon()\Object = GadgetID(GadgetID)
        ListIconFound = #True
        Break
      EndIf
    Next
  EndIf

  If ListSize(ListIcon()) = 0 Or ListIconFound = #False
    AddElement(ListIcon())
    ListIcon()\Object = GadgetID(GadgetID)
    ColumnCount = CocoaMessage(0, GadgetID(GadgetID), "numberOfColumns")
    RowCount = CocoaMessage(0, GadgetID(GadgetID), "numberOfRows")
    Dim ListIcon()\CellColor(RowCount - 1, ColumnCount - 1)
  EndIf

  CellColor = ListIcon()\CellColor(Row, Column)

  Select ColorType
    Case #PB_Gadget_BackColor
      CellColor ! (Color & $FFFFFF)
    Case #PB_Gadget_FrontColor
      CellColor ! ((Color & $FFFFFF) << 32)
  EndSelect

  ListIcon()\CellColor(Row, Column) = CellColor
EndProcedure

Macro SetGadgetItemColor(GadgetID, Row, ColorType, Color, Column)
  SetGadgetItemColorEx(GadgetID, Row, ColorType, Color, Column)
EndMacro

OpenWindow(0, 200, 100, 430, 205,
  "Change color of text and background in single cells")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, 85, "Name",
  100, #PB_ListIcon_GridLines)
ListIconGadget(1, 10, 110, WindowWidth(0) - 20, 85, "Name",
  100, #PB_ListIcon_GridLines)
class_addMethod_(DelegateClass, Selector, @CellDisplayCallback(), "v@:@@@@")

For i = 0 To 1
  AddGadgetColumn(i, 1, "Address",
    GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
    #PB_ListIcon_ColumnWidth) - 8)
  AddGadgetItem(i, -1, "Harry Rannit" + #LF$ +
    "12 Parliament Way, Battle Street, By the Bay")
  AddGadgetItem(i, -1, "Ginger Brokeit" + #LF$ +
    "130 PureBasic Road, BigTown, CodeCity")
  AddGadgetItem(i, -1, "Didi Foundit" + #LF$ +
    "321 Logo Drive, Mouse House, Downtown")
  CocoaMessage(0, GadgetID(i), "setDelegate:", AppDelegate)
Next i

; ----- Set background color of cell 2,0 in ListIcon 0 to yellow
SetGadgetItemColor(0, 2, #PB_Gadget_BackColor, $FFFF, 0)

; ----- Set background color of cell 1,1 in ListIcon 1 to X11 color
;       "Aquamarine"
SetGadgetItemColor(1, 1, #PB_Gadget_BackColor, $D4FF7F, 1)

; ----- Set text color of cell 0,0 in ListIcon 0 to blue
SetGadgetItemColor(0, 0, #PB_Gadget_FrontColor, $FF0000, 0)

; ----- Set text color of cell 1,1 In ListIcon 1 to red
SetGadgetItemColor(1, 1, #PB_Gadget_FrontColor, $FF, 1)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by Shardik on Fri Sep 28, 2018 8:29 pm, edited 1 time in total.
Mindphazer
Enthusiast
Enthusiast
Posts: 340
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: Using Cooca Tips and tricks in real life

Post by Mindphazer »

Yeaaaah !!!
Thank you Shardik, you made my day !
MacBook Pro 14" M1 Pro - 16 Gb - MacOS 14 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Using Cooca Tips and tricks in real life

Post by Shardik »

And here is the extended SetGadgetItemColor() workaround for the ListViewGadget that allows using multiple ListViewGadgets (the code posted in [PB Cocoa] Methods, Tips & Tricks only supports a single ListViewGadget):

Code: Select all

EnableExplicit

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define i.I
Define Selector.I = sel_registerName_("tableView:willDisplayCell:" +
  "forTableColumn:row:")

Structure CellColorEntry
  Object.I
  Array CellColor.Q(0)
EndStructure

NewList ListView.CellColorEntry()

ProcedureC CellDisplayCallback(Object.I, Selector.I, TableView.I, Cell.I,
  *Column, Row.I)
  Shared ListView.CellColorEntry()

  Protected Alpha.CGFloat
  Protected BackColor.L
  Protected Blue.CGFloat
  Protected CellColor.Q
  Protected FrontColor.L
  Protected Green.CGFloat
  Protected ListViewFound.I
  Protected Red.CGFloat

  ForEach ListView()
    If ListView()\Object = TableView
      ListViewFound = #True
      Break
    EndIf
  Next

  If ListViewFound = #True
    CellColor = ListView()\CellColor(Row)

    If CellColor = 0
      CocoaMessage(0, Cell, "setDrawsBackground:", #NO)
      CocoaMessage(0, Cell, 
        "setTextColor:", CocoaMessage(0, 0, "NSColor blackColor"))
    Else
      BackColor = CellColor & $FFFFFF

      If BackColor = 0
        CocoaMessage(0, Cell, "setDrawsBackground:", #NO)
      Else
        CocoaMessage(0, Cell, "setDrawsBackground:", #YES)
        Alpha = 1
        Red = Red(BackColor) / 255
        Green = Green(BackColor) / 255
        Blue = Blue(BackColor) / 255
        CocoaMessage(0, Cell, "setBackgroundColor:", CocoaMessage(0, 0,
          "NSColor colorWithDeviceRed:@", @Red,
          "green:@", @Green,
          "blue:@", @Blue,
          "alpha:@", @Alpha))
      EndIf

      FrontColor = (CellColor >> 32) & $FFFFFF

      If FrontColor = 0
        CocoaMessage(0, Cell, 
          "setTextColor:", CocoaMessage(0, 0, "NSColor blackColor"))
      Else
        Alpha = 1
        Red = Red(FrontColor) / 255
        Green = Green(FrontColor) / 255
        Blue = Blue(FrontColor) / 255
        CocoaMessage(0, Cell, "setTextColor:", CocoaMessage(0, 0,
          "NSColor colorWithDeviceRed:@", @Red,
          "green:@", @Green,
          "blue:@", @Blue,
          "alpha:@", @Alpha))
      EndIf
    EndIf
  EndIf
EndProcedure

Procedure SetGadgetItemColorEx(GadgetID.I, Row.I, ColorType.I, Color.I)
  Shared ListView.CellColorEntry()

  Protected CellColor.Q
  Protected ListViewFound.I
  Protected RowCount.I

  If ListSize(ListView()) > 0
    ForEach ListView()
      If ListView()\Object = GadgetID(GadgetID)
        ListViewFound = #True
        Break
      EndIf
    Next
  EndIf

  If ListSize(ListView()) = 0 Or ListViewFound = #False
    AddElement(ListView())
    ListView()\Object = GadgetID(GadgetID)
    RowCount = CocoaMessage(0, GadgetID(GadgetID), "numberOfRows")
    Dim ListView()\CellColor(RowCount - 1)
  EndIf

  CellColor = ListView()\CellColor(Row)

  Select ColorType
    Case #PB_Gadget_BackColor
      CellColor ! (Color & $FFFFFF)
    Case #PB_Gadget_FrontColor
      CellColor ! ((Color & $FFFFFF) << 32)
  EndSelect

  ListView()\CellColor(Row) = CellColor
EndProcedure

Macro SetGadgetItemColor(GadgetID, Row, ColorType, Color)
  SetGadgetItemColorEx(GadgetID, Row, ColorType, Color)
EndMacro

OpenWindow(0, 200, 100, 430, 230,
  "Change color of text and background in single rows")
ListViewGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) / 2 - 15)
ListViewGadget(1, 10, WindowHeight(0) / 2 + 5, WindowWidth(0) - 20,
  WindowHeight(0) / 2 - 15)

For i = 1 To 5
  AddGadgetItem(0, -1, "Line " + Str(i))
  AddGadgetItem(1, -1, "Line " + Str(i))
Next i

class_addMethod_(DelegateClass, Selector, @CellDisplayCallback(), "v@:@@@@")
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)
CocoaMessage(0, GadgetID(1), "setDelegate:", AppDelegate)

; ----- Set background color of line 1 in ListView 0 to yellow
SetGadgetItemColor(0, 0, #PB_Gadget_BackColor, #Yellow)

; ----- Set background color of line 4 in ListView 1 to X11 color "Aquamarine"
SetGadgetItemColor(1, 3, #PB_Gadget_BackColor, $D4FF7F)

; ----- Set text color of line 3 in ListView 0 to red
SetGadgetItemColor(0, 2, #PB_Gadget_FrontColor, #Red)

; ----- Set text color of line 4 in ListView 1 to blue
SetGadgetItemColor(1, 3, #PB_Gadget_FrontColor, #Blue)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Post Reply