Re[10]: Tcl как обоснование ненужности поддержки компонентности в С++
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 01.06.06 08:40
Оценка: 32 (6) +4 :)
Здравствуйте, VladD2, Вы писали:

VD>Ну, а теперь подытоживаем... Мы получили такой же дизайнер как в C# с мааааленькими оговорочками. Он выгдядит очень убого (думаю, так же убого в нем работать), расширяется не средсвами языка на котором ведется разработка и не имеет моря готовых контролов от третьих (да хоть от каких) производителей.


Он *расширяется* средсвами языка на котором ведётся разработка, к нему есть (ну ладно, в 2000 году, когда я последний раз использовал Tcl/Tk было, а сейчас не знаю) несколько наборов виджетов на все случаи жизни. В *море* готовых контролов нет острой необходимости, потому что все наличные виджеты легко расширяются и модифицируются.

Что-бы не быть голословным приведу пример, который я использовал.
Использовался код

# <s>------------------------------------------------------------------</s>
# EXAMPLE: appointment schedule widget
# <s>------------------------------------------------------------------</s>
# Effective Tcl/Tk Programming
# Mark Harrison, DSC Communications Corp.
# Michael McLennan, Bell Labs Innovations for Lucent Technologies
# Addison-Wesley Professional Computing Series
# ======================================================================
# Copyright © 1996–1997 Lucent Technologies Inc. and Mark Harrison
# ======================================================================


Вот код создания виджета (коментарии жирным — мои):
#  USAGE:  appointment_create <win>
#
#  Creates one page in an appointment book.  This includes a text
#  widget with some special tags and bindings, and a scrollbar.
#  Information is loaded into the page via appointment_load.
# ----------------------------------------------------------------------
proc appointment_create {win} {
   frame $win -class Appointment

   scrollbar $win.sbar -command "$win.text yview"
   pack $win.sbar -side right -fill y

    #Тут создаётся текстовый виджет (аналог RichTextEdit)
    # с вертикальным скролбаром с двумя колонками: 
    # одна 2 сантиметра от левого края и с 
    # правым выравниванием, другая - 2,4 см с левым.
    #
   text $win.text -background white -wrap word \
       -cursor left_ptr -tabs {2c right 2.4c left} \
       -yscrollcommand "$win.sbar set"
   pack $win.text -side left -expand yes -fill both

   #
   # Set up tags for the various text styles...
   #
     # Тэги - это нечто вроде стилей
     # Они имеют ряд свойст, которые исменяют
     # как внешний вид так и поведение элементов,
     # к которым эти теги привязаны. То есть,
     # изменени некого визуального атрибута в тэге
     # изменяет внешний вид всех элементов к которым
     # этот тег привязан. К одному элементу можно
     # привязывать много тегов.
     #
     # Тут конфигурируются теги title, date, hour, 
     # comment, stripe, space.
     # 
     # Строчка 'option get $win titleFont Font' это
     # получение значений из внешних конфигов.
     # На 'X' это родной механизм, по виндами - эмуляция
     
   $win.text tag configure title \
       -font [option get $win titleFont Font]

   $win.text tag configure date \
       -font [option get $win dateFont Font]

   $win.text tag configure hour \
       -font [option get $win hourFont Font]

   $win.text tag configure comment \
       -lmargin1 2.4c -lmargin2 2.4c \
       -font [option get $win commentFont Font]

   $win.text tag configure stripe \
       -background [option get $win stripeBackground Background] \
       -foreground [option get $win stripeForeground Foreground]

   $win.text tag configure space -spacing1 5

   #
   # Set up bindings to handle appointment editing...
   #
   set btags [bindtags $win.text]
   set i [lsearch $btags Text]
   if {$i >= 0} {
       set btags [lreplace $btags $i $i]
   }
   bindtags $win.text $btags

    #Тут ничего необычного - обработка событий клавиатуры...
   bind $win.text <KeyPress> "appointment_insert $win %W %A"
   bind $win.text <Control-KeyPress-h> "appointment_backspace $win %W"
   bind $win.text <KeyPress-BackSpace> "appointment_backspace $win %W"
   bind $win.text <KeyPress-Delete> "appointment_delete $win %W"
   bind $win.text <KeyPress-Tab> "appointment_next $win %W; break"
   bind $win.text <KeyPress-Down> "appointment_next $win %W; break"
   bind $win.text <KeyPress-Up> "appointment_prev $win %W; break"
   bind $win.text <KeyPress-Left> "appointment_left $win %W; break"
   bind $win.text <KeyPress-Right> "appointment_right $win %W; break"

   #
   # Bind to the "comment" fields to let the user position
   # the cursor...
   #
    #... и нажатий мыши
   $win.text tag bind comment <ButtonPress-1> "
       focus %W
       %W mark set insert @%x,%y
   "

   return $win
}


