It is currently Mon Nov 18, 2019 2:52 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Edit TreeGadget items?
PostPosted: Tue Sep 04, 2018 8:05 pm 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
Hi,

I'm trying to set it up so users can edit TreeGadget items, but it's safe to say I have absolutely no idea what I'm doing. I can't get it to start the editing. I'd like to be able to validate what they enter. Does anyone have any tips?

I started with this code by Shardik.

Code:
EnableExplicit

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

ProcedureC GetViewForCellCallback(Object.I, Selector.I, TableView.I, ColumnObject.I, Row.I)
  Protected CellContent.S
  Protected Column.I
  Protected ColumnID.S = PeekS(CocoaMessage(0, CocoaMessage(0, ColumnObject, "identifier"), "UTF8String"), -1, #PB_UTF8)
  Protected View.I
    View = CocoaMessage(0, CocoaMessage(0, 0, "NSTextField new"), "setEditable:", #YES)
  ProcedureReturn View
EndProcedure

OpenWindow(0, 200, 100, 430, 126, "")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)

AddGadgetItem(0, -1, "Harry Rannit")
AddGadgetItem(0, -1, "Ginger Brokeit")
AddGadgetItem(0, -1, "Didi Foundit")

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

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Wed Sep 05, 2018 9:21 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
I had already posted this example of a ListIconGadget with editable cells. Since internally a ListIconGadget in PureBasic is a NSTableView and a TreeGadget is a NSOutlineView which is based on a NSTableView, it would have been as easy as changing the ListIconGadget into a TreeGadget in my example. For your conveniance I have done that for you. (And I have removed the procedure ConvertToUTF8() because it isn't necessary anymore since Fred has removed a bug requiring this produre as a workaround.)
Code:
EnableExplicit

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

ProcedureC EditingFinishedCallback(Object.I, Selector.I, Notification.I)
  Protected EditedCell.I
  Protected EditedColumn.I = CocoaMessage(0, GadgetID(0), "editedColumn")
  Protected EditedRow.I = CocoaMessage(0, GadgetID(0), "editedRow")
  Protected EditedText.S

  EditedCell = CocoaMessage(0, Notification, "object")
  EditedText = PeekS(CocoaMessage(0, CocoaMessage(0, EditedCell, "stringValue"),
    "UTF8String"), -1, #PB_UTF8)
  SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)
EndProcedure

Define CursorLocation.NSPoint
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define SelectedColumn.I
Define Selector.I = sel_registerName("textDidEndEditing:")

OpenWindow(0, 200, 100, 220, 130, "Editable TreeGadget")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddGadgetItem(0, -1, "Fruits")
AddGadgetItem(0, -1, "Apples", 0, 1)
AddGadgetItem(0, -1, "Bananas", 0, 1)
AddGadgetItem(0, -1, "Oranges", 0, 1)
SetGadgetItemState(0, 0, #PB_Tree_Expanded)
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1)
class_addMethod(DelegateClass, Selector, @EditingFinishedCallback(), "v@:@")
CocoaMessage(0, NotificationCenter,
  "addObserver:", AppDelegate,
  "selector:", Selector,
  "name:$", @"NSControlTextDidEndEditingNotification",
  "object:", GadgetID(0))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        CursorLocation\x = WindowMouseX(0)
        CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
        CocoaMessage(@CursorLocation, GadgetID(0),
          "convertPoint:@", @CursorLocation, "fromView:", 0)
        SelectedColumn = CocoaMessage(0, GadgetID(0),
          "columnAtPoint:@", @CursorLocation)
        CocoaMessage(0, GadgetID(0),
          "editColumn:", SelectedColumn,
          "row:", GetGadgetState(0),
          "withEvent:", 0,
          "select:", #YES)
      EndIf
  EndSelect
ForEver


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Thu Sep 06, 2018 8:40 am 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
Thanks, Shardik. I didn't see your ListIconGadget code.

It doesn't work in my project...it won't start the edit when I call:
Code:
CocoaMessage(0, GadgetID(0),
          "editColumn:", SelectedColumn,
          "row:", GetGadgetState(0),
          "withEvent:", 0,
          "select:", #YES)
EndIf
I copied your code exactly. I commented out any other CocoaGadget code I have in there. Can you think of anything that could interfere with it?


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Thu Sep 06, 2018 9:57 am 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
Does my code example from above work unchanged?

If yes, try to post a stripped down version of your project that demonstrates the non-working edit operation.

And please state your MacOS version and your PureBasic version, 32-bit or 64-bit, ASCII or Unicode mode...


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Thu Sep 06, 2018 10:16 am 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
Yes, your code sample works fine unchanged.

It seems the problem is that my TreeGadget is a pointer within a Structure. Is that the wrong thing to do?
Code:
EnableExplicit

Structure MyStructure
  *gadget
EndStructure

Global *test.MyStructure = AllocateStructure(MyStructure)

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

ProcedureC EditingFinishedCallback(Object.I, Selector.I, Notification.I)
  Protected EditedCell.I
  Protected EditedColumn.I = CocoaMessage(0, GadgetID(*test\gadget), "editedColumn")
  Protected EditedRow.I = CocoaMessage(0, GadgetID(*test\gadget), "editedRow")
  Protected EditedText.S

  EditedCell = CocoaMessage(0, Notification, "object")
  EditedText = PeekS(CocoaMessage(0, CocoaMessage(0, EditedCell, "stringValue"),
    "UTF8String"), -1, #PB_UTF8)
  SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)
EndProcedure


Define CursorLocation.NSPoint
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define SelectedColumn.I
Define Selector.I = sel_registerName("textDidEndEditing:")

OpenWindow(0, 200, 100, 220, 130, "Editable TreeGadget")

*test\gadget = TreeGadget(#PB_Any, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddGadgetItem(*test\gadget, -1, "Fruits")
AddGadgetItem(*test\gadget, -1, "Apples", 0, 1)
AddGadgetItem(*test\gadget, -1, "Bananas", 0, 1)
AddGadgetItem(*test\gadget, -1, "Oranges", 0, 1)
SetGadgetItemState(*test\gadget, 0, #PB_Tree_Expanded)
CocoaMessage(0, GadgetID(*test\gadget), "setSelectionHighlightStyle:", -1)
class_addMethod(DelegateClass, Selector, @EditingFinishedCallback(), "v@:@")
CocoaMessage(0, NotificationCenter,
  "addObserver:", AppDelegate,
  "selector:", Selector,
  "name:$", @"NSControlTextDidEndEditingNotification",
  "object:", GadgetID(*test\gadget))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        CursorLocation\x = WindowMouseX(0)
        CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
        CocoaMessage(@CursorLocation, GadgetID(*test\gadget),
          "convertPoint:@", @CursorLocation, "fromView:", 0)
        SelectedColumn = CocoaMessage(0, GadgetID(*test\gadget),
          "columnAtPoint:@", @CursorLocation)
        CocoaMessage(0, GadgetID(*test\gadget),
          "editColumn:", SelectedColumn,
          "row:", GetGadgetState(*test\gadget),
          "withEvent:", 0,
          "select:", #YES)
      EndIf
  EndSelect
ForEver

I am using PB v5.70b1 Unicode on macOS High Sierra.


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Thu Sep 06, 2018 8:57 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
In your code you have forgotten to modify 2 gadget references. Please change in procedure EditingFinishedCallback()
Code:
SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)
to
Code:
  SetGadgetItemText(*test\gadget, EditedRow, EditedText, EditedColumn)
and in your event loop please change
Code:
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
to
Code:
      If EventGadget() = *test\gadget And EventType() = #PB_EventType_LeftClick
and your example will run like a charm... :wink:


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Fri Sep 07, 2018 10:32 am 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
You're right about that. That was a stupid mistake.

However...it's still not working in my project. I can't see what the problem is.


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Sat Mar 16, 2019 6:05 pm 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
I am at my wits' end trying to get this to work in my project. It works if I create a second window and put the TreeGadget in that, but it doesn't work in my main window. I don't understand it.

I have commented out all the unrelated CocoaMessage commands, but that makes no difference.

I have tried recreating the setup of my project in an example (with the TreeGadget in containers, etc.) and it works fine there.

It works if I do this:
Code:
CocoaMessage(0, GadgetID(tree), "setDelegate:", delegateClass)
However, the TreeGadget's items' text disappears.

I am so confused.


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Sat Mar 16, 2019 7:35 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
Sorry, but we are only able to help you if you post a stripped down example demonstrating your problems...


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Sun Mar 17, 2019 6:40 am 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
I know. I'm sorry I couldn't provide one earlier. I spent a long time picking apart my project to see what could be the problem and then I suddenly realised the difference between the TreeGadget in my project and the one in the example...the items in mine have images.

So when an item has an image, it cannot be edited. I am afraid this might be a showstopper for this functionality, though I hope not.
Code:
EnableExplicit

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

ProcedureC EditingFinishedCallback(Object.I, Selector.I, Notification.I)
  Protected EditedCell.I
  Protected EditedColumn.I = CocoaMessage(0, GadgetID(0), "editedColumn")
  Protected EditedRow.I = CocoaMessage(0, GadgetID(0), "editedRow")
  Protected EditedText.S

  EditedCell = CocoaMessage(0, Notification, "object")
  EditedText = PeekS(CocoaMessage(0, CocoaMessage(0, EditedCell, "stringValue"),
    "UTF8String"), -1, #PB_UTF8)
  SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)
EndProcedure

Define CursorLocation.NSPoint
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define SelectedColumn.I
Define Selector.I = sel_registerName("textDidEndEditing:")

CreateImage(0, 16, 16, 24, #Red)
CreateImage(1, 16, 16, 24, #Blue)

OpenWindow(0, 200, 100, 220, 130, "Editable TreeGadget")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddGadgetItem(0, -1, "Fruits", ImageID(0))
AddGadgetItem(0, -1, "Apples", 0, 1)
AddGadgetItem(0, -1, "Bananas", ImageID(1), 1)
AddGadgetItem(0, -1, "Oranges", 0, 1)
SetGadgetItemState(0, 0, #PB_Tree_Expanded)
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1)
class_addMethod(DelegateClass, Selector, @EditingFinishedCallback(), "v@:@")
CocoaMessage(0, NotificationCenter,
  "addObserver:", AppDelegate,
  "selector:", Selector,
  "name:$", @"NSControlTextDidEndEditingNotification",
  "object:", GadgetID(0))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        CursorLocation\x = WindowMouseX(0)
        CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
        CocoaMessage(@CursorLocation, GadgetID(0),
          "convertPoint:@", @CursorLocation, "fromView:", 0)
        SelectedColumn = CocoaMessage(0, GadgetID(0),
          "columnAtPoint:@", @CursorLocation)
        CocoaMessage(0, GadgetID(0),
          "editColumn:", SelectedColumn,
          "row:", GetGadgetState(0),
          "withEvent:", 0,
          "select:", #YES)
      EndIf
  EndSelect
ForEver


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Mon Mar 25, 2019 2:54 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
wombats wrote:
I know. I'm sorry I couldn't provide one earlier. I spent a long time picking apart my project to see what could be the problem and then I suddenly realised the difference between the TreeGadget in my project and the one in the example...the items in mine have images.
Thank you for taking the time to strip down your code until you were able to demonstrate the error.

wombats wrote:
So when an item has an image, it cannot be edited. I am afraid this might be a showstopper for this functionality, though I hope not.
Unfortunately I haven't found a solution yet. Fred seems to use a custom object called "TreeItem". Only Fred or freak possibly know how to make it possible to edit a "TreeItem" containing both an image and a text. The only but complicated alternative I currently can think of is to program a pure API solution using the NSOutlineView on which the TreeGadget is based on. As a further complication the TreeGadget is based on an old cell-based approach which doesn't offer a combination of image and text with native Cocoa framework methods. From the Apple OpenSource site you may download the class ImageAndTextCell.m and header file ImageAndTextCell.h which you would have to implement in your PureBasic code.


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Tue Apr 02, 2019 2:58 pm 
Online
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 500
Shardik wrote:
wombats wrote:
I know. I'm sorry I couldn't provide one earlier. I spent a long time picking apart my project to see what could be the problem and then I suddenly realised the difference between the TreeGadget in my project and the one in the example...the items in mine have images.
Thank you for taking the time to strip down your code until you were able to demonstrate the error.

wombats wrote:
So when an item has an image, it cannot be edited. I am afraid this might be a showstopper for this functionality, though I hope not.
Unfortunately I haven't found a solution yet. Fred seems to use a custom object called "TreeItem". Only Fred or freak possibly know how to make it possible to edit a "TreeItem" containing both an image and a text. The only but complicated alternative I currently can think of is to program a pure API solution using the NSOutlineView on which the TreeGadget is based on. As a further complication the TreeGadget is based on an old cell-based approach which doesn't offer a combination of image and text with native Cocoa framework methods. From the Apple OpenSource site you may download the class ImageAndTextCell.m and header file ImageAndTextCell.h which you would have to implement in your PureBasic code.
That's a shame. Thank you for looking into it.


Top
 Profile  
Reply with quote  
 Post subject: Re: Edit TreeGadget items?
PostPosted: Wed Jul 17, 2019 12:25 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Apr 21, 2005 2:38 pm
Posts: 1653
Location: Germany
I have found a workaround to edit tree items with an image. My example code does the following:
If a tree item selected for edit contains an image:
- Grab that image
- Delete that image from the item
- When text editing starts, no icon is displayed and text editing is possible
- After text editing ends, redisplay the image again

The first step was to find a way how to grab the image from a tree item. For this purpose I already posted this cross-platform example.

This is the complete example which I tested successfully on MacOS 10.6.8 'Snow Leopard' with PB 5.46 x86 in ASCII and Unicode mode and on MacOS 10.13.6 'High Sierra' with PB 5.46 x64 in ASCII and Unicode mode:
Code:
EnableExplicit

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define Cell.I
Define CellImage.I
Define ClassName.S
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define SelectedRow.I
Define Selector.I = sel_registerName_("textDidEndEditing:")

ProcedureC EditingFinishedCallback(Object.I, Selector.I, Notification.I)
  Shared CellImage.I

  Protected EditedCell.I
  Protected EditedColumn.I = CocoaMessage(0, GadgetID(0), "editedColumn")
  Protected EditedRow.I = CocoaMessage(0, GadgetID(0), "editedRow")
  Protected EditedText.S

  EditedCell = CocoaMessage(0, Notification, "object")
  EditedText = PeekS(CocoaMessage(0, CocoaMessage(0, EditedCell, "stringValue"),
    "UTF8String"), -1, #PB_UTF8)
  SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)

  If CellImage
    SetGadgetItemImage(0, EditedRow, CellImage)
    CellImage = 0
  EndIf
EndProcedure

Procedure GetGadgetItemImage(TreeGadgetID.I, Row.I)
  Protected Item.I
  Protected CellImage.I

  Item = CocoaMessage(0, GadgetID(TreeGadgetID), "itemAtRow:", Row)
  CellImage = PeekI(PeekI(PeekI(Item + SizeOf(Integer))) + SizeOf(Integer) * 3)

  ProcedureReturn CellImage
EndProcedure

CreateImage(0, 16, 16, 24, $FF)
CreateImage(1, 16, 16, 24, $FF0000)

OpenWindow(0, 200, 100, 220, 130, "Editable TreeGadget")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddGadgetItem(0, -1, "Fruit", ImageID(0))
AddGadgetItem(0, -1, "Apples", 0, 1)
AddGadgetItem(0, -1, "Bananas", ImageID(1), 1)
AddGadgetItem(0, -1, "Oranges", 0, 1)
SetGadgetItemState(0, 0, #PB_Tree_Expanded)
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1)
class_addMethod_(DelegateClass, Selector, @EditingFinishedCallback(), "v@:@")
CocoaMessage(0, NotificationCenter,
  "addObserver:", AppDelegate,
  "selector:", Selector,
  "name:$", @"NSControlTextDidEndEditingNotification",
  "object:", GadgetID(0))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        SelectedRow = GetGadgetState(0)
        Cell = CocoaMessage(0, GadgetID(0),
          "preparedCellAtColumn:", 0,
          "row:", SelectedRow)
        ClassName = PeekS(CocoaMessage(0, CocoaMessage(0,
          Cell, "className"), "UTF8String"), -1, #PB_UTF8)

        If ClassName = "PBIconTextCell"
          CellImage = GetGadgetItemImage(0, SelectedRow)
          SetGadgetItemImage(0, SelectedRow, 0)
        EndIf

        CocoaMessage(0, GadgetID(0), "setFocusedColumn:", 0)
        CocoaMessage(0, GadgetID(0),
          "editColumn:", 0,
          "row:", SelectedRow,
          "withEvent:", 0,
          "select:", #YES)
      EndIf
  EndSelect
ForEver


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye