2011.08.17
Posted in Work | No Comments »
2011.08.14
OS X 10.5から追加された NSView の enterFullScreenMode:withOptions:、exitFullScreenModeWithOptions:を使ったフルスクリーンの実装サンプル。
環境
- OS X 10.6.7
- Xcode 4.0.2
- ビルドターゲットのバージョンは10.5以降が必須。
1. 新規プロジェクト作成
- Cocoa アプリケーションのプロジェクトテンプレートで新規プロジェクトを作成。
2. AppControllerクラスファイルの作成
- AppController.h
- AppController.m
3. MainViewクラスファイルの作成
4. IBでMainViewの配置と設定
- XcodeのNavigator AreaからMainMenu.xibをクリックしてUI編集画面を表示する。
- Object Libraryから「Object」をXcode の 「Dock」にドラッグアンドドロップ。
- 配置したObjectをクリックして、インスペクタペインの「Custome Class」にMainViewと入力する。
5. IBでAppControllerの設定
- XcodeのNavigator AreaからMainMenu.xibをクリックしてUI編集画面を表示する。
- Object Libraryから「Object」をXcode の 「Dock」にドラッグアンドドロップ。
- 配置したObjectをクリックして、インスペクタペインの「Custome Class」にAppControllerと入力する。
- 「Assistant Editor ボタン」をクリックして、AppController.h に MainView をアウトレットとして接続する。
6. IBで「Full Screen」メニューアイテムの追加
- XcodeのNavigator AreaからMainMenu.xibをクリックしてUI編集画面を表示する。
- Object Libraryから「Menu Item」をメニュー「View」以下(別にどこでもよいけど)に配置する。
- 配置した「Menu Item」を選択し、インスペクタペインの「Title」に「Full Screen」、「Key Equivalant」には「Cmd + F」を設定する。
- 「Assistant Editor ボタン」をクリックして、AppController.h に向けて「Menu Item」からCtrl + クリックでアクションを接続する。アクション名はとりあえず「fullscreen」とする。
※ 「Cmd + F」は既に他のメニューアイテムによって使われているので、とりあえず、「View」以外のメニューは削除しておくか、フルスクリーンのキーボードショートカットを「Cmd + F」以外にする必要がある。
7. MainViewクラスの実装
#import <Foundation/Foundation.h>
@interface MainView : NSView
{}
@end
#import "MainView.h"
@implementation MainView
@end
8. AppControllerクラスの実装
#import <Foundation/Foundation.h>
@class MainView;
@interface AppController : NSObject
{
IBOutlet MainView *mainView;
}
- (IBAction)fullscreen:(id)sender;
@end
#import "AppController.h"
@implementation AppController
#pragma - menu
- (IBAction)fullscreen:(id)sender
{
NSLog(@"isInFullScreenMode: %i", [mainView isInFullScreenMode]);
NSDictionary *fullscreenOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSFullScreenModeSetting];
if([mainView isInFullScreenMode]){
[mainView exitFullScreenModeWithOptions:fullscreenOptions];
}
else{
[mainView enterFullScreenMode:[NSScreen mainScreen] withOptions:fullscreenOptions];
}
// mainViewをFirst Responderにすることで、フルスクリーン表示後にキーボードイベントを受け取れるようにする。
// でないと、ショートカットキー(Cmd + F)でフルスクリーンを解除できなくなる。
[[mainView window] makeFirstResponder:(NSResponder *)mainView];
}
@end
ソース
その他
Posted in blog | No Comments »
2011.07.29
スライドショーの作例。
開発環境
- OS X 10.6.2
- flex_sdk_4.1.0.16076
- rascut 0.2.1
rascutを使っての環境構築の記事:http://d.hatena.ne.jp/nitoyon/20070914/how_to_install_rascut
key points
- そうめん(擬似thread)を使わせてもらいました。
- Tweener
- XMLで動きを定義しています。
デモ
ソース
Posted in blog | No Comments »
2011.05.09
を作ってみました。Safari、Firefox、Chromeだとたぶん動く、IEだと動かない。
screen shot:

