Доброго времени суток.

Выкладываю код дерева.
Код еще очень сырой и некоторые вещи не работаю (например скролл бар, что-то руки до него не доходят).
И вообще, подозреваю, что сам по себе код довольно кривой, много что поправить надо. Но сильно не бейте, пол года назад я вообще не знал что такое программирование (у нас в медакадемии только мс аксесс был, который я как не понимал, так и не понимаю). Так что за критику и указание на ошибки буду благодарен :)
И код пока без коментариев :( (знаю, писать надо, и даже собрался)

Архив содержит py файл с кодом и битмапки, которые надо помести по адресу:
ICONS_PATH = u'C:\\Data\\python\\pytree\\'
или же поменять этот адрес в исходнике.

py файл содержит сам контрол и пример его использования (добавляется дерево, обрабатываются кнопки)
по порядку:

Главный класс pyTreeControl
Он создает конву для рисования себя и методом control возвращает эту конву
basic = pyTreeControl(None, user_callback = key_callback) # название basic  осталось от примера на основе которого делал, но это не важно
appuifw.app.body = basic.control()
user_callback - функция, которая будет вызываться при нажании клавиатуры и будет принимать event, который есть словарь
сам pyTreeControl обрабатывает 4 клавиши (верх - перемещение фокуса вверх, низ - перемещение вниз, право - открыть текущую ветку, лево - закрыть текущую ветку)

Опции pyTreeControl (некоторые поясню):

scroll_bar_width = 5
scroll_bar_type = u'none' # u'always', u'auto'
border_width = 0
level_shift = 7 # смещение уровня относительно своего родителя (пикселей)
tree_shift_h = 4 № отступ от левого края (пикселей)
element_space = 3 # расстояние между элементами строки
draw_hierarchy = True # рисовать линии иерархии?
padding_text = u'…' # текст, который будет добивать строку, которая не входит в контролл полностью

font_height = 18
font_name = u'normal'
font_flags = graphics.FONT_ANTIALIAS

marker_bitmap = u'MARKER' # тип битмапки для обозначение выделенного элемента (а типах и о работе с битмапами ниже)
open_bitmap = u'OPEN' # битмапка для обозначение открытой ветки ()
close_bitmap = u'CLOSE' # битмапка для обозначение закрытой ветки ()

bg_color = 0xD0D0D0 # цвет фона

outline_color = 0x0000FF # цвет линии (выделенной)
fill_color = 0xC3D9FF # цвет заполнения

item_color = 0x505050 # цвет текста элемента
mark_item_color = 0xBB5050 #цвет текста выделенного элемента

padding_color = 0xFF0000 # цвет текста padding_text

hier_color = 0x000000 # цвет линий иерархии
hier_select_color = 0xBB5050 # цвет линии иерархии, если элемент этого уровня иерархи выделен (делал только для отладки, потом оставил - понравилось :))
border_color = outline_color # цвет бордюра, думаю, это уйдет, потому что бордюр тоже переделать надо

при изменении одного из этих параметров нужно вызывать pyTreeControl.redraw() НО!!! после изменения параметров scroll_bar_width, border_width, font_* нужно вызывать pyTreeControl.reinit(), чтобы все пересчитать. Можно вообще только reinit() вызывать, но redraw быстрее, оно просто перерисовывает, не пересчитывая
Конструктор pyTreeControl принимает так же еще и размеры контрола и его координаты (это на будущее сделано, есть идея кой - какая) gj по умолчанию - полная клиентская область с координатами (0, 0).

Второй по величине класс - cTreeOssa (Ossa (лат.) - скелет)
Этот класс собержит в себе информацию о структуре дерева. Свой уровень, тип, имя, полный путь от первого родителя, описание, состояние (открыт/зарыт, отмечен/не отмечен)

именно экземпляр этого класса нужно передать в pyTreeControl либо при создании:
tree = cTreeOssa(u'----')
controll = pyTreeControl(tree, user_callback = key_callback)
либо после создания методом set_tree(tree)
basic.set_tree(tree) # после этого вызова контрол сам перерисует дерево
стоит отметить, что самый верхний уровень дерева (0 уровень) (элемент с именем u'—-' в примере) не прорисовывается, все начинается с его потомков (1 уровня)

То есть контрол может динамически менять дерево для отображения. (при добавлении дерева контрол переустанавливает ему уровни cTreeOssa.set_level()).


удалять дерево нужно в 2 этапа
сначла нужно вызывать метод del_branch() очистит всех потомков, только потом del test

Битмапы:
За битмапы отвечает класс cBitmapReserv
в конструктор он принимает путь и словарь с описание битмапов.
в описании словарь: {тип: (имя файла, создать для битмапы маску?)}

тип - это тот самый тип дерева, который соджержит cTreeOssa
2 параметр кортежа - True или False обозначает нужно ли создать маску для битмапы. Если маска нужна, то создается, используя цвет (255, 0, 255) (это поправлю, чтоб параметром было)
Пока pyTreeControl сам создает экземпляр cBitmapReserv, что не очень хорошо (тоже поменяю). так же cBitmapReserv не может пока дополнять словарь с битмапами.
Теперь контрол, при отрисовке элемента, спрашивает у cBitmapReserv картинку нужного типа и тот ему ее возвращает вместе с маской, если такая есть. картинки создаются из словаря не сразу, а только при первом запросе. Если картинки определенного типа не нашлоcь, возвращается дефолтная битмапа (с типом u'')

в примере приведен key_callback:
'*' - делает скриншот контрола (сохраняется в u'C:\\Data\\python\\')
'0' - добавляет элемент 1-ого уровня в дерево контролла
'#' - добаляет элемент в текущее дерево (выделенный элемент) (если находит в имени ‘:-)’ делает элемент смайликом, иначе просто дефолтным листом и устанавливает текущий элемент в тип “DIR”, чтоб так синяя папка отрисовывалась)
'C' - удаляет текущий элемент из дерева
'1', ‘2’ - увеличивает/уменьшает высоту шрифта
'4', ‘6’ - увеличивает/уменьшает ширину границы контрола
'5' - переименовывает текущий элемент

Так, вроде все. Если что еще вспомню – допишу. Будут вопросы - спрашивайте.
Все изменения и дополнения буду отмечать в этой теме.


почему файлы не цепляются? куда архив можно выложить?

файл выложил тут http://slil.ru/26234856
модераторы, может прицепите его к теме?