SeeMe for Windows v3.2.2

SeeMe v4 をそろそろ本格的にやらなきゃいけない。
誰だよ催促してきたのは、ブログは見ていないということだろうけどやっているよ。

でも 10 正式版がそろそろ出る予感がするので C# のまま手直しで済ませる。
ソースコードを丸ごと公開しているんだから他の誰かにやってほしいんだが。

それもあるわけだが Visual Studio を使いたくなってきた。
ということで我がマシンは Vista HDD にしばらく換装することにした。

起動してずっと HDD がガリガリガリガリガリガリガリガリガリガリ…
自動更新で何故か二回再起動させられる…
そういえば sp2 が出ていたんだっけ、ダウンロード…

いや、毎日使うような人なら細切れになるからいいのだろうけど。
私のように数ヶ月間電源を入れない人だと全部一気に行われるからタマラン。
ほとんどが自動で行われるのはいいと思うけど何もかも時間が掛かりすぎ。
二時間以上掛かってやっと使える状態に。

久々に Vista を使ってみると Explorer がやっぱり酷すぎる。
flv 画質は DirectShow より GStreamer のほうが滑らかなような気がする。
Windows Power Shell は何故こんなに制限を設けてしまったやら。
どのフォントにしてもギザギザにしか見えない。

しかし Windows 版 Opera は Linux 版を知っている人ならありえないほど安定。
Opera 10 Beta もインストール、やっぱり仮想で使うよりケタ違いにスムース。
あれ?Silverright も Firefox プラグインで動かせる範囲なら動くジャン。

Opera の為だけに Windows へ戻ろうかと思うくらいだ。
でもその他が全部不便なんだよなぁ、せめて bash レベルの使える端末があれば…
Ubuntu Linux はスクリプトが書ける人なら便利過ぎるだけなのだが。

、、、、、、、、、、、、、、、、、、、、

まあそれはいい、とにかく開発。

Python を 3.0 から 2.6.2 に変更、やはり 3.0 常用はまだ早い。
IronPython を 2.0.1 から 2.6beta へ変更、setter が必要なので。

Python はインストーラが全部やってくれる。
IronPython は自分で Path を通す、一応 Vista での方法を書いておきます。

「コンピュータ」を右クリックしてプロパティ。
「システムの詳細設定(A)」をクリックしてダイアログを出す。
下のほうにある「環境変数(N)」をクリックしてダイアログを出す。
「Path」の所をダブルクリックして変数値の最後にセミコロン区切りでパスを入力。

environ

これでシェルから ipy という名前だけで使えるようになる。
Windows ばかり使っている人には何故そんなことをする必要があるか解らないかも。

ipy_path

と、ココまでやったけどやっぱりまず C# で SeeMe を。

v3 も手直ししたい所があって放置しているのでやっておこう。
ということは v4 は別プロジェクトにしないといけないわな。

SeeMe4 という別ソリューションを作りひたすらコピー。
だけではやはりエラー、名前空間を SeeMe4 に変えなきゃいけないのね。
それでもエラー、XAML 中の名前空間ってのがあると気がつくのに時間が掛かった。
一度 Visual Studio を再起動しないと XAML の再読込が失敗する場合が多いぞこのやろう。

しかし Visual Studio の C# は至れり尽くせりだ。
こんな環境でプログラミングを覚えると IDE が無いと何も作れない人になりそうだよ。
テキストエディタと IronPython では MSDN とにらめっこだしね。
ということでチャチャっと v3.2.2 を作って公開。

seemev4a

v4 は今こんな感じ、なんとか全部のデフォルト名を抜けるようになった状態。
UseTLD を追加するだけだから変更自体は簡単だけどつじつま合わせをどうするかだ。
読み込む ini の名前や位置が変わっているので設定を v3 とは別に作って…
えーとそれから…他人が作ったアプリの一部を弄くるアプリってメンドクセ!

SeeMe v4 as IronPython + WPF

ということで
SeeMe v4 は IronPython + WPF で作ることにしました。
Opera 10 正式版のファイル名やディレクトリ構成がどうなるか解らない状態だけど。

ユーザーに IronPython 2.6 のインストールを強要という暴挙ですが…
まあいいじゃないか、私は Opera より「気軽な開発」を普及させたいんだから。

seeme401

まだ Custom search.ini の読み込み部分しか作っていない。
しかし IronPython も単純に open() で開くと UTF-8 として読み込むんだね。
StreamReader を通しているのだろうけどコレなら楽チンだ。

しかし v3 と同じ外観ではつまらない。
何か面白いインターフェイスにできないかな?と模索中。
ということでここまでのバックアップ。

seeme_a401

