; Описание ...: Для каждой вкладки PanelGadget создаётся внутренний документ одного ScintillaGadget
; Автор ......: Webarion
; Примечание .: Это тестовый код, здесь есть недоработки.
DeclareModule SciDocTab
Enumeration Commands
#Tab_Add
#Tab_Delete
#Tab_Index
#Tab_Count
#Tab_Select
EndEnumeration
Prototype UserProc_Handler( Command, TabGadget, TabIndex = -1 )
Structure Doc_SDT
*SciDoc ; указатель на документ Scintilla, связанный с вкладкой
Anchor.i ; позиция якоря
CaretPos.i ; положение каретки
FirstLine.i ; положение верхней строки
List FoldLine.i() ; список свёрнутых строк
EndStructure
Structure TabGadget
SciGadget.i
UserProc_Handler.UserProc_Handler
List Doc.Doc_SDT()
EndStructure
Global NewMap TabGadget.TabGadget()
Declare Register( ScintillaGadget, TabGadget, *CallbackProcedure )
Declare AddTab( TabGadget )
Declare SelectTab( TabGadget, TabIndex = -1 )
Declare DeleteTab( TabGadget, TabIndex = -1 )
EndDeclareModule
Module SciDocTab
Procedure _UserProc_Controller( Command, TabGadget, TabIndex = -1 )
If FindMapElement( TabGadget(), Str(TabGadget) )
With TabGadget()
If \UserProc_Handler
ProcedureReturn \UserProc_Handler( Command, TabGadget, TabIndex )
EndIf
EndWith
EndIf
EndProcedure
Procedure Register( ScintillaGadget, TabGadget, *UserProc_Handler )
With TabGadget( Str(TabGadget) )
\SciGadget = ScintillaGadget
\UserProc_Handler = *UserProc_Handler
EndWith
EndProcedure
Procedure AddTab( TabGadget )
With TabGadget()
Protected This_Tab = _UserProc_Controller( #Tab_Index, TabGadget )
If This_Tab > -1
SelectElement( \Doc(), This_Tab )
EndIf
LastElement( \Doc() )
AddElement( \Doc() )
NewIndex = ListIndex( \Doc() )
_UserProc_Controller( #Tab_Add, TabGadget, NewIndex )
Protected DocsCount = ListSize( \Doc() )
If DocsCount = 1
\Doc()\SciDoc = ScintillaSendMessage(\SciGadget, #SCI_GETDOCPOINTER)
ScintillaSendMessage(\SciGadget, #SCI_ADDREFDOCUMENT, 0, \Doc()\SciDoc)
ElseIf DocsCount > 1
\Doc()\SciDoc = ScintillaSendMessage(\SciGadget, #SCI_CREATEDOCUMENT)
EndIf
; ScintillaSendMessage( \SciGadget, #SCI_SETDOCPOINTER, 0, \Doc()\SciDoc )
EndWith
SelectTab( TabGadget, NewIndex )
EndProcedure
Procedure SelectTab( TabGadget, TabIndex = -1 )
With TabGadget()
Static Old_Select_TabIndex = -1
If Old_Select_TabIndex <> -1
Protected *OldDoc_SDT.Doc_SDT = SelectElement( \Doc(), Old_Select_TabIndex)
If *OldDoc_SDT
*OldDoc_SDT\Anchor = ScintillaSendMessage(\SciGadget, #SCI_GETANCHOR)
*OldDoc_SDT\CaretPos = ScintillaSendMessage(\SciGadget, #SCI_GETCURRENTPOS)
*OldDoc_SDT\FirstLine = ScintillaSendMessage(\SciGadget, #SCI_GETFIRSTVISIBLELINE)
Protected lineStart = 0
Repeat
Protected FoldLine = ScintillaSendMessage(\SciGadget, #SCI_CONTRACTEDFOLDNEXT, lineStart)
If FoldLine <> -1
AddElement( *OldDoc_SDT\FoldLine() ) : *OldDoc_SDT\FoldLine() = FoldLine
EndIf
lineStart = FoldLine + 1
Until FoldLine = -1
EndIf
EndIf
If TabIndex = -1
TabIndex = _UserProc_Controller( #Tab_Index, TabGadget )
EndIf
If TabIndex > ListSize( \Doc() ) - 1
ProcedureReturn
EndIf
If TabIndex <> -1
Protected *Doc_SDT.Doc_SDT = SelectElement( \Doc(), TabIndex )
ScintillaSendMessage(\SciGadget, #SCI_SETDOCPOINTER, 0, *Doc_SDT\SciDoc)
ScintillaSendMessage(\SciGadget, #SCI_SETFIRSTVISIBLELINE, *Doc_SDT\FirstLine)
ScintillaSendMessage(\SciGadget, #SCI_SETSEL, *Doc_SDT\Anchor, *Doc_SDT\CaretPos)
ForEach *Doc_SDT\FoldLine()
ScintillaSendMessage(\SciGadget, #SCI_FOLDLINE, *Doc_SDT\FoldLine(), 0 )
Next
SetActiveGadget(\SciGadget)
_UserProc_Controller( #Tab_Select, TabGadget, TabIndex )
Old_Select_TabIndex = TabIndex
EndIf
EndWith
EndProcedure
Procedure DeleteTab( TabGadget, TabIndex = -1 )
With TabGadget()
If TabIndex = -1
TabIndex = _UserProc_Controller( #Tab_Index, TabGadget )
EndIf
Protected CountTabs = _UserProc_Controller( #Tab_Count, TabGadget )
If TabIndex > -1 And CountTabs > 1
Protected *Doc.Doc_SDT = SelectElement( \Doc(), TabIndex)
ScintillaSendMessage(\SciGadget, #SCI_RELEASEDOCUMENT, 0, *Doc\SciDoc)
DeleteElement( \Doc() )
If CountTabs > 1
_UserProc_Controller( #Tab_Delete, TabGadget, TabIndex )
CountTabs = ListSize( \Doc() )
If TabIndex = CountTabs
_UserProc_Controller( #Tab_Select, TabGadget, CountTabs-1 )
Else
_UserProc_Controller( #Tab_Select, TabGadget, TabIndex )
EndIf
SelectTab(TabGadget)
EndIf
EndIf
EndWith
EndProcedure
EndModule
; ПРИМЕР для PanelGadget
CompilerIf #PB_Compiler_IsMainFile
If Not InitScintilla() : MessageRequester("", "Не удалось инициализировать компонент Scintilla" ) : End : EndIf
Enumeration Gadgets
#Sci
#Sci2
#ButAdd
#ButAdd2
#ButDel
#ButDel2
#Panel
#Panel2
#TabBar
EndEnumeration
; Обработчик вкладок PanelGadget
Procedure _PanelGadget_TabCallback( Command, PanelGadget, TabIndex = -1 )
Select Command
Case SciDocTab::#Tab_Add
; создадим нумерацию для двух PanelGadget
Static NumName1 = 1, NumName2 = 1
Protected NumName
If PanelGadget = #Panel
NumName = NumName1 : NumName1 + 1
Else
NumName = NumName2 : NumName2 + 1
EndIf
OpenGadgetList(PanelGadget)
AddGadgetItem(PanelGadget, TabIndex, "Вкладка " + Str(NumName) ) ; создаём новую вкладку
CloseGadgetList()
Case SciDocTab::#Tab_Delete
RemoveGadgetItem(PanelGadget, TabIndex)
Case SciDocTab::#Tab_Index
ProcedureReturn GetGadgetState(PanelGadget)
Case SciDocTab::#Tab_Count
ProcedureReturn CountGadgetItems(PanelGadget)
Case SciDocTab::#Tab_Select
SetGadgetState( PanelGadget, TabIndex )
EndSelect
EndProcedure
; генератор текста и стиля для документа
Procedure.s SciGenText(Sci)
Protected Rnd, String.s = "" , Num
RandomSeed(Random(100000, 1))
While Num<50
Rnd =Random(122, 48)
Select Rnd
Case 48 To 57, 65 To 90
String + Chr(Rnd) : Num + 1
EndSelect
Wend
Protected Pos
Static Pos1 = 3, Pos2 = 3, N1 = 1, N2 = 1
If Sci = #Sci
Pos = Pos1 : Pos1 + 5 : String = Str(N1) + ") " + String : N1 + 1
Else
Pos = Pos2 : Pos2 + 5 : String = Str(N2) + ") " + String : N2 + 1
EndIf
Define *Buff = UTF8(String)
ScintillaSendMessage(Sci, #SCI_SETTEXT, 0, *Buff)
FreeMemory(*Buff)
ScintillaSendMessage(Sci, #SCI_STYLESETBACK, 1, $32CD9A)
ScintillaSendMessage(Sci, #SCI_STYLESETFORE, 1, $FF0000)
ScintillaSendMessage(Sci, #SCI_STARTSTYLING, Pos )
ScintillaSendMessage(Sci, #SCI_SETSTYLING, 5, 1 )
EndProcedure
If OpenWindow( 0, 0, 0, 500, 380, "Example PanelGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
ButtonGadget(#ButAdd, 450, 10, 20, 20, "+") : ButtonGadget(#ButDel, 470, 10, 20, 20, "-")
ButtonGadget(#ButAdd2, 450, 200, 20, 20, "+") : ButtonGadget(#ButDel2, 470, 200, 20, 20, "-")
If LoadFont(0, "Arial", 16)
Define FontID = FontID(0)
SetGadgetFont(#ButAdd, FontID) : SetGadgetFont(#ButDel, FontID)
SetGadgetFont(#ButAdd2, FontID) : SetGadgetFont(#ButDel2, FontID)
EndIf
PanelGadget(#Panel, 10, 10, 440, 22) : CloseGadgetList()
PanelGadget(#Panel2, 10, 200, 440, 22) : CloseGadgetList()
ScintillaGadget(#Sci, 10, 32, 480, 150, 0 )
ScintillaGadget(#Sci2, 10, 222, 480, 150, 0 )
; покрасим основной цвет #Sci и #Sci2
ScintillaSendMessage( #Sci, #SCI_STYLESETFORE, 0, $0045FF )
ScintillaSendMessage( #Sci2, #SCI_STYLESETFORE, 0, $8515C7 )
; привязка и регистрация в SciDocTab
SciDocTab::Register( #Sci, #Panel, @_PanelGadget_TabCallback() )
SciDocTab::Register( #Sci2, #Panel2, @_PanelGadget_TabCallback() )
; Первая вкладка
SciDocTab::AddTab( #Panel ) : SciGenText(#Sci)
SciDocTab::AddTab( #Panel2 ) : SciGenText(#Sci2)
Repeat
Define eventID = WaitWindowEvent()
Select eventID
Case #PB_Event_Gadget
Select EventGadget()
; for #Panel
Case #ButAdd
SciDocTab::AddTab(#Panel) : SciGenText(#Sci)
Case #ButDel
SciDocTab::DeleteTab(#Panel)
Case #Panel
SciDocTab::SelectTab(#Panel)
; for #Panel2
Case #ButAdd2
SciDocTab::AddTab(#Panel2) : SciGenText(#Sci2)
Case #ButDel2
SciDocTab::DeleteTab(#Panel2)
Case #Panel2
SciDocTab::SelectTab(#Panel2)
EndSelect
EndSelect
Until eventID = #PB_Event_CloseWindow
EndIf
CompilerEndIf