понедельник, 22 сентября 2014 г.

Об уходе

По улице ушёл человек. Капли дождя стекали по его бледно-коричневому плащу, и блестели под бледно-желтым светом уличного фонаря. Ему было лет 40-45, но его сутулистая фигура делала его много старше. Внезапно он скорчился, схватился за грудь и опустился на колено. Боль была такая, что невозможно было вздохнуть. Это был сердечный приступ... Внезапно боль отступила, и он поднялся с колен. К его удивлению боли не было совсем, более того, его охватила необычайная лёгкость. И... Отсутствие необходимости дышать. Неподалёку он увидел женскую фигуру в чёрном плаще. В голове эхом отозвался ее голос - "пора"! Мужчина в недоумении спросил - "неужели я умер?". Женщина тихо ответила "да". В ещё голосе слышалась какая-то теплота. Она повторила "пора". Вокруг все завертелось, смазалось, яркий свет ослепил глаза. А затем он оказался  в светлой комнате. И было много встреч, рассказов, анекдотов (!). А потом тот же голос снова сказал "тебе пора!". Вокруг все закрутилось в бешаном танце света, а в рязанском род доме раздался звонкий плач младенца.

суббота, 5 октября 2013 г.

Странные мысли

Ну вот, снова все по-старому, снова дом-работа, снова - комп и незабвенный Mass Effect, и все так же, скривив губы, и попытавшись превратить эту гримасу в подобие улыбки ты продолжаешь идти сквозь осень, ты, человек дождя, который вечно плачет по тем упущенным минутам твоей жизни, которые ты не смог превратить в минуты счастья... Ты идешь, видишь мир вокруг, жизнь вокруг, ты понимаешь, что все это идет мимо тебя, и ты думаешь, что... Да что ты там думаешь, все твои мысли собраны вокруг одного - безделья, называемого учеными мужами покоем. Конечно, гораздо проще писать эти строки, чем пытаться изменить что-либо в своей жизни, пойти по пути, своему пути, пути, не продиктованному никем, но сердцем и душой... Моя душа, есть ли ты на самом деле, или же в конце пути ожидает лишь мрак небытия? Ну что же, всему свое время, настанет и мой миг истины, который будет длится сотни лет вплоть до будущего моего воплощения...

четверг, 4 июля 2013 г.

Потери

Странная штука - жизнь... Люди приходят в нее, уходят, как будто заходят в вагон поезда, но когда кто-то уходит, становится тяжело, причем даже если знал мельком. Странно, сегодня посмотрев фильм «Есть мечты - будут путешествия» стало еще тяжелее, и если бы слезы могли течь из глаз, набралось бы ведро, нахлынула такая тоска, непонятно из-за чего - то ли из-за фильма, в котором героиня - девочка 12-и лет едва не сошла с ума из-за того, что случайно убила своих родителей, когда отец начал домогаться ее по-пьяни, то ли из-за того, что ушел мой близкий человек, то ли из-за осознания того, что я иду путем, который ведет в никуда, и изменить его не могу, поскольку в противном случае это может навредить моим близким, да кроме того, потому что у меня нет (и, возможно, не будет) финансовых возможностей для этого... Просто сегодня был очень тяжелый день, который впечатается в память. Возможно... Память тоже иногда выкидывает странные трюки... Вроде бы важное событие теряется на фоне бесконечно одинаковых будней, неразличимых между собой как капли воды во время дождя. События тянутся сплошной бурой лентой, не оставляя места надежде что-либо изменить. Нужен план... Реальный план, по которому я буду строить свою жизнь. Как сказала Кейси - «есть события, которые происходят сами собой, а есть события, которые ты заставляешь произойти - в этом разница между наличием плана и его отсутствием». Но важно различать реальный план от воздушных замков, и строить свою жизнь именно по реальному плану... Как трудно понимать, что моя жизнь с родными медленно, но неумолимо завершается. Не могу  сказать, что меня пугает самостоятельная жизнь - ее я испытал еще в армейке, однако что действительно пугает, так это судьба моей семьи, в которой у каждого из ее членов не осталось ничего, кроме друг друга. Господи, как мне сохранить семью?!...

понедельник, 12 ноября 2012 г.

Project codekeeper - борьба с "красявостями"

Когда только начал разработку CodeKeeper'а, хотел сделать его в mac'овском стиле, однако понял, что в результате погони за "красявостими" начинает страдать функционал, а это считаю недопустимым. В итоге решил воспользоваться стандартными контролами, которые, впрочем, обеспечивают бОльшую функциональность, нежели, опять же, красивые контролы. В частности на замену sidebar'у собственного производства пришел стандартный TreeViewControl, который, несмотря на свою стандартность, может обеспечивать неограниченную степень вложенности, что для категорий актуально. К примеру, разработчик занимается созданием сайта, у него есть набор сниппетов как в PHP, так и в JavaScript, так и в HTML. В дальнейшем свои наработки он планирует использовать где-либо еще. Соответственно, ему потребуется примерно следующая структура:

Web-Shop
+ HTML
|+Template
||- Meta
||- Header
||- Body
||- Navigation
||- Footer
|+ Chunks
||- Breadcrumbs
||- SearchForm
|+ JavaScript
||+ jQuery
|||- Slider
|||- AjaxSearch
+ PHP
|- Front-end production editor
|- Price uploader
|- XML Parser


То есть, число вложенных категорий не должно быть фиксированным. Это первый момент. Второй момент - это диалоговые окна. Дело в том, что функция |form|.ShowDialog() подразумевает то, что программа запрашивает у пользователя некие данные, и до момента их ввода не позволяет пользователю работать с другими частями программы, кроме того функция |form|.ShowDialog() способна возвращать в функцию, ее вызвавшую данные, которые пользователь ввел в |form|. В случае же с использованием UserControl я пока не знаю, как создать подобный функционал, но больший вопрос в целесообразности "придумывания велосипеда". Все уже есть. Так что, возвращаемся к истокам, старому доброму "венику"...

суббота, 29 сентября 2012 г.

Project CodeKeeper - диалоги о диалогах (часть 1)

Доброго времени суток! Проект CodeKeeper продолжается, и сейчас я начинаю создавать диалоговые окна. На самом деле я большой поклонник Mac'ов, и мне очень нравится способ вызова модальных диалоговых окон в среде Mac OS X (они плавно "выезжают" из-под заголовка окна, и "заезжают" обратно после выбранного пользователем действия, будь то Оk, Cancel, или что-либо еще). Итак, определимся с задачами:

1. Поскольку "окна" напрямую взаимодействуют с родительской формой, то я решил эти окна сделать не окнами а UserControl'ами (их проще разместить на родительской форме в соответствии с ее координатами).

2. Должно быть две публичных процедуры: "выезда" и "заезда" контрола, причем они должны быть адаптированы к любому размеру контрола вплоть до 640х480 (минимальный размер окна программы)

3. Должна быть процедура центровки, которая динамически корректировала бы положение "окна" во время изменения размеров родительской формы.

4. Код функции самого диалогового окна будет содержаться внутри самого диалогового окна

Хотел было сделать затемнение типа Apple'овских фото-галерей, но полу-прозрачность в среде winforms невозможна, а переносить проект на WPF-платформу не получится во-первых потому, что компонент для отображения текста с подсветкой синтаксиса у меня есть только для WinForms, а во-вторых слишком незначительная деталь, чтобы задумываться о переносе проекта на другую платформу. Итак, продолжим. На данный момент программа выглядит так:


Начинаем "войну" с диалоговыми окнами :).

пятница, 28 сентября 2012 г.

Project CodeKeeper - тонкости перевода

Столкнулся с неожиданной проблемой: дело в том, что приведенная ранее процедура и структура текстового файла позволяли менять лишь одно свойства элемента формы - текст. Но как быть, к примеру, с всплывающими подсказками? Придется изменить структуру текстового файла и процедуру локализации, а именно:

Текстовой файл:

<имя контрола><Tab>Параметр><Tab><Значение>, где
<имя контрола> - имя элемента управления формы
<Параметр> - то, что нужно изменить, может быть:

  • Text (Текст)
  • ToolTip (Всплывающая подсказка)
  • NullValuePrompt (Приглашение пустого текстового поля (фишка DevExpress))
<Значение> - Локализованный параметр
<Tab> - символ табуляции

Текст процедуры:
      Public Sub translate(Language As String)
        Dim langFile As String = Application.StartupPath + "\lang\" + Language + ".txt"

        If System.IO.File.Exists(langFile) Then
            'Формирование лингвистического массива
            Dim lines() As String = System.IO.File.ReadAllLines(langFile)
            Dim langArray(lines.Length - 1)() As String
            For f As Integer = 0 To lines.Length - 1
                Dim tempArray() As String = lines(f).Split(vbTab)
                langArray(f) = {tempArray(0), tempArray(1), tempArray(2)}
            Next

            'Поиск контролов формы
            For f As Integer = 0 To langArray.Length - 1
                'форма
                If langArray(f)(0) = "formName" Then
                    Me.Text = langArray(f)(2)
                Else
                    Dim c() As Control = Me.Controls.Find(langArray(f)(0), True)
                    If c.Count > 0 Then
                        Select Case c(0).GetType
                            Case GetType(TextEdit)
                                'Текстовое поле
                                Dim tc As TextEdit = c(0)
                                Select Case langArray(f)(1)
                                    Case "Text" : tc.Text = langArray(f)(2)
                                    Case "NullValuePrompt" : tc.Properties.NullValuePrompt = langArray(f)(2)
                                    Case "ToolTip" : tc.ToolTip = langArray(f)(2)
                                End Select
                                'Кнопка
                            Case GetType(SimpleButton)
                                Dim tc As SimpleButton = c(0)
                                Select Case langArray(f)(1)
                                    Case "Text" : tc.Text = langArray(f)(2)
                                    Case "ToolTip" : tc.ToolTip = langArray(f)(2)
                                End Select
                                'Кнопка со стрелкой
                            Case GetType(DropDownButton)
                                Dim tc As DropDownButton = c(0)
                                Select Case langArray(f)(1)
                                    Case "Text" : tc.Text = langArray(f)(2)
                                    Case "ToolTip" : tc.ToolTip = langArray(f)(2)
                                End Select
                                'Раскрывающийся список
                            Case GetType(ComboBoxEdit)
                                Dim tc As ComboBoxEdit = c(0)
                                Select Case langArray(f)(1)
                                    Case "Text" : tc.Text = langArray(f)(2)
                                    Case "ToolTip" : tc.ToolTip = langArray(f)(2)
                                End Select
                            Case Else
                                'Другое
                                c(0).Text = langArray(f)(2)
                        End Select
                    End If
                End If
            Next
        Else
            MsgBox("Файл языка не найден")
        End If
    End Sub