それにしても VirtualBox 上の Windows 7 での開発はやはり辛い。
しばらく Vista HDD に戻すか悩むところ。

Linux 版はあまりにも需要が無さ過ぎるので終了する予定。
だって検索バーをドロップダウンで文字入力不能になるのでは…
v10 でなんとかなるのを期待していたんだけーがなぁ。

IronPython in Gtk #

Ubuntu 9.04 で IronPython が動かせるので Gtk# を試してみる。

Mono, Gtk# and ironpython | Kushal , kD & FOSS

まぁ他国ならこんな簡単に見つけることができるんだが。
私がよく書くコードと同様にするなら class を作って

#-*- coding:Latin-1 -*-
"""
Error
#-*- coding:utf-8 -*-
"""

import clr
clr.AddReference('gtk-sharp')

import System
import Gtk

class GtkSharpWindow(Gtk.Window):
    """
        GtkSharp Test
    """
    def __init__(self, title):
        """
            Gtk.Window.__init__(self) is No
            Constructor has been
        """
        # GtkButton
        button = Gtk.Button("Click!")
        button.Clicked += self.on_button_clicked
        # GtkTextView
        self.textview = Gtk.TextView()
        # Packing
        vbox = Gtk.VBox()
        vbox.PackStart(button, False, False, 0)
        vbox.PackStart(self.textview)
        self.Add(vbox)
        # self
        self.DeleteEvent += self.delete_event
        self.Resize(320, 100)
        self.ShowAll()

    def delete_event(self, sender, e):
        """
        	Required
        """
        Gtk.Application.Quit()

    def on_button_clicked(self, sender, e):
        """
            Button Click Signal Handrer
        """
        self.textview.Buffer.SetText("Hello World!")

if __name__ == "__main__":
    Gtk.Application.Init()
    w = GtkSharpWindow("TitleBar")
    Gtk.Application.Run()

mono_ipy1

こんな感じかな。
Gtk.Application.Init() によるライブラリ初期化は必須のようで。
__init__() にはタイトル文字列を入れないと通らない、もっと柔軟にしてくれよ。
親 class の __init__() はやっぱり不要、まぁ Windows 版と同じ exe だし。
pack_start のパラメータは一つか全部しか選べない、PyGtk ならデフォルト引数があるのに。
ShowAll() しないとウインドウを表示できませんので気をつけて。

後は…見ての通り PyGtk とほとんど変わらない。
が、どうしても気になる GtkTextView からの GtkTextBuffer 取得方法。

self.textview.GetBuffer().SetText("Hello World!")

なら解るんだがこんな関数はない。
ついでにメソッドは全部小文字に統一されている GTK+ を何故かキャメルケース化している。
DevHelp が役に立たないような GTK+ バインディングはどうなんだと思うんですけど。

ところで何故 Latin-1 ?って UTF-8 に書き換えてみてよ。

mono_ipy2

意味ワカンネ、つまり未対応ってことかな。
これじゃリテラルに日本語が使えないわな、方法模索中。

つーかやっぱり文字が見にくいのでコレ用に bash のプロファイルを作るはめになったぞと。

Enjoy!

IronEditor

IronEditor なるものを見つけた。
なんか mono でも動くらしいから試してみよう。

irb

あらら、IronPython も IronRuby も同梱なのね。
IronPython 2 系は以前 mono で試して動かなかった経験があるんだけど。

ipy

動くじゃん、ビルド方法が違うのかな?
てゆーか 1.1 もそうだけど文字色を変更するのをやめてくれないか。
まあいいや、IronEditor を起動してみる。

なんじゃこりゃ…

勝手に最大化で起動する大迷惑なことをしてくれる、何時のアプリじゃい!
mono が悪いのだろうけど一度最小化しないとウインドウ化できない。

てゆーかコレってもしかしなくても WindowsForm だよな。
せめて Gtk# にしてくれ、XP で .NET より更にレスポンスが悪いんだよ!
mono ではボタンを押してもヘコまないわ異様に待たされるわ、という現実を知ってくれよ。
少し使うと急にキーボードを受け付けなくなるし、Opera なんか可愛いレベルで。

やっぱり mono は駄目だ、JAVA と何も変わらないというか WindowsForm は Swing 以下だ。
それでもせめて Windows で使えるようなアプリなら使ってみようと思うんだが…

ironeditor

おいおい、if __name__ == “__main__”: を入れたら動かないよ!
__main__ を本体で実効しているの?これじゃ何も作れないんですけど。
Tab キーも Tab しか入れられない、日本語を打つと2つ流し込まれる。

そんな基本的な事はこれだけどエディタヲタの大好きな色分けや自動インデントはある。
なんというか…まあそんな感じであった。

