суббота, 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 я пока не знаю, как создать подобный функционал, но больший вопрос в целесообразности "придумывания велосипеда". Все уже есть. Так что, возвращаемся к истокам, старому доброму "венику"...
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, а во-вторых слишком незначительная деталь, чтобы задумываться о переносе проекта на другую платформу. Итак, продолжим. На данный момент программа выглядит так:
1. Поскольку "окна" напрямую взаимодействуют с родительской формой, то я решил эти окна сделать не окнами а UserControl'ами (их проще разместить на родительской форме в соответствии с ее координатами).
2. Должно быть две публичных процедуры: "выезда" и "заезда" контрола, причем они должны быть адаптированы к любому размеру контрола вплоть до 640х480 (минимальный размер окна программы)
3. Должна быть процедура центровки, которая динамически корректировала бы положение "окна" во время изменения размеров родительской формы.
4. Код функции самого диалогового окна будет содержаться внутри самого диалогового окна
Хотел было сделать затемнение типа Apple'овских фото-галерей, но полу-прозрачность в среде winforms невозможна, а переносить проект на WPF-платформу не получится во-первых потому, что компонент для отображения текста с подсветкой синтаксиса у меня есть только для WinForms, а во-вторых слишком незначительная деталь, чтобы задумываться о переносе проекта на другую платформу. Итак, продолжим. На данный момент программа выглядит так:
Начинаем "войну" с диалоговыми окнами :).
пятница, 28 сентября 2012 г.
Project CodeKeeper - тонкости перевода
Столкнулся с неожиданной проблемой: дело в том, что приведенная ранее процедура и структура текстового файла позволяли менять лишь одно свойства элемента формы - текст. Но как быть, к примеру, с всплывающими подсказками? Придется изменить структуру текстового файла и процедуру локализации, а именно:
Текстовой файл:
<имя контрола><Tab>Параметр><Tab><Значение>, где
<имя контрола> - имя элемента управления формы
<Параметр> - то, что нужно изменить, может быть:
<Tab> - символ табуляции
Текстовой файл:
<имя контрола><Tab>Параметр><Tab><Значение>, где
<имя контрола> - имя элемента управления формы
<Параметр> - то, что нужно изменить, может быть:
- Text (Текст)
- ToolTip (Всплывающая подсказка)
- NullValuePrompt (Приглашение пустого текстового поля (фишка DevExpress))
<Значение> - Локализованный параметр
Текст процедуры:
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
среда, 20 июня 2012 г.
Ajax и с чем его едят
Не так давно начал тестить новое для себя понятие - Ajax. Javascript, совмещенный с PHP дает очень интересные возможности программирования веб-приложений, но до недавнего времени работа с ним для меня была как дайвинг в болоте - вроде бы работает, но непонятно, как, порой возникают ошибки, лечатся, но опять же, не пойми как. И вот, более-менее все стало по своим местам. Итак, обо всем по порядку: Архитектура Клиент-Сервер-Клиент: подразумевает следующее: пользователь(клиент) отправляет запрос на сервер, там его запрос обрабатывается, и возвращается результат обработки введенных данных. Обычно для реализации этой архитектуры достаточно самого что ни на есть обыкновенного PHP. Это сценарий, выполняемый на стороне сервера, куда отправляются данные с локального(клиентского) компьютера. Все бы хорошо, но работа скрипта подразумевает перезагрузку страницы, что влечет за собой обнуление сохраненных Java-переменных, нарушение восприятия, ну и вообще просто неприятно. И тут как раз и приходит на выручку Ajax. Ajax позволяет запускать PHP-скрипт не перегружая страницу, и возвращать результат обработки непосредственно в Javascript. Итак:
<script>
xHR=new XMLHttpRequest();
</script>
В переменную xHR мы записываем экземпляр класса XMLHttpRequest, который и обеспечивает обмен данными между Javascript и PHP, и все бы хорошо, если бы не треклятый ослик, который и тут нам пихает палки в колеса. Дело в том, что Internet Explorer не умеет работать с объектом XMLHttpRequest, для этого у него есть специализированная "примочка" - ActiveX. Итак, чтобы Ajax заработал и на осле, модифицируем наш скрипт:
<script>
if(window.XMLHttpRequest){
xHR=new XMLHttpRequest();
}else{
if(window.activeXObject){
xHR=new activeXObject("Microsoft.XMLHTTP");
}else{
alert("Ваш браузер не поддерживает Ajax!");
}
}
</script>
Инструкция "if(window...)" означает - "если сможешь, сделай так...". Итак, начало положено, что же дальше? А дальше нам предстоит обеспечить передачу данных PHP-скрипту, для чего мы сделаем следующее:
<script>
if(window.XMLHttpRequest){
xHR=new XMLHttpRequest();
}else{
if(window.activeXObject){
xHR=new activeXObject("Microsoft.XMLHTTP");
}else{
alert("Ваш браузер не поддерживает Ajax!");
}
}
xHR.open("POST","myScript.php",false);
xHR.send("myVar=myVarValue");
</script>
В строке /xHR.open("POST","myScript.php",false);/ мы инициировали передачу данных серверному сценарию myScript.php, передача будет осуществляться методом POST, false указывает на то, что асинхронный режим использоваться не будет. Далее, строкой /xHR.send("myVar=myVarValue");/ мы отправили данные указанному выше скрипту, а именно в переменную myVar мы записали значение myVarValue. Теперь, чтобы получить эти данные в PHP-скрипте нам достаточно воспользоваться глобальным массивом $_POST:
<?
echo "Моя переменная равна:".$_POST['myVar'];
?>
Если бы PHP-скрипт запускался напрямую, он бы выдал надпись "Моя переменная равна: myVarValue", однако, поскольку скрипт был инициирован из Javascript, результат его работы возвращается туда же, в переменную responseText или responseXML (в случае, если результатом является XML-файл). В нашем случае это responseText. Итак, финал:
<script>
if(window.XMLHttpRequest){
xHR=new XMLHttpRequest();
}else{
if(window.activeXObject){
xHR=new activeXObject("Microsoft.XMLHTTP");
}else{
alert("Ваш браузер не поддерживает Ajax!");
}
}
xHR.open("POST","myScript.php",false);
xHR.send("myVar=myVarValue");
alert(xHR.responseText);
</script>
И все бы хорошо, пока я не наткнулся на такую ошибку: origin /хост/ is not allowed by access-control-allow-origin. Связано это с тем, что для сервера http://domain.com и http://www.domain.com - это разные сервера, как следствие может возникнуть ситуация, воспринимаемая сервером, как попытка запуска Javascript'ом одного домена PHP-скрипта другого. Лечится все достаточно просто: лучше использовать абсолютные пути при указании расположения скриптов, или же использовать HTML-директиву <base href="...">.
Подписаться на:
Сообщения (Atom)
