Page 1 of 2

PanelGadget Question

Posted: Fri Apr 18, 2008 3:04 pm
by hagibaba
Is there any easy way to associate a panelgadget item with a gadget contained in the item?

Posted: Fri Apr 18, 2008 3:09 pm
by Fluid Byte
Say what?

Posted: Fri Apr 18, 2008 3:11 pm
by rsts
probably yes, but we need to know a little more about your requirements.

getgadgetstate may help

cheers

Posted: Fri Apr 18, 2008 3:14 pm
by Fluid Byte
Are you just guessing or do you actually know what he means? If so, enlighten me please.

Posted: Fri Apr 18, 2008 5:37 pm
by rsts
I asked for additional requirements because I wasn't sure as to what he was asking either, but if he was wondering about the state pf a panel when certain gadget events happened, he could certainly determine that.

Yes, without knowing exactly what he was asking, I was guessing, but was thinking we could help if we really understood the requirements.

cheers

Posted: Fri Apr 18, 2008 6:26 pm
by netmaestro
It's not difficult. It's slightly more trouble if -1 is used for dynamic adding of items but not much. In this case you can use:

Code: Select all

AddGadgetItem (0, -1,"Panel 2")
item = SendMessage_(GadgetID(0), #TCM_GETITEMCOUNT, 0,0)-1
ButtonGadget(2, 10, 15, 80, 24,"Button 1") : SetGadgetData(2, item)
Now GetGadgetData for the button gadget# 2 will contain the panel item it's located on, regardless of whether the item is currently selected or not.

Posted: Fri Apr 18, 2008 6:52 pm
by rsts
the maestro speaks.

See, i was right, we could help out :)

cheers

Posted: Fri Apr 18, 2008 8:06 pm
by hagibaba
Sorry, I should have given a bit more information. I meant dynamically. I'm currently using this method... Thanks to netmaestro I can use his method instead, which looks simple and bulletproof.

Code: Select all

Structure FILE
 Filename.s
 Editor.l
 Panel.l
EndStructure

Global NewList FileList.FILE()

Code: Select all

