X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/17c0e08c61c69b77e58b3e9ffc78d58fcf105940..b67a93277892e8226d8e59162a14564f661843f6:/wxPython/src/gtk/controls2.py diff --git a/wxPython/src/gtk/controls2.py b/wxPython/src/gtk/controls2.py index 7b8c5eae19..fcbe7ee362 100644 --- a/wxPython/src/gtk/controls2.py +++ b/wxPython/src/gtk/controls2.py @@ -7,6 +7,8 @@ from windows import * from gdi import * +from fonts import * + from clip_dnd import * from events import * @@ -77,6 +79,9 @@ def EVT_LIST_ITEM_ACTIVATED(win, id, func): def EVT_LIST_CACHE_HINT(win, id, func): win.Connect(id, -1, wxEVT_COMMAND_LIST_CACHE_HINT, func) +def EVT_LIST_ITEM_FOCUSED(win, id, func): + win.Connect(id, -1, wxEVT_COMMAND_LIST_ITEM_FOCUSED, func) + # wxTreeCtrl events def EVT_TREE_BEGIN_DRAG(win, id, func): @@ -157,15 +162,15 @@ class wxListItemAttrPtr : return val def GetTextColour(self, *_args, **_kwargs): val = apply(controls2c.wxListItemAttr_GetTextColour,(self,) + _args, _kwargs) - if val: val = wxColourPtr(val) + if val: val = wxColourPtr(val) ; val.thisown = 1 return val def GetBackgroundColour(self, *_args, **_kwargs): val = apply(controls2c.wxListItemAttr_GetBackgroundColour,(self,) + _args, _kwargs) - if val: val = wxColourPtr(val) + if val: val = wxColourPtr(val) ; val.thisown = 1 return val def GetFont(self, *_args, **_kwargs): val = apply(controls2c.wxListItemAttr_GetFont,(self,) + _args, _kwargs) - if val: val = wxFontPtr(val) + if val: val = wxFontPtr(val) ; val.thisown = 1 return val def __repr__(self): return "" % (self.this,) @@ -181,9 +186,12 @@ class wxListItemPtr(wxObjectPtr): def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,controls2c=controls2c): - if self.thisown == 1 : - controls2c.delete_wxListItem(self) + def __del__(self, delfunc=controls2c.delete_wxListItem): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def Clear(self, *_args, **_kwargs): val = apply(controls2c.wxListItem_Clear,(self,) + _args, _kwargs) return val @@ -343,24 +351,15 @@ class wxListEventPtr(wxNotifyEventPtr): def __init__(self,this): self.this = this self.thisown = 0 - def GetCode(self, *_args, **_kwargs): - val = apply(controls2c.wxListEvent_GetCode,(self,) + _args, _kwargs) + def GetKeyCode(self, *_args, **_kwargs): + val = apply(controls2c.wxListEvent_GetKeyCode,(self,) + _args, _kwargs) return val def GetIndex(self, *_args, **_kwargs): val = apply(controls2c.wxListEvent_GetIndex,(self,) + _args, _kwargs) return val - def GetOldIndex(self, *_args, **_kwargs): - val = apply(controls2c.wxListEvent_GetOldIndex,(self,) + _args, _kwargs) - return val - def GetOldItem(self, *_args, **_kwargs): - val = apply(controls2c.wxListEvent_GetOldItem,(self,) + _args, _kwargs) - return val def GetColumn(self, *_args, **_kwargs): val = apply(controls2c.wxListEvent_GetColumn,(self,) + _args, _kwargs) return val - def Cancelled(self, *_args, **_kwargs): - val = apply(controls2c.wxListEvent_Cancelled,(self,) + _args, _kwargs) - return val def GetPoint(self, *_args, **_kwargs): val = apply(controls2c.wxListEvent_GetPoint,(self,) + _args, _kwargs) if val: val = wxPointPtr(val) ; val.thisown = 1 @@ -393,18 +392,15 @@ class wxListEventPtr(wxNotifyEventPtr): if name == "m_code" : controls2c.wxListEvent_m_code_set(self,value) return - if name == "m_itemIndex" : - controls2c.wxListEvent_m_itemIndex_set(self,value) - return if name == "m_oldItemIndex" : controls2c.wxListEvent_m_oldItemIndex_set(self,value) return + if name == "m_itemIndex" : + controls2c.wxListEvent_m_itemIndex_set(self,value) + return if name == "m_col" : controls2c.wxListEvent_m_col_set(self,value) return - if name == "m_cancelled" : - controls2c.wxListEvent_m_cancelled_set(self,value) - return if name == "m_pointDrag" : controls2c.wxListEvent_m_pointDrag_set(self,value.this) return @@ -415,14 +411,12 @@ class wxListEventPtr(wxNotifyEventPtr): def __getattr__(self,name): if name == "m_code" : return controls2c.wxListEvent_m_code_get(self) - if name == "m_itemIndex" : - return controls2c.wxListEvent_m_itemIndex_get(self) if name == "m_oldItemIndex" : return controls2c.wxListEvent_m_oldItemIndex_get(self) + if name == "m_itemIndex" : + return controls2c.wxListEvent_m_itemIndex_get(self) if name == "m_col" : return controls2c.wxListEvent_m_col_get(self) - if name == "m_cancelled" : - return controls2c.wxListEvent_m_cancelled_get(self) if name == "m_pointDrag" : return wxPointPtr(controls2c.wxListEvent_m_pointDrag_get(self)) if name == "m_item" : @@ -430,6 +424,7 @@ class wxListEventPtr(wxNotifyEventPtr): raise AttributeError,name def __repr__(self): return "" % (self.this,) + GetCode = GetKeyCode class wxListEvent(wxListEventPtr): def __init__(self,*_args,**_kwargs): self.this = apply(controls2c.new_wxListEvent,_args,_kwargs) @@ -519,6 +514,9 @@ class wxListCtrlPtr(wxControlPtr): def GetItemSpacing(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_GetItemSpacing,(self,) + _args, _kwargs) return val + def SetItemSpacing(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_SetItemSpacing,(self,) + _args, _kwargs) + return val def GetSelectedItemCount(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_GetSelectedItemCount,(self,) + _args, _kwargs) return val @@ -578,6 +576,9 @@ class wxListCtrlPtr(wxControlPtr): def ClearAll(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_ClearAll,(self,) + _args, _kwargs) return val + def EditLabel(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_EditLabel,(self,) + _args, _kwargs) + return val def EnsureVisible(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_EnsureVisible,(self,) + _args, _kwargs) return val @@ -617,15 +618,38 @@ class wxListCtrlPtr(wxControlPtr): def ScrollList(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_ScrollList,(self,) + _args, _kwargs) return val + def SetItemTextColour(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_SetItemTextColour,(self,) + _args, _kwargs) + return val + def GetItemTextColour(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_GetItemTextColour,(self,) + _args, _kwargs) + if val: val = wxColourPtr(val) ; val.thisown = 1 + return val + def SetItemBackgroundColour(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_SetItemBackgroundColour,(self,) + _args, _kwargs) + return val + def GetItemBackgroundColour(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_GetItemBackgroundColour,(self,) + _args, _kwargs) + if val: val = wxColourPtr(val) ; val.thisown = 1 + return val def SortItems(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_SortItems,(self,) + _args, _kwargs) return val + def GetMainWindow(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_GetMainWindow,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) + def GetColumn(self, *_args, **_kwargs): + val = apply(controls2c.wxListCtrl_GetColumn,(self,) + _args, _kwargs) + if val is not None: val.thisown = 1 + return val + + def GetItem(self, *_args, **_kwargs): val = apply(controls2c.wxListCtrl_GetItem,(self,) + _args, _kwargs) - val.thisown = 1 + if val is not None: val.thisown = 1 return val @@ -646,6 +670,14 @@ class wxListCtrlPtr(wxControlPtr): '''get the currently focused item or -1 if none''' return self.GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED) + def GetFirstSelected(self, *args): + '''return first selected item, or -1 when none''' + return self.GetNextSelected(-1) + + def GetNextSelected(self, item): + '''return subsequent selected items, or -1 when no more''' + return self.GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) + def IsSelected(self, idx): '''return TRUE if the item is selected''' return self.GetItemState(idx, wxLIST_STATE_SELECTED) != 0 @@ -658,6 +690,20 @@ class wxListCtrlPtr(wxControlPtr): def ClearColumnImage(self, col): self.SetColumnImage(col, -1) + + def Append(self, entry): + '''Append an item to the list control. The entry parameter should be a + sequence with an item for each column''' + if len(entry): + if wx.wxUSE_UNICODE: + cvtfunc = unicode + else: + cvtfunc = str + pos = self.GetItemCount() + self.InsertStringItem(pos, cvtfunc(entry[0])) + for i in range(1, len(entry)): + self.SetStringItem(pos, i, cvtfunc(entry[i])) + return pos class wxListCtrl(wxListCtrlPtr): def __init__(self,*_args,**_kwargs): @@ -747,15 +793,15 @@ class wxTreeItemAttrPtr : return val def GetTextColour(self, *_args, **_kwargs): val = apply(controls2c.wxTreeItemAttr_GetTextColour,(self,) + _args, _kwargs) - if val: val = wxColourPtr(val) + if val: val = wxColourPtr(val) ; val.thisown = 1 return val def GetBackgroundColour(self, *_args, **_kwargs): val = apply(controls2c.wxTreeItemAttr_GetBackgroundColour,(self,) + _args, _kwargs) - if val: val = wxColourPtr(val) + if val: val = wxColourPtr(val) ; val.thisown = 1 return val def GetFont(self, *_args, **_kwargs): val = apply(controls2c.wxTreeItemAttr_GetFont,(self,) + _args, _kwargs) - if val: val = wxFontPtr(val) + if val: val = wxFontPtr(val) ; val.thisown = 1 return val def __repr__(self): return "" % (self.this,) @@ -771,9 +817,12 @@ class wxTreeItemIdPtr : def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,controls2c=controls2c): - if self.thisown == 1 : - controls2c.delete_wxTreeItemId(self) + def __del__(self, delfunc=controls2c.delete_wxTreeItemId): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def IsOk(self, *_args, **_kwargs): val = apply(controls2c.wxTreeItemId_IsOk,(self,) + _args, _kwargs) return val @@ -782,6 +831,7 @@ class wxTreeItemIdPtr : return val def __repr__(self): return "" % (self.this,) + Ok = IsOk class wxTreeItemId(wxTreeItemIdPtr): def __init__(self,*_args,**_kwargs): self.this = apply(controls2c.new_wxTreeItemId,_args,_kwargs) @@ -837,14 +887,18 @@ class wxTreeEventPtr(wxNotifyEventPtr): val = apply(controls2c.wxTreeEvent_GetKeyEvent,(self,) + _args, _kwargs) if val: val = wxKeyEventPtr(val) return val - def GetCode(self, *_args, **_kwargs): - val = apply(controls2c.wxTreeEvent_GetCode,(self,) + _args, _kwargs) + def GetKeyCode(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeEvent_GetKeyCode,(self,) + _args, _kwargs) return val def GetLabel(self, *_args, **_kwargs): val = apply(controls2c.wxTreeEvent_GetLabel,(self,) + _args, _kwargs) return val + def IsEditCancelled(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeEvent_IsEditCancelled,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) + GetCode = GetKeyCode class wxTreeEvent(wxTreeEventPtr): def __init__(self,*_args,**_kwargs): self.this = apply(controls2c.new_wxTreeEvent,_args,_kwargs) @@ -932,6 +986,18 @@ class wxTreeCtrlPtr(wxControlPtr): def SetPyData(self, *_args, **_kwargs): val = apply(controls2c.wxTreeCtrl_SetPyData,(self,) + _args, _kwargs) return val + def GetItemTextColour(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeCtrl_GetItemTextColour,(self,) + _args, _kwargs) + if val: val = wxColourPtr(val) ; val.thisown = 1 + return val + def GetItemBackgroundColour(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeCtrl_GetItemBackgroundColour,(self,) + _args, _kwargs) + if val: val = wxColourPtr(val) ; val.thisown = 1 + return val + def GetItemFont(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeCtrl_GetItemFont,(self,) + _args, _kwargs) + if val: val = wxFontPtr(val) ; val.thisown = 1 + return val def IsVisible(self, *_args, **_kwargs): val = apply(controls2c.wxTreeCtrl_IsVisible,(self,) + _args, _kwargs) return val @@ -1048,6 +1114,9 @@ class wxTreeCtrlPtr(wxControlPtr): def ScrollTo(self, *_args, **_kwargs): val = apply(controls2c.wxTreeCtrl_ScrollTo,(self,) + _args, _kwargs) return val + def GetEditControl(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeCtrl_GetEditControl,(self,) + _args, _kwargs) + return val def EditLabel(self, *_args, **_kwargs): val = apply(controls2c.wxTreeCtrl_EditLabel,(self,) + _args, _kwargs) return val @@ -1072,6 +1141,9 @@ class wxTreeCtrlPtr(wxControlPtr): def SetItemFont(self, *_args, **_kwargs): val = apply(controls2c.wxTreeCtrl_SetItemFont,(self,) + _args, _kwargs) return val + def GetBoundingRect(self, *_args, **_kwargs): + val = apply(controls2c.wxTreeCtrl_GetBoundingRect,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) @@ -1108,6 +1180,150 @@ def wxPreTreeCtrl(*_args,**_kwargs): return val +class wxDirItemDataPtr(wxObjectPtr): + def __init__(self,this): + self.this = this + self.thisown = 0 + def SetNewDirName(self, *_args, **_kwargs): + val = apply(controls2c.wxDirItemData_SetNewDirName,(self,) + _args, _kwargs) + return val + def __setattr__(self,name,value): + if name == "m_path" : + controls2c.wxDirItemData_m_path_set(self,value) + return + if name == "m_name" : + controls2c.wxDirItemData_m_name_set(self,value) + return + if name == "m_isHidden" : + controls2c.wxDirItemData_m_isHidden_set(self,value) + return + if name == "m_isExpanded" : + controls2c.wxDirItemData_m_isExpanded_set(self,value) + return + if name == "m_isDir" : + controls2c.wxDirItemData_m_isDir_set(self,value) + return + self.__dict__[name] = value + def __getattr__(self,name): + if name == "m_path" : + return controls2c.wxDirItemData_m_path_get(self) + if name == "m_name" : + return controls2c.wxDirItemData_m_name_get(self) + if name == "m_isHidden" : + return controls2c.wxDirItemData_m_isHidden_get(self) + if name == "m_isExpanded" : + return controls2c.wxDirItemData_m_isExpanded_get(self) + if name == "m_isDir" : + return controls2c.wxDirItemData_m_isDir_get(self) + raise AttributeError,name + def __repr__(self): + return "" % (self.this,) +class wxDirItemData(wxDirItemDataPtr): + def __init__(self,*_args,**_kwargs): + self.this = apply(controls2c.new_wxDirItemData,_args,_kwargs) + self.thisown = 1 + + + + +class wxGenericDirCtrlPtr(wxControlPtr): + def __init__(self,this): + self.this = this + self.thisown = 0 + def Create(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_Create,(self,) + _args, _kwargs) + return val + def ExpandPath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_ExpandPath,(self,) + _args, _kwargs) + return val + def GetDefaultPath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetDefaultPath,(self,) + _args, _kwargs) + return val + def SetDefaultPath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_SetDefaultPath,(self,) + _args, _kwargs) + return val + def GetPath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetPath,(self,) + _args, _kwargs) + return val + def GetFilePath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetFilePath,(self,) + _args, _kwargs) + return val + def SetPath(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_SetPath,(self,) + _args, _kwargs) + return val + def ShowHidden(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_ShowHidden,(self,) + _args, _kwargs) + return val + def GetShowHidden(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetShowHidden,(self,) + _args, _kwargs) + return val + def GetFilter(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetFilter,(self,) + _args, _kwargs) + return val + def SetFilter(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_SetFilter,(self,) + _args, _kwargs) + return val + def GetFilterIndex(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetFilterIndex,(self,) + _args, _kwargs) + return val + def SetFilterIndex(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_SetFilterIndex,(self,) + _args, _kwargs) + return val + def GetRootId(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetRootId,(self,) + _args, _kwargs) + if val: val = wxTreeItemIdPtr(val) ; val.thisown = 1 + return val + def GetTreeCtrl(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetTreeCtrl,(self,) + _args, _kwargs) + return val + def GetFilterListCtrl(self, *_args, **_kwargs): + val = apply(controls2c.wxGenericDirCtrl_GetFilterListCtrl,(self,) + _args, _kwargs) + if val: val = wxDirFilterListCtrlPtr(val) + return val + def __repr__(self): + return "" % (self.this,) +class wxGenericDirCtrl(wxGenericDirCtrlPtr): + def __init__(self,*_args,**_kwargs): + self.this = apply(controls2c.new_wxGenericDirCtrl,_args,_kwargs) + self.thisown = 1 + self._setOORInfo(self) + + + +def wxPreGenericDirCtrl(*_args,**_kwargs): + val = wxGenericDirCtrlPtr(apply(controls2c.new_wxPreGenericDirCtrl,_args,_kwargs)) + val.thisown = 1 + val._setOORInfo(val) + return val + + +class wxDirFilterListCtrlPtr(wxChoicePtr): + def __init__(self,this): + self.this = this + self.thisown = 0 + def Create(self, *_args, **_kwargs): + val = apply(controls2c.wxDirFilterListCtrl_Create,(self,) + _args, _kwargs) + return val + def FillFilterList(self, *_args, **_kwargs): + val = apply(controls2c.wxDirFilterListCtrl_FillFilterList,(self,) + _args, _kwargs) + return val + def __repr__(self): + return "" % (self.this,) +class wxDirFilterListCtrl(wxDirFilterListCtrlPtr): + def __init__(self,*_args,**_kwargs): + self.this = apply(controls2c.new_wxDirFilterListCtrl,_args,_kwargs) + self.thisown = 1 + self._setOORInfo(self) + + + +def wxPreDirFilterListCtrl(*_args,**_kwargs): + val = wxDirFilterListCtrlPtr(apply(controls2c.new_wxPreDirFilterListCtrl,_args,_kwargs)) + val.thisown = 1 + val._setOORInfo(val) + return val + + #-------------- FUNCTION WRAPPERS ------------------ @@ -1137,6 +1353,7 @@ wxEVT_COMMAND_LIST_COL_RIGHT_CLICK = controls2c.wxEVT_COMMAND_LIST_COL_RIGHT_CLI wxEVT_COMMAND_LIST_COL_BEGIN_DRAG = controls2c.wxEVT_COMMAND_LIST_COL_BEGIN_DRAG wxEVT_COMMAND_LIST_COL_DRAGGING = controls2c.wxEVT_COMMAND_LIST_COL_DRAGGING wxEVT_COMMAND_LIST_COL_END_DRAG = controls2c.wxEVT_COMMAND_LIST_COL_END_DRAG +wxEVT_COMMAND_LIST_ITEM_FOCUSED = controls2c.wxEVT_COMMAND_LIST_ITEM_FOCUSED wxLC_VRULES = controls2c.wxLC_VRULES wxLC_HRULES = controls2c.wxLC_HRULES wxLC_ICON = controls2c.wxLC_ICON @@ -1206,9 +1423,11 @@ wxTR_HAS_BUTTONS = controls2c.wxTR_HAS_BUTTONS wxTR_TWIST_BUTTONS = controls2c.wxTR_TWIST_BUTTONS wxTR_NO_LINES = controls2c.wxTR_NO_LINES wxTR_MAC_BUTTONS = controls2c.wxTR_MAC_BUTTONS +wxTR_AQUA_BUTTONS = controls2c.wxTR_AQUA_BUTTONS wxTR_SINGLE = controls2c.wxTR_SINGLE wxTR_MULTIPLE = controls2c.wxTR_MULTIPLE wxTR_EXTENDED = controls2c.wxTR_EXTENDED +wxTR_FULL_ROW_HIGHLIGHT = controls2c.wxTR_FULL_ROW_HIGHLIGHT wxTR_EDIT_LABELS = controls2c.wxTR_EDIT_LABELS wxTR_LINES_AT_ROOT = controls2c.wxTR_LINES_AT_ROOT wxTR_HIDE_ROOT = controls2c.wxTR_HIDE_ROOT @@ -1252,3 +1471,10 @@ wxEVT_COMMAND_TREE_ITEM_ACTIVATED = controls2c.wxEVT_COMMAND_TREE_ITEM_ACTIVATED wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK = controls2c.wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK = controls2c.wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK wxEVT_COMMAND_TREE_END_DRAG = controls2c.wxEVT_COMMAND_TREE_END_DRAG +wxDIRCTRL_DIR_ONLY = controls2c.wxDIRCTRL_DIR_ONLY +wxDIRCTRL_SELECT_FIRST = controls2c.wxDIRCTRL_SELECT_FIRST +wxDIRCTRL_SHOW_FILTERS = controls2c.wxDIRCTRL_SHOW_FILTERS +wxDIRCTRL_3D_INTERNAL = controls2c.wxDIRCTRL_3D_INTERNAL +wxDIRCTRL_EDIT_LABELS = controls2c.wxDIRCTRL_EDIT_LABELS +wxID_TREECTRL = controls2c.wxID_TREECTRL +wxID_FILTERLISTCTRL = controls2c.wxID_FILTERLISTCTRL