主な構成要素
- CodeIgniter 2.0
- Doctrine
- MySQL
- Flash
- jQuery
Posted in blog | No Comments »
2011.02.05
CodeIgniter 2.0 のブランチ
- http://d.hatena.ne.jp/Kenji_s/20110129/1296265837
- CodeIgniter Core
- CIの開発元であるEllisLab の商用製品( Such as ExpressionEngine and MojoMotor )で使用されるブランチ
- CodeIgniter Reactor
- これがオープンソースコミュニティのためのメインブランチ。
- CI コミュニティで育てていくためのブランチ。
- 新機能、バグフィックス、改良、ドキュメンテーションの整備はこちらで行なわれる。
- EllisLabによる CodeIgniter Core の成果物もこちらにマージされていく。
大きな変更点、新機能
- PHP 4 サポートの廃止。今後は PHP 5.1 以上が必須要件となる。
- フォームヘルパーでのCSRFプロテクション
- Drivers
- Application Packages
- Scaffoldingの廃止。
- Validationクラスは削除されました。=> Form Validationクラスを使う。
- 今までのPlugin機能の削除。ヘルパーを使ってね。
- Added routing overrides to the main index.php file, enabling the normal routing to be overridden on a per “index” file basis.
- メインのindex.phpファイルを上書きするルーティングが追加されたので、通常のルーティングを有効にするには各"index"ファイルを上書きする。(よくわかんね)
- 404ページをコントローラで制御するために$route[‘404_override’]を追加しました。
- 50以上のバグフィックス。
Reactor には上記のものすべてに加え、以下のナイスな独自変更を含んでいる(以下のものはCoreには含まれないという意味だろう):
- GETクエリ文字列の完全なサポート。
- base_urlがブランクなら自動的に探知する。
- ファイルシステムによる新しいキャッシュドライバー、APCとmemcacheのサポート
- 簡単なcronジョブのためのコマンドラインに対応する。
- 20以上の調整と改善。
すべての変更点はchange logをご覧あれ
コアクラスの拡張
コアクラス(system/core 内の CI_Controller など)の拡張クラス(MY_Controller)は
に配置する必要がある。
つまり application/libraries/MY_Controller.php は、application/core/MY_Controller.php に移動する必要がある。
system/libraries 内のクラスの拡張は 今まで通り application/libraries に配置してOK
refs
追記 2012.02.11
- php5.3からはCIではなく、fuelPHPを使わせてもらうとこにした。
- CIのライセンス問題ではなく単に実装の好みの問題で。
Posted in blog | No Comments »
2011.01.27
参考リンク
ポイント
- (1). browser.xulに を配置する。
- (2). nsIWebProgressListenerインターフェースを実装したオブジェクトを作成する。
- (3). (2)で作成したオブジェクトを gBrowser.addProgressListener でgBrowserにセットする。
(1). browser.xul の一部
<!-- ... -->
<browser type="content" flex="1" id="content"/>
<!-- ... -->
<statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
<image src="chrome://yobrowser/content/throbber.gif" id="throbber-image"/>
<progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/>
</statusbarpanel>
<!-- ... -->
(2)(3). MyProgressListenerの実装とセット
var gBrowser = null;
var gProgressMeterPanel = null;
function BrowserStartup()
{
// ....
gBrowser = document.getElementById("content");
gProgressMeterPanel = document.getElementById("statusbar-progresspanel");
gBrowser.addProgressListener(MyProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
// ....
}
var MyProgressListener = {
, statusMeter: null // progressmeter
, QueryInterface: function(aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
}
, onProgressChange : function (aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress)
{
if (aMaxTotalProgress > 0) {
var percentage = (aCurTotalProgress * 100) / aMaxTotalProgress;
this.statusMeter.value = percentage;
}
}
, onStateChange: function (aWebProgress, aRequest, aStateFlags, aStatus)
{
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
const nsIChannel = Components.interfaces.nsIChannel;
if(aStateFlags & nsIWebProgressListener.STATE_START && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK){
dump("読み込み開始");
var location = aRequest.QueryInterface(nsIChannel).URI;
gProgressMeterPanel.collapsed = false;
this.statusMeter = document.getElementById("statusbar-icon");
this.statusMeter.value = 0;
}
else if (aStateFlags & nsIWebProgressListener.STATE_STOP && aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
dump("読み込み終了");
gProgressMeterPanel.collapsed = true;
}
}
, onLocationChange: function (aWebProgress, aRequest, aLocationURI)
{}
, onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage)
{}
, onSecurityChange: function (aWebProgress, aRequest, aState)
{}
}
Posted in blog | No Comments »
2011.01.15
指定したセレクタ内の h1...h6 からTOCを生成する。デフォルトでは <div id="summary"></div> 内に生成される。
download
ソース
;(function($){
var namespace = "createSummary";
$.fn[namespace] = function(config) {
var config = $.extend({
where:'#summary'
}, config);
var target = this;
$(config.where).append('<ul></ul>');
var ul = '<ul style="margin-left:2em;"></ul>';
var h = $(target).find('h1, h2, h3, h4, h5, h6');
function getN(ele)
{
ele.nodeName.match(/(\d)/i);
return RegExp.$1;
}
$.each(h, function(i, v)
{
var n = getN(v);
var t = 'h'+n+'-'+i;
var li = '<li>' + '<a href="#' + t + '">' + $(v).text() + '</a>' + '</li>';
$(v).append('<a name="' + t + '"></a>');
if(i <= 0){
$(config.where + " ul:last").append(li);
}
else{
var p_n = getN(h[i-1]); // prev n
if(n < p_n){
$(config.where + " ul:last").parents('ul:last').append(li);
}
else if(n > p_n){
$(config.where + " li:last").append(ul);
$(config.where + " ul:last").append(li);
}
else{
$(config.where + " li:last").after(li);
}
}
});
};
})(jQuery);
使い方
<html>
<head>
<script type="text/javascript">
jQuery(function($){
// div.entry 内の見出しタグ(h1 ... h6)から div#summary 内にTOCを生成
$("div.entry").createSummary();
});
</script>
</head>
<body>
<div id="summary"></div>
<div class="entry">
<h1>見出し1</h1>
<h2>見出し2</h2>
<h3>見出し3</h3>
</div>
</body>
Posted in blog | No Comments »
2011.01.08
エンタープライズアプリだとよくあるご要望で、とにかくなんか処理を起動したら、終わるまで画面をいじれないようにしたい。
index.html
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>screenlock test</title>
<script type="text/javascript" src="./jquery.js"></script>
<script type="text/javascript">
$(function() {
$("#Btn").click(function(evt)
{
lockScreen();
//「?time=xxxx」はIEのキャッシュ対策
var url = './main.php?' + new Date().getTime();
$.getJSON(url, function(evt)
{
// サーバーからレスポンスがあった
unlockScreen();
alert(evt[0]);
});
});
function lockScreen()
{
$("body").append('<div id="LockScreen" style="position:absolute;left:0;top:0;width:100%;height:100%;color:black;background:white;opacity:0.8;filter:alpha(opacity=80);"><p align="center">現在重い処理をしてます。<br />しばらくお待ちくださいでやんす。<br /><img src="loading.gif" /></p></div>');
}
function unlockScreen()
{
$("#LockScreen").remove();
}
});
</script>
</head>
<body>
<input type="button" name="btn" id="Btn" value="処理開始" />
</body>
</html>
main.php
<?php
// なんか重い処理
sleep(10);
// レスポンスする
$ret = array(
'処理完了'
);
echo json_encode($ret);
Posted in blog | No Comments »
2010.12.15
$ export ZF_CONFIG_FILE=./.zf.ini
$ php scripts/zf show config
User Configuration: ./.zf.ini
|-- php
| `-- include_path: /Users/yokada/work/web/49283/site/pragma/libs:.
|-- basicloader
| `-- classes
| |-- 1: Pragma_Tool_Provider_Hello
| `-- 2: Pragma_Tool_Provider_Doctrine
`-- basePath: /Users/yokada/work/web/49283/site
または、一行で、
$ ZF_CONFIG_FILE=./.zf.ini zf show config
指定した設定ファイルが無ければ、HOMEディレクトリ(ZF_HOME、HOME、HOMEPATH、USERPROFILE)の環境変数のパスにある .zf.ini が読み込まれる。
Posted in blog | No Comments »
2010.12.14
デフォルトではリクエストオブジェクトはFrontControllerによるディスパッチループの本体であるdispatchメソッドで初期化されるが、ブートストラップでリクエストオブジェクトを利用して、URLごとに処理を振り分けたい場合に。
モジュールを使わない場合
application/Bootstrap.php でリクエストオブジェクトを初期化する
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initRequest()
{
$request = new Zend_Controller_Request_Http();
Zend_Controller_Front::getInstance()->getRouter()->route($request);
var_dump($request);
/**
* /a/b/c をリクエストした場合
*
object(Zend_Controller_Request_Http)[10]
protected '_paramSources' =>
array
0 => string '_GET' (length=4)
1 => string '_POST' (length=5)
protected '_requestUri' => string '/a/b/c' (length=6)
protected '_baseUrl' => string '' (length=0)
protected '_basePath' => null
protected '_pathInfo' => string '/a/b/c' (length=6)
protected '_params' =>
array
'controller' => string 'a' (length=1)
'action' => string 'b' (length=1)
'module' => string 'default' (length=7)
protected '_rawBody' => null
protected '_aliases' =>
array
empty
protected '_dispatched' => boolean false
protected '_module' => string 'default' (length=7)
protected '_moduleKey' => string 'module' (length=6)
protected '_controller' => string 'a' (length=1)
protected '_controllerKey' => string 'controller' (length=10)
protected '_action' => string 'b' (length=1)
protected '_actionKey' => string 'action' (length=6)
*/
}
}
モジュールを使う場合(Aというモジュールを例とする)
application/modules/a/Bootstrap.php でリクエストオブジェクトを初期化する。
<?php
class A_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initModuleRequest()
{
$request = new Zend_Controller_Request_Http();
Zend_Controller_Front::getInstance()->getRouter()->route($request);
var_dump($request);
/**
* /a/b/cをリクエストした場合
*
object(Zend_Controller_Request_Http)[31]
protected '_paramSources' =>
array
0 => string '_GET' (length=4)
1 => string '_POST' (length=5)
protected '_requestUri' => string '/a/b/c' (length=6)
protected '_baseUrl' => string '' (length=0)
protected '_basePath' => null
protected '_pathInfo' => string '/a/b/c' (length=6)
protected '_params' =>
array
'module' => string 'a' (length=1)
'controller' => string 'b' (length=1)
'action' => string 'c' (length=1)
protected '_rawBody' => null
protected '_aliases' =>
array
empty
protected '_dispatched' => boolean false
protected '_module' => string 'a' (length=1)
protected '_moduleKey' => string 'module' (length=6)
protected '_controller' => string 'b' (length=1)
protected '_controllerKey' => string 'controller' (length=10)
protected '_action' => string 'c' (length=1)
protected '_actionKey' => string 'action' (length=6)
*/
}
}
モジュールを使う場合は、実際は自分用のモジュールブートストラップ(MyModuleBootstrap extends Zend_Application_Module_Bootstrap) を作成して、そこに初期化処理を書くことになると思う。
Posted in blog | No Comments »