のなちす
http://kuar.blog.shinobi.jp/
HP→http://sora-blue.net/~kuar/index.html
ja
2011-08-07T09:34:04+09:00
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/-c---%E3%81%82%E3%81%9F%E3%81%8B%E3%82%82%E3%83%A1%E3%83%B3%E3%83%90%E3%81%AE%E5%88%A5%E5%90%8D%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%8C%AF%E3%82%8B%E8%88%9E%E3%81%86
[C++]あたかもメンバの別名のように振る舞う
あまりこういうことには出会わないとは思うが稀にメンバの名前を変えたいとか振る舞い方を変えたいとかあったりする。
例えばWindowsでのRECT構造体。
struct RECT{
int left,top,right,bottom;
};
こいつをちょっと不便だから
struct Re...
例えばWindowsでのRECT構造体。
struct RECT{
int left,top,right,bottom;
};
こいつをちょっと不便だから
struct Rect{
int x,y,width,height;
};
にしたいと考える。
このままRectを拡張してしまえばいいじゃないかと思う人は話はここまでである。
しかしまあ、このまま拡張しても不便だから。特にRECTの参照渡しをする機会が多いのでその都度
RECT rect = Rect.RECT();
hoge(&rect);
とするのも面倒なわけである。
そのままダイレクトに引数に入れるために継承を行うとする。
struct Rect:public RECT{
};
メンバをどうするかである。プロパティとしてはx,y,width,heightとして扱いたい。
xとyに関しては少々不細工であってもleftとrightのポインタを持っておけばなんとかなりそうでもない。
struct Rect:public RECT{
Rect():x(&left),y(&top){}
int* x,y;
};
widthやheightはそうはいかない。widthはright-left、heightはbottom-topという式になる。
struct Rect:public RECT{
Rect():x(&left),y(&top){}
int width()const{return right-left;}
int width(int newWidth){return right = left + newWidth;}
int height()const{return bottom-top;}
int height(int newHeight){return bottom = top + newHeight;}
int* x,y;
};
形はどうであれこれでひとまずは、できたかのように思える。
しかしもっと自然に振舞いたいと思うわけである。
*rect.x = 1;
rect.width(3);
これを
rect.x = 1;
rect.width = 3;
などど記述できればまさにメンバの名前を変えたように振る舞っているといえよう。実際に振る舞えるようにしてみる ]]>
未選択
2011-08-07T09:34:17+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/nstextview%E3%81%AE%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E4%BD%8D%E7%BD%AE%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B
NSTextViewのカーソル位置を取得する
なかなか見つからないカーソル位置の取得関数。こんな関数名で実装されてたらそらわからんわなー。
NSTextFieldのカーソル位置も同じメソッドで取得することができる。
このRectはカーソルのフレームであるため、原点が左下のCocoaでは、y軸をheightだけ引く処理が必要になるであろう。
...
NSTextFieldのカーソル位置も同じメソッドで取得することができる。
このRectはカーソルのフレームであるため、原点が左下のCocoaでは、y軸をheightだけ引く処理が必要になるであろう。
NSRect rect = [textView firstRectForCharacterRange:[textView selectedRange]];]]>
未選択
2011-02-21T09:45:50+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/%E7%84%A1%E9%A1%8C_426
無題
Cocoaを参考に自作しているFrameWorkの描画についての高速化の覚え書き。
まず前提として、Windowに対してViewが1枚貼られている。規定となるViewである。
CocoaでいうNSWindowのcontentLayerに該当する。
ちなみにこのViewは常にWindowsサイズ...
まず前提として、Windowに対してViewが1枚貼られている。規定となるViewである。
CocoaでいうNSWindowのcontentLayerに該当する。
ちなみにこのViewは常にWindowsサイズと同じサイズになるようにWindowのサイズ変更が行われると、このViewのサイズも変更される。
Viewについてはレイヤー構造となっており、Viewが配列を有しており、addSubViewするとpush_backされる。
ViewはsuperViewへのポインタを格納している。無論subViewsも。因みにcontentLayerのsuperViewはNULL。
上の階層へ行くには連結リストを利用し、下の階層へは配列でアクセスすることになる。
描画はViewがもつdrawRect(Rect rect)で行う。Viewが持つdrawRect関数に関してはsubViewに対してdrawRect関数を呼ぶだけなので画像やテキストを描画する際にはViewを継承したImageViewやTextViewを利用する。
引数のrectが描画する四角形である。再描画処理は重いので必要最低限の範囲で行う。
例えばWindowサイズが800*600に対して再描画するViewが100*50だったなら、Viewの100*50だけ再描画する。
半透明などが絡むと混色処理が必要になるので再描画はcontentLayerからdrawRect関数を呼び出す。
また、contentLayerを持っているのはWindowなので実際には再描画はWindowに対して再描画するように命令を出す。
実際に関数はこんな感じ
struct Rect{
Rect()x(0),y(0),width(0),height(0){}
Rect(int _x,int _y ,int _width,int _height)x(_x),y(_y),width(_width),height(_height){}
int x,y,width,height;
};
class Window{
public :
virtual void drawRect(Rect rect);
private :
View* m_contentLayer;
};
class View{
public :
View(Rect rect);
virtual void drawRect(Rect rect);
virtual void repaint();
private :
Rect m_rect;
std::vector m_subViews;
};
void Window::drawRect(Rect rect){
contentLayer->drawRect(rect);
}
void View::drawRect(Rect rect){
// ここに何かしら描画処理
std::vector::iterator it = m_subViews.begin();
std::vector::iterator end = m_subViews.end();
for (; it != end; ++it){
(*it)->drawRect(rect);
}
}
再描画関数に関しては自身のx,yからwidth,heightだけ再描画すればいいので
void View::repaint(){
m_window->drawRect(m_frame);
}
となる。因みにcontentLayerはWindowへのポインタを持っており、addSubViewを呼び出すことにより、子にもwindowへのポインタが渡されるため、addSubViewされている全てのviewはwindowにアクセスできる。
画像に関してはもしも再描画したいViewが半透明ではない場合、contentLayerから描画するのは無意味である。
なぜなら混色が行われない以上、そのViewから下の階層のレイヤーしか見えないのだから。
void Window::drawRect(Rect rect,View* view){
if (view == NULL ){
contentLayer->drawRect(rect);
}else {
view->drawRect(rect);
}
}
この実装により、200枚ImageViewを貼ったとしても見える部分しか描画しないので処理は画像を2〜3枚貼る程度に収めることができる。
ただ、if文或いは三項条件演算子を通るコストはかかるが……。
実際にはsuperViewが該当のviewの背面に写るであろうviewとは限らない。
というと構造はsuperViewのsubViewsの中にviewそのものが格納されている。
もしviewがsuperViewから見てsubViewsの[1]以上であれば、superViewとviewの間に他のviewが存在する。
しかし、そのviewは再描画するべきviewと完全に重なっている保証はないため、完全に重なっているsuperViewに対して処理を行なっている。
最も、superViewのsubViewにviewが100枚とかあるとsuperViewとviewの間のviewへ問い合わせる処理にしないと最適化にならないが、
ここでは少量のviewしか扱わないことを前提としてこの実装にしている。
void View::repaint(){
m_window->repaint(m_frame,this );
}
因みに不可視 or alphaが0なら描画の必要はないため
void View::drawRect(Rect rect){
if(m_alpha != 0){
//ここに何かしら描画処理
std::vector::iterator it = m_subViews.begin();
std::vector::iterator end = m_subViews.end();
for (; it != end; ++it){
(*it)->drawRect(rect);
}
}
}
自身が見えないのであれば当然subViewも見えないわけである。
見えるようにしたければ子の描画処理をifの外へ出してやるといい。ただ、不便なのは間違いない。
では、半透明だった場合を考える。半透明であれば混色が必要となる。
しかし半透明だから諦めてcontentLayerから描画するのは重すぎる。
なので半透明か否かをsuperViewへ問い合せて不透明ならそこから描画、半透明ならさらにsuperViewへ問い合わせ…ということにする。
連結リストなのでアクセスは遅いが描画をするよりかはマシだろう。
View* view::getSuperOpaqueView(){
return (m_superView->getAlpha == 255) ? m_superView : m_superView->getSuperOpaqueView();
}
void View::repaint(){
if (m_alpha == 255){
m_window->drawRect(m_rect,this );
}else {
m_window->drawRect(m_rect,getSuperOpaqueView());
}
}
ここでは不透明の値が255と定義されているのもとする。モノによっては1.0とかだったりするので状況に合わせて値を変えてほしい。
因みにこれは人によりけりであるが、addSubViewやsetAlpha、setVisible、setFrameなどViewを弄るような関数を利用する場合
自動的にrepaintするか否かである。基本的には自動でrepaintしたほうが便利だがこれでは高速化は望めない。
速さを気にする人なら明示的にrepaintを行うようにするといい。どっちもという人はwindowにisAutorepaintという関数をひとつ作って、局所的にするといい。
void addSubView(View* view){
m_subViews.push_back(view);
if (m_window->isAutoRepaint()){
repaint();
}
}
実際に使うときは
m_window->setAutoRepaint(false );
for (int i=0;i<100;++i){
addSubView(new View(Rect(0,0,100,100)));
}
m_window->setAutoRepaint(true );
repaint();
とするとわりと高速に動作するようになる。
複数のWindowを扱う時を想定して、Windowのメンバ関数にしてある。
全Windowおかまいなしにしたいなら広域変数でいいだろう。
ここでは特に何も書いていないがdrawRect関数には本来ならば他にも複数の引数が絡むことになり、Windows32APIであれば、HDCもしくはHWNDが、DirectXであればLPDIRECT3D9、LPDIRECT3DDEVICE9などが入ることになるであろう。故にdrawRect関数そのものは直接呼び出すことはできないであろう。最も実装によっては可能と言えば可能だが難しいと私は思う。]]>
未選択
2011-01-04T19:43:15+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/%E7%84%A1%E9%A1%8C_425
無題
HPを更新しました。ツイッターの登場でますますブログとHPの影が薄いです。
mixiも殆どサンシャイン牧場やって他人の日記見るしかやってない!
ツイッターに殆ど書きたいことを書いてしまうのでこのブログもあまり意味をなしていない状況。
とりあえずはプログラムで詰まったところを書いとくみたいな感じ...
mixiも殆どサンシャイン牧場やって他人の日記見るしかやってない!
ツイッターに殆ど書きたいことを書いてしまうのでこのブログもあまり意味をなしていない状況。
とりあえずはプログラムで詰まったところを書いとくみたいな感じではあるがそれもツイッターに取られてしまっている。
とりあえず今回はCALayerのcontentsについての記述。
CALayerのcontentsはどうもすぐに内容をreleaseしてしまうのかあとからaddSublayerするとBusErrorに。
layer.contents = (id)[image CGImage];
じゃあretainすりゃいいじゃんって思って
[[image CGImage] retain]
こいつでもダメ。
CGImageRefをretainする関数があったんだけどそれでもダメ。
どうしたもんかなー。]]>
未選択
2010-12-23T14:54:18+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/-vc--6-%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%BB%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E8%A8%AD%E5%AE%9A
[VC++6]スクリーンセーバーのデバッグ設定
プロジェクト設定
・デバッグ
実行ファイル:○○.exe->○○.scr
プログラムの引数:/s
・リンク
出力ファイル名:○○.exe->○○.scr
これでF5でスクリーンセーバーのデバッグができる。
ただし結局はOutputDebugStringやprintf...
・デバッグ
実行ファイル:○○.exe->○○.scr
プログラムの引数:/s
・リンク
出力ファイル名:○○.exe->○○.scr
これでF5でスクリーンセーバーのデバッグができる。
ただし結局はOutputDebugStringやprintfが使えないので難儀である。
MessageBoxは使えるが使い物にはならないし必要ならファイル出力でもするか?]]>
未選択
2010-04-11T09:10:35+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/%E6%9C%AA%E9%81%B8%E6%8A%9E/nsslider%E3%81%AE%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E5%87%A6%E7%90%86
NSSliderのドラッグ処理
mouseDragged:(NSEvent*)theEventを使うように感じるがそういったメソッドは存在しない。
マウスドッグではなくIBActionを使う。
-(void)awakeFromNib{
&#x0009;NSSlider* slider = [[NSSlider allo...
マウスドッグではなくIBActionを使う。
-(void)awakeFromNib{
NSSlider* slider = [[NSSlider alloc] initWithFrame:NSMakeRect(0,0,100,100)];
[slider setTarget:self];
[slider setAction:@selector(sliderMove:)];
}
-(IBAction)sliderMove:(id)sender{
NSLog(@"move!");
}
ドラッグされようがクリックされようが呼び出される。]]>
未選択
2010-03-18T21:11:51+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/objective-c/nsimage%E3%81%A7dpi%E3%82%92%E7%84%A1%E8%A6%96%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95
NSImageでdpiを無視する方法
NSImageはdpiを判別できないことがあるらしい。
その為画像が勝手に縮小されたりするのでその回避法。
http://arms22.blog91.fc2.com/blog-entry-101.html
これで画像もちゃんと表示されるし、[image size]で正確なサイズも返ってくる...
その為画像が勝手に縮小されたりするのでその回避法。
http://arms22.blog91.fc2.com/blog-entry-101.html
これで画像もちゃんと表示されるし、[image size]で正確なサイズも返ってくる。]]>
Objective-C
2010-02-20T09:33:04+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/objective-c/%E3%81%AC%E3%82%8B%E3%81%BD_421
ぬるぽ
Objective-CにおいてNULL(nil)のオブジェクトを参照しても何も起こらない。
JavaのようにNullpointerExceptionなどは出ずただ、何も起こらない。
これがあるからOutletが外れてても気付けないんだ。
...
JavaのようにNullpointerExceptionなどは出ずただ、何も起こらない。
これがあるからOutletが外れてても気付けないんだ。
]]>
Objective-C
2010-02-14T23:32:44+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/unix%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/airmac%E3%81%AEon%E3%80%81off%E3%82%92%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%8B%E3%80%82
AirMacのon、offを切り替える。
ググってもなかなか見つけられないのでメモ。
UNIXコマンドでAirMacを切り替える。
sudo networksetup -setairportpower off
sudo networksetup -setairportpower on
-getairportpowerで現在の状態...
UNIXコマンドでAirMacを切り替える。
sudo networksetup -setairportpower off
sudo networksetup -setairportpower on
-getairportpowerで現在の状態を確認できます。
MacOS 10.5.3以下くらいならsudo ifconfig en1 up/downでも切り替わりますがそれ以降あたりからdownはきくけどonできなくなるみたいです。
ifconfigのほうはあくまでもUNIX用らしくApple純正はnetworksetupとかなんとか。
airportコマンドで接続先を変更。
airport -s・・接続先検索
airport -I・・現在の状態
scselectコマンドでネットワーク環境切り替え。
scselect ・・・ネットワーク一覧。
scselect Automatic・・・ネットワークを自動へ切り替え
sudo ipconfig set en1 DHCP・・・DHCPリース。でもたまにIPアドレスがぶっ飛ぶので多分networksetup・・
というよりこのあたり一体全部networksetupでできることは全部やったほうがいい気がする。
-helpに大体書いてあるので大抵のことはできる。
詳しくはgoogle先生にお願いしていください。
これでUNIXコマンドでネットワーク全般を全て弄ることができる。]]>
UNIXコマンド
2010-02-10T12:20:13+09:00
Kuar
NINJA BLOG
Kuar
-
http://kuar.blog.shinobi.jp/objective-c/%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E5%87%A1%E3%83%9F%E3%82%B9
よくある凡ミス
・nilとか返ってくると思ったらOutletが外れていた。
XCodeのコンソールからはわからないので侮れない。
でもnibみたらすぐわかる。
・サブクラス化しているのに他のクラスではsuperClassでキャストしてしまってメソッドなどが無いと怒られる。
Ex: CustomView...
XCodeのコンソールからはわからないので侮れない。
でもnibみたらすぐわかる。
・サブクラス化しているのに他のクラスではsuperClassでキャストしてしまってメソッドなどが無いと怒られる。
Ex: CustomView.m
@interface CustomView : NSView{}
(他のclassで)
IBOutlet NSView* view;
・[NSObject alloc] init]してない。
・autoreleaseで消えてしまってる。広域宣言だろうとautoreleaseが呼ばれて消えるのでautoreleaseが呼ばれるメソッドは要注意。[NSString stringByXXXXX]とか[NSArray arrayWithXXXX]とか。]]>
Objective-C
2010-02-09T20:17:28+09:00
Kuar
NINJA BLOG
Kuar