Причем я слегка изменил стартер:
    Private Sub starter() Handles MyBase.Load
        Dim localizations() As String = System.IO.Directory.GetFiles(Application.StartupPath + "\lang\")
        Me.selLanguage.Properties.Items.Clear()
        For f As Integer = 0 To localizations.Length - 1
            Dim fileInfo As New System.IO.FileInfo(localizations(f))
            Me.selLanguage.Properties.Items.Add(fileInfo.Name.Substring(0, fileInfo.Name.Length - 4))
        Next
        If My.Settings.lang <> "" Then
            translate(My.Settings.lang)
            Me.selLanguage.Text = My.Settings.lang
        Else
            translate("English")
        End If
    End Sub

Таким образом, список локализаций теперь не фиксированный, а подгружается динамически в зависимости от содержимого папки lang в папке программы.

Project CodeKeeper - начало



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

Попытка номер раз:
Задаем свойство isLocalizable=true для формы, параметр Language переставляем на English (изменений не видать), перебиваем заголовки кнопок, групп и прочих элементов управления, все вроде бы ничего, затем возвращаем Language на Default. Вернулись русские метки. Переключили на English - английские метки. Все зашибись (вроде бы). Теперь задача сделать runtime локализацию (то есть переключение между языками программы во время ее работы). Добавляем на форму ComboBoxEdit (используется набор DevExpress XtraEditors, но стандартный набор тоже подойдет). Прописываем код:


Private Sub languageSelector() handles ComboBoxEdit1.SelectedIndexChanged
Select Case ComboBoxEdit.SelectedIndex
Case 0 'Выбран английский язык
Threading.Thread.CurrentThread.CurrentCulture=new Globalization.CultureInfo("en-US")
Threading.Thread.CurrentUIThread.CurrentCulture=new Globalization.CultureInfo("en-US")

Case1 'Выбран русский язык
Threading.Thread.CurrentThread.CurrentCulture=new Globalization.CultureInfo("ru-RU")
Threading.Thread.CurrentUIThread.CurrentCulture=new Globalization.CultureInfo("ru-RU")
End Select
End Sub


Запускаем проект. И сколько бы не выбирали язык - результат - ноль...

Попытка номер два - плюнул на встроенные возможности Visual Studio по локализации, и сделал финт ушами. Для начала создал небольшой текстовой файл такого типа:
<имя контрола>=<локализованное название>, затем:

Private Sub languageSelector() handles ComboBoxEdit1.SelectedIndexChanged
Translate(ComboBoxEdit1.Text)
 'Сохраняем установки языка (для начала - Проект->Свойства проекта->Параметры, там создаем строковой параметр Lang)
My.Settings.Lang=ComboBoxEdit1.Text
 My.Settings.Save
End Sub

'Делаем подпрограмму доступной из других классов инструкцией Public
Public Sub Translate(Language as String)

Dim langFile as String=Application.StartupPath+"\lang\"+Language+".txt"
If System.IO.File.Exists(langFile)
Dim Lines() as String=System.IO.File.ReadAllLines(langFile)
'Формирование локализационного массива
Dim Lang as new HashTable
For f as Integer=0 to Lines.length-1
Dim pair() as string=Lines(f).Split("=")
Lang(pair(0))=pair(1)
Next
'Поиск контрола по имени и присваивание ему значения текста
dim keys as Icollection=Lang.keys
for f as Integer=0 to keys.Count-1

'Параметр True подтверждает поиск по всей иерархии
Dim c() as Control=Me.Controls.Find(keys(0),True)
c(0).Text=Lang(keys(f))
c(0).Update()
Next
Else
MessageBox.Show("Файл языка не найден!","Ошибка")
End If

End Sub

И вуаля! Заработало!

Теперь при вызове дочерних форм делаем следующее:
Private Sub starter() Handles MyBase.Load
 Fotm1.Translate(My.Settings.Lang)
End Sub