でも Ubuntu 9.04 でそのまま動かせる IronPython 2.0 が手に入ったので収穫はあったぞと。
使うかどうかは今後どうなるかだが、Gtk# で可能なことは PyGtk で全部可能かつ早いしなぁ。

Enjoy!

WPF ListView DataBinding for IronPython

ぱぇぽぃ2 ? Blog Archive ? Python getter, setter
の続き、上手くいったので覚書に。
ObservableCollection を作って ListView で DataBinding させる。

Silverlight Dynamic Languages SDK – Discussions

ほう、こうすればいいんだ。
コレを IronPython 2.6 から使える property setter でやってみる。

{ironpythondir}/Tutorial/pyevent.py
をソースコードと同じ場所にコピー

追記と小変更

pyevent.py の import はこうすればコピー不要

import sys
tutorial_path = IO.Path.GetDirectoryName(sys.executable) + "\\Tutorial"
sys.path.insert(0, tutorial_path)
from pyevent import *

データトリガーなんかをコードで行う方法が解らないので XAML で。
以下ソースコード

#-*- coding:utf-8 -*-

import clr

clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")

from System import *
from System.Windows import *
from System.Windows.Controls import *
from System.Collections.ObjectModel import *
from System.ComponentModel import *
from System.Windows.Markup import XamlReader

# Search pyevent.py
import sys
tutorial_path = IO.Path.GetDirectoryName(sys.executable) + "\\Tutorial"
sys.path.insert(0, tutorial_path)
from pyevent import *

listview_str = """<ListView
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ListView.Resources>
        <Style x:Key="sensitive" TargetType="TextBlock">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=show}" Value="False">
                    <Setter Property="Foreground" Value="Silver" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <DataTemplate x:Key="tpl_show">
            <CheckBox IsChecked="{Binding Path=show}" />
        </DataTemplate>
        <DataTemplate x:Key="tpl_name">
            <TextBlock Text="{Binding Path=name}" TextTrimming="CharacterEllipsis"
                Style="{StaticResource sensitive}" />
        </DataTemplate>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Show" CellTemplate="{StaticResource tpl_show}" />
            <GridViewColumn Header="Name" CellTemplate="{DynamicResource tpl_name}" />
        </GridView>
    </ListView.View>
</ListView>"""

class NotifyPropertyChangedBase(INotifyPropertyChanged):
    """
        http://sdlsdk.codeplex.com/Thread/View.aspx?ThreadId=30322
    """
    PropertyChanged = None
    def __init__(self):
        (self.PropertyChanged, self._propertyChangedCaller) = make_event()

    def add_PropertyChanged(self, value):
        self.PropertyChanged += value

    def remove_PropertyChanged(self, value):
        self.PropertyChanged -= value
    
    def OnPropertyChanged(self, propertyName):
        self._propertyChangedCaller(self, PropertyChangedEventArgs(propertyName))


class MyData(NotifyPropertyChangedBase):
    """
        use setter getter.
        IronPython 2.6 or later.
    """
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value
        self.OnPropertyChanged("name")

    @property
    def show(self):
        return self._show

    @show.setter
    def show(self, value):
        self._show = value
        self.OnPropertyChanged("show")

class DataBindingTest(Window):
    """
        ListView DataBinding Test class
    """
    def __init__(self):
        self.data = ObservableCollection[MyData]()
        self.Resources["data"] = self.data
        self.listview = XamlReader.Parse(listview_str)
        self.listview.ItemsSource = self.data
        # Temporary Data
        datadict = {"IronPython": True,
                    "C#": False,
                    "F#": True,
                    "Python": True,
                    "Ruby": False,
                    "Perl": False,
                    "C/C++": True }
        for key in datadict.keys():
            en = MyData()
            en.name = key
            en.show = datadict[key]
            self.data.Add(en)
        self.Content = self.listview
        self.Title = "DataBindingTest"
        self.Width = 300
        self.Height = 300
        # Data Check
        self.Closed += self.on_closed

    def on_closed(self, sender, e):
        """
            Checking self.data
        """
        s = ""
        for data in self.data:
            s += "%s: %s\r\n" % (data.name, data.show)
        MessageBox.Show(s)

if __name__ == "__main__":
    a = Application()
    a.Run(DataBindingTest())

data_binding_test

見事にデータ内容と表示が一致するようになりました。
CheckBox On Off で TextBlock の色が即座に変更されます。
Ruby だけ Off に変更してみた例

ruby_off

終了時に ObservableCollection の内容を確認。

off_result

CheckBox の値がそのままデータとなっていることが解ります。
IronPython でもコレが可能なんですね、2.6 正式版が待ちどおしい。

Enjoy!