Skip to content
2月 23 11

DragBorder (自作 UIComponent の紹介)

by wetcradle

分割された領域のサイズ配分をドラッグ操作で変更できるあれです、あれ。

  • マウスアクションを受け取る余分な領域を指定可能(range プロパティ)
  • もちろん、スキンやマウスカーソルのスタイルは設定可能

サンプル

真ん中の縦線をドラッグしてみてください。

使い方

package {
	
	import com.wetcradle.skins.border.MacDragBorderCursorIcon;
	import com.wetcradle.ui.border.DragBorder;
	import com.wetcradle.ui.border.DragBorderDirection;
	import com.wetcradle.ui.border.DragBorderEvent;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	
	public class DragBorderSample extends MovieClip {
		
		private var dragBorder:DragBorder;
		
		private var leftItem:Sprite;
		private var rightItem:Sprite;
		
		private const BORDER_WIDTH:Number = 2;
		private const LEFT_ITEM_MIN_WIDTH:Number = 50;
		private const RIGHT_ITEM_MIN_WIDTH:Number = 50;
		private const STAGE_WIDTH:Number = 300;
		private const STAGE_HEIGHT:Number = 100;
		
		public function DragBorderSample():void {
			leftItem = createItem(0x663333);
			addChild(leftItem);
			
			rightItem = createItem(0x336699);
			addChild(rightItem);
			
			dragBorder = new DragBorder();
			//ドラッグ中のマウスカーソルを OS X 風に
			dragBorder.setStyle("cursorIcon", MacDragBorderCursorIcon);
			dragBorder.setSize(BORDER_WIDTH, STAGE_HEIGHT);
			//水平方向に動く
			dragBorder.direction = DragBorderDirection.HORIZONTAL;
			//左右 4px の領域でマウスアクションを有効にする
			dragBorder.range = 4;
			dragBorder.addEventListener(DragBorderEvent.DRAG, dragBorderDragHandler);
			addChild(dragBorder);
			
			refreshSize();
		}
		
		private function createItem(color:uint):Sprite {
			var item:Sprite = new Sprite();
			item.graphics.beginFill(color);
			item.graphics.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
			item.graphics.endFill();
			return item;
		}
		
		private function refreshSize():void {
			dragBorder.x = Math.max(LEFT_ITEM_MIN_WIDTH, Math.min(STAGE_WIDTH - RIGHT_ITEM_MIN_WIDTH - BORDER_WIDTH, dragBorder.x));
			
			leftItem.width = dragBorder.x;
			
			rightItem.x = dragBorder.x + dragBorder.width;
			rightItem.width = STAGE_WIDTH - rightItem.x;
		}
		
		private function dragBorderDragHandler(e:DragBorderEvent):void {
			refreshSize();
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110223.tar.gz

2月 10 11

SlideSwitch 改良しました (自作 UIComponent の紹介)

by wetcradle

以前紹介した RateSelector をちょっとだけ改良しました。

  • focusRectSkin に対応
  • スペースキー、左右のキーに対応
  • iOS 風スキン追加(com.wetcradle.skins.slideSwitch.SlideSwitchCostumer.ironSlideSwitch メソッド)

サンプル

使い方

package {
	
	import com.wetcradle.skins.slideSwitch.SlideSwitchCostumer;
	import com.wetcradle.ui.slideSwitch.SlideSwitch;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	public class SlideSwitchSample extends MovieClip {
		
		private var slideSwitch:SlideSwitch;
		
		public function SlideSwitchSample():void {
			super();
			
			slideSwitch = new SlideSwitch();
			SlideSwitchCostumer.ironSlideSwitch(slideSwitch);
			slideSwitch.selectedLabel="ON";
			slideSwitch.deselectedLabel="OFF";
			slideSwitch.move(10, 10);
			slideSwitch.setSize(150, 25);
			slideSwitch.addEventListener(Event.CHANGE, changeHandler);
			addChild(slideSwitch);
		}
		
		private function changeHandler(e:Event):void {
			trace(slideSwitch.selected);
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110210.tar

2月 2 11

RateSelector 改良しました (自作 UIComponent の紹介)

by wetcradle

以前紹介した RateSelector をちょっとだけ改良しました。

  • minimum プロパティを追加
  • liveDragging プロパティを追加
  • focusRectSkin に対応
  • 上下左右のキーに対応

サンプル

使い方

package {
	
	import com.wetcradle.ui.rateSelector.RateSelector;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	public class RateSelectorSample extends MovieClip {
		
		private var rateSelector:RateSelector;
		
		public function RateSelectorSample():void {
			rateSelector = new RateSelector();
			rateSelector.move(10, 10);
			rateSelector.setSize(100, 22);
			rateSelector.minimum = 1;
			rateSelector.value = 3;
			//rateSelector.liveDragging = true;
			rateSelector.addEventListener(Event.CHANGE, changeHandler);
			addChild(rateSelector);
		}
		
		private function changeHandler(e:Event):void {
			trace(rateSelector.value);
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110202.tar

1月 30 11

follow_logger.pl の改良版

by wetcradle

以前、公開した follow_logger.pl ですが、もっと柔軟に使えるように改良しました。

@masmt のつぶやき(公式 RT 除く)を RT するだけの @masmt_bot を作ったのですが、自分と @masmt_bot のそれぞれのフォロー関係を記録する必要が出てきたためです。

変更点

  • オプションとしてユーザ名を指定するようにした
  • オプションとして出力ファイルを指定するようにした
  • Config::Pit を使用するようにした

このスクリプトを使う場合は Config::Pit の使い方を調べてください。

使い方

以下を実行すると wetcradle がフォローしているユーザを wetcradle.following.log に、
wetcradle をフォローしているユーザを wetcradle.follower.log に追記していきます。
追記は最後の状態から変更があった場合のみ行われます。

follow_logger.pl -u wetcradle -i ./wetcradle.following.log -e ./wetcradle.follower.log

ソースコード

#!/usr/bin/perl -w

use strict;
use warnings;
use Net::Twitter;
use Config::Pit;
use File::Basename;
use Getopt::Long;

$| = 1;

########## usage ##########
sub usage {
	my $program = basename($0);
	print STDERR "$program -u screen_name [ -i following.log ] [ -e follower.log ]\n";
	print STDERR "$program -h\n";
}

########## config ##########
my $PIT_KEY = "twitter.com/follow_logger.pl";

########## option ##########
my $screen_name;
my $help_mode;
my $following_filename;
my $follower_filename;
GetOptions(
	"user=s" => \$screen_name,
	"i=s" => \$following_filename,
	"e=s" => \$follower_filename,
	"help" => \$help_mode,
);
if ($help_mode) {
	&usage();
	exit 0;
}
if (!defined($screen_name)) {
	&usage();
	exit 1;
}
if (!defined($following_filename) && !defined($follower_filename)) {
	&usage();
	print STDERR "\nfollowing.log or follower.log must be specified\n";
	exit 1;
}

########## main ##########
my $nt = &process_authorization($screen_name);
&process_following($nt, $following_filename) if (defined($following_filename));
&process_follower($nt, $follower_filename) if (defined($follower_filename));
print "done\n";

########## process_authorization ##########
sub process_authorization($) {
	my ($screen_name) = @_;
	
	print "process_authorization: $screen_name\n";
	
	my $access_token_pit_key = "$PIT_KEY/$screen_name";
	
	my $consumer_config = pit_get($PIT_KEY, require => {
		"consumer_key" => "<consumer_key of follow_logger.pl>",
		"consumer_secret" => "<consumer_secret of follow_logger.pl>"
	});
	
	my $nt = Net::Twitter->new(
		traits => ['API::REST', 'OAuth'],
		consumer_key => $consumer_config->{consumer_key},
		consumer_secret => $consumer_config->{consumer_secret},
	);
	
	my $access_token_config = pit_get($access_token_pit_key);
	my $access_token = $access_token_config->{access_token};
	my $access_token_secret = $access_token_config->{access_token_secret};
	
	if ($access_token && $access_token_secret) {
		$nt->access_token($access_token);
		$nt->access_token_secret($access_token_secret);
	}
	
	if (!$nt->authorized) {
		my ($user_id, $temp_screen_name);
		print "Authorize this app at " . $nt->get_authorization_url . "\n";
		print "Enter the PIN: ";
		my $pin = <STDIN>;
		chomp $pin;
		($access_token, $access_token_secret, $user_id, $temp_screen_name) = $nt->request_access_token(verifier => $pin);
		die "user mismatch: $screen_name != $temp_screen_name" if ($screen_name ne $temp_screen_name);
		Config::Pit::set($access_token_pit_key, data => {
			access_token => $access_token,
			access_token_secret => $access_token_secret,
		});
	}
	
	return $nt;
}

########## process_following ##########
sub process_following($$) {
	my ($nt, $following_filename) = @_;
	
	print "process_following: $following_filename\n";
	
	my $friends_ref = &get_all_friends($nt);
	my $str = "";
	if ($friends_ref) {
		my @friends = @{$friends_ref};
		foreach my $friend_hash_ref (@friends) {
			my %friend_hash = %{$friend_hash_ref};
			$str .= "," . $friend_hash{"screen_name"};
		}
		$str .= "\n";
		
		my $last_following;
		if (-f $following_filename) {
			open(FOLLOWING, "<$following_filename") || die "open failed: $following_filename";
			my @lines = <FOLLOWING>;
			close(FOLLOWING);
			$last_following = pop(@lines);
			$last_following =~ s/^\d+//;
		}
		
		if (!defined($last_following) || $str ne $last_following) {
			$str = time . $str;
			open(FOLLOWING, ">>$following_filename");
			print FOLLOWING $str;
			close(FOLLOWING);
		}
	}
	else {
		warn "friends failed\n";
	}
}

########## process_follower ##########
sub process_follower($$) {
	my ($nt, $follower_filename) = @_;
	
	print "process_follower: $follower_filename\n";
	
	my $followers_ref = &get_all_followers($nt);
	my $str = "";
	if ($followers_ref) {
		my @followers = @{$followers_ref};
		foreach my $follower_hash_ref (@followers) {
			my %follower_hash = %{$follower_hash_ref};
			$str .= "," . $follower_hash{"screen_name"};
		}
		$str .= "\n";
		
		my $last_follower;
		if (-f $follower_filename) {
			open(FOLLOWER, "<$follower_filename") || die "oped failed: $follower_filename";
			my @lines = <FOLLOWER>;
			close(FOLLOWER);
			$last_follower = pop(@lines);
			$last_follower =~ s/^\d+//;
		}
		
		if (!defined($last_follower) || $str ne $last_follower) {
			$str = time . $str;
			open(FOLLOWER, ">>$follower_filename");
			print FOLLOWER $str;
			close(FOLLOWER);
		}
	}
	else {
		warn "followers failed\n";
	}
}

########## get_all_friends ##########
sub get_all_friends($) {
	my ($nt) = @_;
	print ".";
	my $result_ref = $nt->friends({cursor => -1});
	if (!$result_ref) {
		return undef;
	}
	my %result = %{$result_ref};
	my $friends = $result{"users"};
	while ($result{"next_cursor"} != 0) {
	#{
		print ".";
		$result_ref = $nt->friends({cursor => $result{"next_cursor"}});
		if (!$result_ref) {
			return undef;
		}
		%result = %{$result_ref};
		push(@{$friends}, @{$result{"users"}});
	}
	print "\n";
	return $friends;
}

########## get_all_followers ##########
sub get_all_followers($) {
	my ($nt) = @_;
	print ".";
	my $result_ref = $nt->followers({cursor => -1});
	if (!$result_ref) {
		return undef;
	}
	my %result = %{$result_ref};
	my $followers = $result{"users"};
	while ($result{"next_cursor"} != 0) {
	#{
		print ".";
		$result_ref = $nt->followers({cursor => $result{"next_cursor"}});
		if (!$result_ref) {
			return undef;
		}
		%result = %{$result_ref};
		push(@{$followers}, @{$result{"users"}});
	}
	print "\n";
	return $followers;
}
1月 30 11

ITmedia と クラウド Watch の全文配信 RSS

by wetcradle

ITmediaクラウド Watch が微妙な RSS 配信をしているので、広告排除と全文配信化のスクリプトを作りました。

フィルタリングされた RSS

以下でフィルタリング済みの RSS を配信しています。

配信には自宅サーバも使っているので、私の都合で配信が止まったりするかもしれません。

スクリプトについて

スクリプトは filterss.rb という名前です。filter + rss です。
以下のようなフィルタリングルールを作成して、スクリプトの引数として指定してやると加工された RSS が出力されます。

<rule>
	<block>
		<target>item_title</target>
		<regexp>^AD:</regexp>
	</block>
	<extract>
		<target>item_page</target>
		<value>#article_body</value>
	</extract>
	<extract>
		<target>item_page</target>
		<value>#cmsBody</value>
	</extract>
	<extract>
		<target>item_page</target>
		<value>.newart</value>
	</extract>
</rule>

スクリプトは恥ずかしいので載せません。
見たいという人がいれば公開します。

1月 30 11

MacBook でバッテリー低下時にビープ音を鳴らす

by wetcradle

MacBook をサーバとして使っているのですが、たまに電源を別の MacBook 充電のために奪われてしまいます。
そのまま電源を戻すのを忘れていると MacBook(サーバ) がスリープしてしまうので、こんなスクリプトを crontab に登録。

#!/bin/sh

ratio=`pmset -g ps | tail -n 1 | awk '{print $2}' | sed -e "s/%.*//g"`
if [ $ratio -le 70 ]
then
	osascript -e 'beep 10'
fi
1月 23 11

RateSelector (自作 UIComponent の紹介)

by wetcradle

(2011/06/08 追記) RateSelector 改良しました (自作 UIComponent の紹介) を参照してください。

iTunes でレート設定するアレみたいなコンポーネントです。
シンプルなので特に説明することは無いです。

サンプル

使い方

package {
	
	import com.wetcradle.ui.rateSelector.RateSelector;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	public class RateSelectorSample extends MovieClip {
		
		private var rateSelector:RateSelector;
		
		public function RateSelectorSample():void {
			rateSelector = new RateSelector();
			rateSelector.move(10, 10);
			rateSelector.setSize(100, 22);
			rateSelector.value = 3;
			rateSelector.addEventListener(Event.CHANGE, changeHandler);
			addChild(rateSelector);
		}
		
		private function changeHandler(e:Event):void {
			trace(rateSelector.value);
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110123_2.tar

1月 23 11

ArrangeDataGrid (自作 UIComponent の紹介)

by wetcradle

fl.controls.DataGrid が気に入らなかったので拡張させました。

  • 列の入れ替えが可能(Mac みたいなアニメーション)
  • 入れ替えを禁止する列の指定可能
  • ヘッダを右クリックすることで表示する列を選択可能
  • ダミーレンダラ(データの無いセルの描画定義)

サンプル

使い方


package {

import com.wetcradle.skins.dataGrid.DataGridCostumer;
import com.wetcradle.skins.scrollBar.ScrollBarCostumer;
import com.wetcradle.ui.dataGrid.ArrangeDataGrid;
import com.wetcradle.ui.dataGrid.ArrangeDataGridColumn;
import fl.controls.ScrollPolicy;
import fl.controls.Slider;
import fl.controls.dataGridClasses.DataGridColumn;
import fl.data.DataProvider;
import flash.display.MovieClip;
import flash.events.Event;
//import flashx.textLayout.container.ScrollPolicy;

public class ArrangeDataGridSample extends MovieClip {

private var widthSlider:Slider;
private var heightSlider:Slider;
private var arrangeDataGrid:ArrangeDataGrid;

public function ArrangeDataGridSample():void {
configSlider();
configArrangeDataGrid();
refreshSize();
}

private function configSlider():void {
widthSlider = createSlider(10, 10, 400);
heightSlider = createSlider(10, 40, 400);
}

private function configArrangeDataGrid():void {
var columnA:ArrangeDataGridColumn = new ArrangeDataGridColumn(“a”);
//この列のユーザによる並べ替えを禁止する
columnA.arrangeable = false;
//この列のユーザによる表示/非表示の切り替えを禁止する
columnA.collapsable = false;

var columnB:DataGridColumn = new DataGridColumn(“b”);

var columnD:ArrangeDataGridColumn = new ArrangeDataGridColumn(“d”);
columnD.arrangeable = false;
//ヘッダを右クリックした時に表示されるカラムを表す文字列
columnD.collapseCaption = “D”;

arrangeDataGrid = new ArrangeDataGrid();
DataGridCostumer.macDataGrid(arrangeDataGrid);
ScrollBarCostumer.ironScrollBar(arrangeDataGrid);
arrangeDataGrid.move(10, 70);
arrangeDataGrid.columns = [columnA, columnB, “c”, columnD, “e”];
arrangeDataGrid.dataProvider = getDataProvider();
arrangeDataGrid.headerHeight = 20;
arrangeDataGrid.rowHeight = 20;
arrangeDataGrid.allowMultipleSelection = true;
//arrangeDataGrid.horizontalScrollPolicy=ScrollPolicy.AUTO;
//ユーザによる列の並べ替えを禁止する場合は arrangeable を true とする
//arrangeDataGrid.arrangeable = false;
//ユーザによる列の表示/非表示の切り替えを禁止する場合は arrangeable を true とする
//arrangeDataGrid.collapsable = false;
addChild(arrangeDataGrid);
}

private function createSlider(x, y, value):Slider {
var slider:Slider = new Slider();
slider.move(x, y);
slider.setSize(200, 3);
slider.minimum = 30;
slider.maximum = 500;
slider.snapInterval = 1;
slider.value = value;
slider.liveDragging = true;
slider.addEventListener(Event.CHANGE, sliderChangeHandler);
addChild(slider);
return slider;
}

private function getDataProvider():DataProvider {
var array:Array = new Array();
for (var i:int=0; i<15; i++) { array.push({a:i, b:Math.random(), c:Math.random(), d:1}); } return new DataProvider(array); } private function refreshSize():void { arrangeDataGrid.setSize(widthSlider.value, heightSlider.value); } private function sliderChangeHandler(e:Event):void { refreshSize(); } } } [/as3]

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110123.tar

1月 19 11

Snow Leopard で Ruby/DBI インストール

by wetcradle

メモメモ

$ export PATH=${PATH}/usr/local/mysql/bin
$ export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}/usr/local/mysql/lib
$ sudo gem install dbd-mysql
$ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
$ sudo gem install dbi

参考サイト

1月 16 11

SearchTextInput (自作 UIComponent の紹介)

by wetcradle

かなり小ネタですが、Mac でよくみる検索ボックスみたいな UIComponent を紹介します。
このコンポーネントは今回公開するライブラリから追加されました。

  • アイコンを設定可能(デフォルトでは虫眼鏡)
  • 文字が入力されている状態では削除ボタンが表示される
  • 何も文字が入力されていない状態に、設定した文字列を設定したスタイルで表示できる

サンプル

package {
	
	import com.wetcradle.ui.textInput.SearchTextInput;
	import flash.display.MovieClip;
	import flash.text.TextFormat;
	
	public class SearchTextInputSample extends MovieClip {
		
		private var searchTextInput:SearchTextInput;
		
		public function SearchTextInputSample():void {
			searchTextInput = new SearchTextInput();
			searchTextInput.move(10, 10);
			searchTextInput.setSize(200, 22);
			searchTextInput.setStyle("captionTextFormat", new TextFormat(null, 11, 0x999999));
			searchTextInput.captionText = "Google";
			addChild(searchTextInput);
		}
		
	}
}

ダウンロード

ソースコードはコメントほとんど入れてないです。ごめんなさい。
それと、ライブラリ適当に変えていくのでバージョン間に互換性はあんま無いです。

lib.20110116.tar.gz(バグが含まれていたので以下のバージョンを使用してください)
lib.20110123_2.tar.gz