Теперь пример добавления строчек в виджет:
# ----------------------------------------------------------------------
#  USAGE:  appointment_load_slot <win> <slot> <appmt> <allSlots>
#
#  Adds a single line to the appointment book <win>.  Each line
#  represents one time slot.  <slot> contains the hour like "8:00am".
#  <appmt> is a list containing the alarm setting and the comment
#  message.  <allSlots> is a list of all of the slots, in the order
#  that they are displayed on the page.
# ----------------------------------------------------------------------
proc appointment_load_slot {win slot appmt allSlots} {
   if {[string match "*:00" $slot]} {
       set htags "hour space"
   } else {
       set htags "hour"
   }
     # htags - это набор тэтов, согласно которым
     # меняется внешний вид текста
     # Текст добавляется уже с тэгами (последняя переменная).
   $win.text insert end "\t$slot\t" $htags

   appointment_load_bell $win $slot $appmt

   set pos [lsearch $allSlots $slot]
   if {$pos % 2 != 0} {
       set ctags "comment stripe"
   } else {
       set ctags "comment"
   }
   set mesg [lindex $appmt 1]
   $win.text insert end "$mesg\n" $ctags
}


Переход между строчками:
# ----------------------------------------------------------------------
#  USAGE:  appointment_next <twin>
#
#  Moves to the next appointment slot on the text widget <twin>.
# ----------------------------------------------------------------------
proc appointment_next {win twin} {
   set range [$twin tag nextrange hour insert]
   if {$range != ""} {
       set index [lindex $range 0]
       set range [$twin tag nextrange comment $index]
       set index [lindex $range 0]
       $twin mark set insert $index
   }
   $twin see insert
}


Весь код приводить естественно не стану.
Вот внизу картинка того как оно выглядит. Поставить курсор куда-то кроме поля для ввода текста нельзя. Автоматически развдигаются строчки для ввода кода. По умолчанию поле со временем белое, я его сделал желтым что-бы выделить. Добавлю еще, что не смотря на то, что исходно Tcl на поддерживает никакого ООП, сами виджеты традиционно работают по вполне ООП схеме.
Например, .but configure ....
Тут .but — это кнопка, объект-получатель сообщения 'configure' с параметрами ..... Достигается это путём создания процедуры которая и занимается "диспетчеризацией" сообщений. В далёком 2000 "pure tcl" виджеты в разных виджетсетах работали с нормальной скоростью.
То есть то что получился полноценный виджет, отличающийся довольно радикально от исходного текстового. Работает на куче платформ.

А теперь внимание вопрос, как расширить RichTextEdit до чего-то подобного? Вопрос дялеко не праздный, так как попытавшись изменить поведение какого-то контрола, я вдруг с удивлением узнал, что у него половина методов не виртуальные, и наследников создавать бесполезно, а переписывать с нуля — не спортивно.



VD>Ну, и чем вы тут хвастались? Убогостью? Ее и так кругом хватает.


А я уж думаю думаю, неужели у Влада 5 копеек нету? Тогда просвети, Влад, ты зачем сцинтилу прикручивал я Янусу? Почему не расширил функциональность стандартных котролов? Так вот, Влад, "убожество" это когда, чтобы что-то сделать приходся брать сторонний контрол, или переписывать всё с нуля. "Коде реюзе", блин.
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.