Procedure MenuNew() ;Open a new panel
 
 AddElement(FileList())
 FileList()\Panel = CountGadgetItems(#EditorPanel)
 FileList()\Filename = "<New>" + Str(FileList()\Panel)
 
 OpenGadgetList(#EditorPanel)
  AddGadgetItem(#EditorPanel, FileList()\Panel, FileList()\Filename)
  FileList()\Editor = EditorGadget(#PB_Any, BorderSize, BorderSize, GetGadgetAttribute(#EditorPanel, #PB_Panel_ItemWidth) - BorderSize2, GetGadgetAttribute(#EditorPanel, #PB_Panel_ItemHeight) - BorderSize2)
 CloseGadgetList()
 
 SendMessage_(GadgetID(FileList()\Editor), #EM_LIMITTEXT, -1, 0)
 SetGadgetColor(FileList()\Editor, #PB_Gadget_BackColor, $dfffff)
 EditorFont(FileList()\Editor, "Courier")
 EditorFontSize(FileList()\Editor, 10)
 SetGadgetState(#EditorPanel, FileList()\Panel)
 
EndProcedure

Code: Select all

Procedure MenuClose() ;Close the active panel

 Protected State.l = GetGadgetState(#EditorPanel)
 
 If CountList(FileList()) = 0 ;If no panels
  ProcedureReturn ;Exit
 EndIf
 
 ResetList(FileList())
 While NextElement(FileList()) ;Find the active panel
  If FileList()\Panel = State : Break : EndIf
 Wend
 
 OpenGadgetList(#EditorPanel) ;Delete panel item and editor gadget
  RemoveGadgetItem(#EditorPanel, FileList()\Panel)
  FreeGadget(FileList()\Editor)
 CloseGadgetList()
 
 If FileList()\Panel = CountGadgetItems(#EditorPanel)
  SetGadgetState(#EditorPanel, FileList()\Panel - 1) ;Use last panel
 Else
  SetGadgetState(#EditorPanel, FileList()\Panel) ;Use next panel
 EndIf
 
 DeleteElement(FileList())
 ResetList(FileList())
 While NextElement(FileList())
  If FileList()\Panel > State
   FileList()\Panel - 1 ;Reorder panel IDs to match new panel items
  EndIf
 Wend
 
EndProcedure

Posted: Fri Apr 18, 2008 10:30 pm
by hagibaba
No, that doesn't help.

The problem is that I need to open multiple new panels with editors and identify which editor belongs to what panel. When I close a panel, the panel item indexs are automatically reordered by PB so an index that used to be correct won't be any more.

I got around this by reordering my stored indexes to match. I thought maybe there was a better way to do it but I'll just use what I have then.

Posted: Fri Apr 18, 2008 11:39 pm
by Fluid Byte
You could use the handle of the related static window to identify a panel item.

Code: Select all

OpenWindow(0,0,0,320,240,"void",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
PanelGadget(0,0,0,0,0)
AddGadgetItem(0,-1,"untitled1")
AddGadgetItem(0,-1,"untitled2")
AddGadgetItem(0,-1,"untitled3")

Procedure EnumChildProc(hwnd,lParam)
	Static WinNum
	
	WinNum + 1
	Debug "Window Handle #" + Str(WinNum) + " = " + Str(hwnd)
	
	ProcedureReturn 1
EndProcedure

EnumChildWindows_(GadgetID(0),@EnumChildProc(),0)

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend

Posted: Fri Apr 18, 2008 11:46 pm
by hallodri

Posted: Sat Apr 19, 2008 2:30 am
by Sparkie
Would this work for you ?

Code: Select all

Procedure.l SetTabId(panelGad, tabNum)
  i$ = GetGadgetItemText(panelGad, tabNum)
  tci.TC_ITEM
  tci\mask = #TCIF_PARAM
  
  ;... Get the ID of the previous Panel added and increment by 1
  id = GetGadgetData(panelGad) + 1
  
  ;... Set the new Panel ID
  tci\lParam = id
  SendMessage_(GadgetID(panelGad), #TCM_SETITEM, tabNum, tci)
  
  ;... Increment our Panel ID data
  SetGadgetData(panelGad, id)
  
EndProcedure

Procedure GetTabId(panelGad, tabNum)
  tci.TC_ITEM\mask = #TCIF_PARAM
  SendMessage_(GadgetID(panelGad), #TCM_GETITEM, tabNum, @tci)
  SetGadgetText(0, "Panel ID is: " + Str(tci\lParam))
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  TextGadget(0, 10, 10, 100, 30, "Panel ID is: ")
  PanelGadget(1, 10, 40, 480, 350) 
  AddGadgetItem(1, 0, "Panel 0") 
  AddGadgetItem(1, 1, "Panel 1") 
  AddGadgetItem(1, 2, "Panel 2") 
  CloseGadgetList()
  
  ;... Set the PanleGadget Data to -1
  SetGadgetData(1, -1)
  
  ButtonGadget(2, 200, 10, 100, 25, "Remove Panel 1")
  
  ;... Add Panel ID's to each Panel (tab)
  For i = 0 To CountGadgetItems(1) - 1
    SetTabId(1, i)
  Next
  
  ;... Get the Panel ID for selected Panel
  GetTabId(1, GetGadgetState(1))
  
  Repeat
    event = WaitWindowEvent()
    If event = #PB_Event_Gadget And EventGadget() = 1
      ;... Get the Panel ID for selected Panel
      GetTabId(1, GetGadgetState(1))
    EndIf
    
    If EventType() = #PB_EventType_LeftClick And EventGadget() = 2
      RemoveGadgetItem(1, 1)
      AddGadgetItem(1, 1, "Panel 3")
      ;... Set the Panel ID for out new Panel
      SetTabId(1, 1)
      DisableGadget(2, 1)
    EndIf
    
  Until event = #PB_Event_CloseWindow  
EndIf

Posted: Sat Apr 19, 2008 8:30 pm
by hagibaba
First of all, thanks for all the replies.

I looked at all of them and they all look like solutions.

I thrashed around with EnumChildWindows_() for ages but it has a big problem, it also enums gadgets contained in the panel items/tabs, causing too much confusion for me.

I tried out the "SetGadgetItemData & SetGadgetItemColor for Panels" code but it looked too long and complicated.

So then I tried implementing Sparkie's code and it didn't work, I couldn't understand how to incorporate it.

Then I thought through what I wanted and fiddled with Sparkie's code until I got it working. Here is what I have now... Thanks Sparkie.

Code: Select all

Structure FILE
 Filename.s
 Editor.l
 hwnd.l
EndStructure

Global NewList FileList.FILE()

Code: Select all

Procedure GetPanelID(Panel.l, Item.l)

 Protected tc.TC_ITEM ;Tab Control (Panel) Structure
 tc.TC_ITEM\mask = #TCIF_PARAM ;Use application-defined data
 SendMessage_(GadgetID(Panel), #TCM_GETITEM, Item, @tc)
 ProcedureReturn tc\lParam ;Return panel item handle
 
EndProcedure

Code: Select all

Procedure MenuNew() ;Open a new panel
 
 Protected State.l = CountGadgetItems(#EditorPanel)
 
 AddElement(FileList()) ;New element
 FileList()\Filename = "<New>" ;+ Str(State)
 
 OpenGadgetList(#EditorPanel) ;New panel item and editor gadget
  AddGadgetItem(#EditorPanel, State, FileList()\Filename)
  FileList()\Editor = EditorGadget(#PB_Any, BorderSize, BorderSize, GetGadgetAttribute(#EditorPanel, #PB_Panel_ItemWidth) - BorderSize2, GetGadgetAttribute(#EditorPanel, #PB_Panel_ItemHeight) - BorderSize2)
 CloseGadgetList()
 
 EditorFont(FileList()\Editor, "Courier") ;Modify the editor gadget
 EditorFontSize(FileList()\Editor, 10)
 SetGadgetColor(FileList()\Editor, #PB_Gadget_BackColor, $dfffff)
 SendMessage_(GadgetID(FileList()\Editor), #EM_LIMITTEXT, -1, 0)
 
 FileList()\hwnd = GetPanelID(#EditorPanel, State)
 
 SetActiveGadget(FileList()\Editor)
 SetGadgetState(#EditorPanel, State) ;Set as active panel
 
EndProcedure

Code: Select all

Procedure MenuClose() ;Close the active panel

 Protected State.l, lParam.l
 
 If CountList(FileList()) = 0
  ProcedureReturn ;If no panels then exit
 EndIf
 
 State = GetGadgetState(#EditorPanel) 
 lParam = GetPanelID(#EditorPanel, State)
 
 ResetList(FileList())
 While NextElement(FileList()) ;Find the active panel
  If FileList()\hwnd = lParam : Break : EndIf
 Wend
 
 OpenGadgetList(#EditorPanel) ;Delete panel item and editor gadget
  RemoveGadgetItem(#EditorPanel, State)
  FreeGadget(FileList()\Editor)
 CloseGadgetList()
 
 If State = CountGadgetItems(#EditorPanel)
  SetGadgetState(#EditorPanel, State - 1) ;Use last panel
 Else
  SetGadgetState(#EditorPanel, State) ;Use next panel
 EndIf
 
 DeleteElement(FileList())
 
EndProcedure

Posted: Sat Apr 19, 2008 10:11 pm
by Sparkie
You're welcome. Sorry for the confusion, but glad you were able to get it sorted out. :)

Posted: Sun Apr 20, 2008 2:30 pm
by hagibaba
No problem, I was looking for a simple solution. Any variation of your SetTabId and GetTabId is the way to go.

It's actually not documented what I ended up with in GetPanelID, ie. that tc\lParam holds the panel item handle by default. I'm not sure if this would work on all PCs though. Maybe I should set it with, for example, the editorgadget handle to be sure. Any ideas?