ずっと君のターン

2008-07-21 主に曇り

protocalendar用のウィジェット

| 01:57 | protocalendar用のウィジェット - ずっと君のターン を含むブックマーク

日付を簡単に入力したかったのでprotocalendar.js用のウィジェットを作ってみた。

こんだけ。今のところprotocalendarのオプションは何も設定できない。

# widgets.py
from django import newforms as forms

class CalendarWidget(forms.TextInput):
  def render(self, name, value, attrs=None):
    return super(CalendarWidget, self).render(name, value, attrs) + """
      <script type="text/javascript">
         InputCalendar.createOnLoaded('%s');
      </script>
    """ % attrs['id']

使い方はこう。

import time
import widgets
class YourForm(djangoforms.ModelForm):
  class Meta:
    model = models.YourModel
  date = forms.CharField(widget=widgets.CalendarWidget, initial=time.strftime('%m/%d/%Y'))

現在日付を初期値にする必要がないならimport timeとinitialオプションはいらない。

2008-02-18 雲一つない

injectをwhileの代わりに使う

| 14:17 |  injectをwhileの代わりに使う - ずっと君のターン を含むブックマーク

Railsのacts_as_treeで、あるノードの親を全て取得するのに

def parents
  ret = []
  current = self
  while current.parent
    ret << current.parent
    cur = current.parent
  end
  ret
end

とかやってたんですけど、どうもどんくさくて嫌なので無理やり回避。

class LazyArray                                                
  def initialize(first, &next_block)                           
    @current = first                                           
    @next_block = next_block                                   
  end                                                          
                                                               
  def inject(sum, &block)                                      
    block.call sum, @current                                   
    inject sum, &block if @current = @next_block.call(@current)
    sum                                                        
  end                                                          
end                                                            

って言うのを作って、修正後はこう。

def parents
  LazyArray.new(parent){|d| d.parent}.inject([]){|s, d| s << d}
end

LazyArrayという名前が誇大に過ぎると言う文句は、まぁその通りだと思います。

2008-02-16 快晴なのに休出

サブディレクトリ内のコントローラに同一ディレクトリ内のapplication.rhtmlを適用

| 11:34 | サブディレクトリ内のコントローラに同一ディレクトリ内のapplication.rhtmlを適用 - ずっと君のターン を含むブックマーク

admin/top_controller.rbにはviews/layouts/admin/application.rhtmlを自動的に適用して欲しかったので、とりあえず次のようにしてみた。

app/controller/application.rb

class ApplicationController < ActionController::Base
  class <<self
    def default_layout_with_subdirectory
      l = default_layout_without_subdirectory
      if l == 'application' and name.include? '::'
        subdir_layout = "#{File.dirname name.underscore}/application"
        if File.exist? "#{RAILS_ROOT}/app/views/layouts/#{subdir_layout}.rhtml"
          return subdir_layout
        end
      end
      l
    end
    alias_method_chain :default_layout, :subdirectory
  end

  # 以下略

(注)application.rxmlには対応してません。

NOVNOV 2008/02/17 00:38 ついでだし
”#{File.dirname name.underscore}/#{File.basename name.underscore}”
にも対応すると、もっと使いやすいかもです♪

technohippytechnohippy 2008/02/17 11:23 んー、これはレイアウトをデフォルトで共有するための変更なので、NOVさんのだと私の希望の動作とかなり違っちゃってます・・・

2008-01-11 どんにょり

配列からランダムに指定数分アイテムを抜き出す

| 16:51 |  配列からランダムに指定数分アイテムを抜き出す - ずっと君のターン を含むブックマーク

def pick_some(num, ary)
  (1..num).inject([]){|s, e| s << ary.delete_at(rand(ary.size))}.compact
end

順序は崩れます。

inject使いたいのでtimes doじゃなくてむりやりRangeにした。

2007-10-06 くもり

画像をクリッピング

| 00:34 |  画像をクリッピング - ずっと君のターン を含むブックマーク

たとえば100x100の画像に10x10のマージンを用意するにはこんな感じ。

draw.define_clip_path 'clip' do
  draw.path "M 10 10 L 10 90 L 90 90 L 10 90 z"
end
draw.push
draw.clip_path 'clip'
# draw使っていろいろ描画
draw.pop

パス指定のフォーマットはSVGのパスと同じらしい。

名前つきのパスを定義して、パス名でクリップ領域を指定しないとだめらしい。

あと、pushとpopがなぜか必要らしい。


なんかごちゃごちゃするのでMagick::Drawに次のようなメソッドを追加した。

class Magick::Draw
  def within_clip(svg_path, &block)
    clip_name = "clip#{Time.now.to_i}"
    define_clip_path(clip_name){path svg_path}
    push
    clip_path clip_name
    block.call
    pop
  end
end
draw.within_clip("M 10 10 L 10 90 L 90 90 L 10 90 z") do
  # 描画
end

問題なく動いてるっぽい。