Home | History | Annotate | Download | only in views
      1 #include "SkWindow.h"
      2 #include "SkCanvas.h"
      3 #include "SkOSMenu.h"
      4 #include "SkSystemEventTypes.h"
      5 #include "SkTime.h"
      6 
      7 #define SK_EventDelayInval "\xd" "n" "\xa" "l"
      8 
      9 #define TEST_BOUNDERx
     10 
     11 #include "SkBounder.h"
     12 class test_bounder : public SkBounder {
     13 public:
     14 	test_bounder(const SkBitmap& bm) : fCanvas(bm) {}
     15 protected:
     16 	virtual bool onIRect(const SkIRect& r)
     17 	{
     18 		SkRect	rr;
     19 
     20 		rr.set(SkIntToScalar(r.fLeft), SkIntToScalar(r.fTop),
     21 				SkIntToScalar(r.fRight), SkIntToScalar(r.fBottom));
     22 
     23 		SkPaint	p;
     24 
     25 		p.setStyle(SkPaint::kStroke_Style);
     26 		p.setColor(SK_ColorYELLOW);
     27 
     28 #if 0
     29 		rr.inset(SK_ScalarHalf, SK_ScalarHalf);
     30 #else
     31 		rr.inset(-SK_ScalarHalf, -SK_ScalarHalf);
     32 #endif
     33 
     34 		fCanvas.drawRect(rr, p);
     35 		return true;
     36 	}
     37 private:
     38 	SkCanvas	fCanvas;
     39 };
     40 
     41 SkWindow::SkWindow() : fFocusView(NULL)
     42 {
     43 	fClick = NULL;
     44 	fWaitingOnInval = false;
     45 
     46 #ifdef SK_BUILD_FOR_WINCE
     47 	fConfig = SkBitmap::kRGB_565_Config;
     48 #else
     49 	fConfig = SkBitmap::kARGB_8888_Config;
     50 #endif
     51 }
     52 
     53 SkWindow::~SkWindow()
     54 {
     55 	delete fClick;
     56 
     57 	fMenus.deleteAll();
     58 }
     59 
     60 void SkWindow::setConfig(SkBitmap::Config config)
     61 {
     62 	this->resize(fBitmap.width(), fBitmap.height(), config);
     63 }
     64 
     65 void SkWindow::resize(int width, int height, SkBitmap::Config config)
     66 {
     67 	if (config == SkBitmap::kNo_Config)
     68 		config = fConfig;
     69 
     70 	if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig)
     71 	{
     72 		fConfig = config;
     73 		fBitmap.setConfig(config, width, height);
     74 		fBitmap.allocPixels();
     75 
     76 		this->setSize(SkIntToScalar(width), SkIntToScalar(height));
     77 		this->inval(NULL);
     78 	}
     79 }
     80 
     81 void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
     82 {
     83 	fBitmap.eraseARGB(a, r, g, b);
     84 }
     85 
     86 void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b)
     87 {
     88 	fBitmap.eraseRGB(r, g, b);
     89 }
     90 
     91 bool SkWindow::handleInval(const SkRect& r)
     92 {
     93 	SkIRect	ir;
     94 
     95 	r.round(&ir);
     96 	fDirtyRgn.op(ir, SkRegion::kUnion_Op);
     97 
     98 #ifdef SK_BUILD_FOR_WIN32xxxx
     99 	if (!fWaitingOnInval)
    100 	{
    101 		fWaitingOnInval = true;
    102 		(new SkEvent(SK_EventDelayInval))->post(this->getSinkID(), 10);
    103 	}
    104 #else
    105 	this->onHandleInval(ir);
    106 #endif
    107 	return true;
    108 }
    109 
    110 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
    111 	#include <windows.h>
    112 	#include <gx.h>
    113 	extern GXDisplayProperties gDisplayProps;
    114 #endif
    115 
    116 #ifdef SK_SIMULATE_FAILED_MALLOC
    117 extern bool gEnableControlledThrow;
    118 #endif
    119 
    120 bool SkWindow::update(SkIRect* updateArea)
    121 {
    122 	if (!fDirtyRgn.isEmpty())
    123 	{
    124 		SkBitmap bm = this->getBitmap();
    125 
    126 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
    127 		char* buffer = (char*)GXBeginDraw();
    128 		SkASSERT(buffer);
    129 
    130 		RECT	rect;
    131 		GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
    132 		buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;
    133 
    134 		bm.setPixels(buffer);
    135 #endif
    136 
    137 		SkCanvas	canvas(bm);
    138 
    139 		canvas.clipRegion(fDirtyRgn);
    140 		if (updateArea)
    141 			*updateArea = fDirtyRgn.getBounds();
    142 
    143 		// empty this now, so we can correctly record any inval calls that
    144 		// might be made during the draw call.
    145 		fDirtyRgn.setEmpty();
    146 
    147 #ifdef TEST_BOUNDER
    148 		test_bounder	b(bm);
    149 		canvas.setBounder(&b);
    150 #endif
    151 #ifdef SK_SIMULATE_FAILED_MALLOC
    152 		gEnableControlledThrow = true;
    153 #endif
    154 #ifdef SK_BUILD_FOR_WIN32
    155 		try {
    156 			this->draw(&canvas);
    157 		}
    158 		catch (...) {
    159 		}
    160 #else
    161 		this->draw(&canvas);
    162 #endif
    163 #ifdef SK_SIMULATE_FAILED_MALLOC
    164 		gEnableControlledThrow = false;
    165 #endif
    166 #ifdef TEST_BOUNDER
    167 		canvas.setBounder(NULL);
    168 #endif
    169 
    170 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
    171 		GXEndDraw();
    172 #endif
    173 
    174 		return true;
    175 	}
    176 	return false;
    177 }
    178 
    179 bool SkWindow::handleChar(SkUnichar uni)
    180 {
    181 	if (this->onHandleChar(uni))
    182 		return true;
    183 
    184 	SkView* focus = this->getFocusView();
    185 	if (focus == NULL)
    186 		focus = this;
    187 
    188 	SkEvent evt(SK_EventType_Unichar);
    189 	evt.setFast32(uni);
    190 	return focus->doEvent(evt);
    191 }
    192 
    193 bool SkWindow::handleKey(SkKey key)
    194 {
    195 	if (key == kNONE_SkKey)
    196 		return false;
    197 
    198 	if (this->onHandleKey(key))
    199 		return true;
    200 
    201 	// send an event to the focus-view
    202 	{
    203 		SkView* focus = this->getFocusView();
    204 		if (focus == NULL)
    205 			focus = this;
    206 
    207 		SkEvent evt(SK_EventType_Key);
    208 		evt.setFast32(key);
    209 		if (focus->doEvent(evt))
    210 			return true;
    211 	}
    212 
    213 	if (key == kUp_SkKey || key == kDown_SkKey)
    214 	{
    215 		if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
    216 			this->onSetFocusView(NULL);
    217 		return true;
    218 	}
    219 	return false;
    220 }
    221 
    222 bool SkWindow::handleKeyUp(SkKey key)
    223 {
    224     if (key == kNONE_SkKey)
    225         return false;
    226 
    227     if (this->onHandleKeyUp(key))
    228         return true;
    229 
    230     //send an event to the focus-view
    231     {
    232         SkView* focus = this->getFocusView();
    233         if (focus == NULL)
    234             focus = this;
    235 
    236         //should this one be the same?
    237         SkEvent evt(SK_EventType_KeyUp);
    238         evt.setFast32(key);
    239         if (focus->doEvent(evt))
    240             return true;
    241     }
    242     return false;
    243 }
    244 
    245 void SkWindow::addMenu(SkOSMenu* menu)
    246 {
    247 	*fMenus.append() = menu;
    248 	this->onAddMenu(menu);
    249 }
    250 
    251 void SkWindow::setTitle(const char title[]) {
    252     if (NULL == title) {
    253         title = "";
    254     }
    255     fTitle.set(title);
    256     this->onSetTitle(title);
    257 }
    258 
    259 bool SkWindow::handleMenu(uint32_t cmd)
    260 {
    261 	for (int i = 0; i < fMenus.count(); i++)
    262 	{
    263 		SkEvent* evt = fMenus[i]->createEvent(cmd);
    264 		if (evt)
    265 		{
    266 			evt->post(this->getSinkID());
    267 			return true;
    268 		}
    269 	}
    270 	return false;
    271 }
    272 
    273 //////////////////////////////////////////////////////////////////////
    274 
    275 bool SkWindow::onEvent(const SkEvent& evt)
    276 {
    277 	if (evt.isType(SK_EventDelayInval))
    278 	{
    279 		SkRegion::Iterator	iter(fDirtyRgn);
    280 
    281 		for (; !iter.done(); iter.next())
    282 			this->onHandleInval(iter.rect());
    283 		fWaitingOnInval = false;
    284 		return true;
    285 	}
    286 	return this->INHERITED::onEvent(evt);
    287 }
    288 
    289 bool SkWindow::onGetFocusView(SkView** focus) const
    290 {
    291 	if (focus)
    292 		*focus = fFocusView;
    293 	return true;
    294 }
    295 
    296 bool SkWindow::onSetFocusView(SkView* focus)
    297 {
    298 	if (fFocusView != focus)
    299 	{
    300 		if (fFocusView)
    301 			fFocusView->onFocusChange(false);
    302 		fFocusView = focus;
    303 		if (focus)
    304 			focus->onFocusChange(true);
    305 	}
    306 	return true;
    307 }
    308 
    309 //////////////////////////////////////////////////////////////////////
    310 
    311 void SkWindow::onHandleInval(const SkIRect&)
    312 {
    313 }
    314 
    315 bool SkWindow::onHandleChar(SkUnichar)
    316 {
    317 	return false;
    318 }
    319 
    320 bool SkWindow::onHandleKey(SkKey key)
    321 {
    322 	return false;
    323 }
    324 
    325 bool SkWindow::onHandleKeyUp(SkKey key)
    326 {
    327     return false;
    328 }
    329 
    330 bool SkWindow::handleClick(int x, int y, Click::State state)
    331 {
    332 	bool handled = false;
    333 
    334 	switch (state) {
    335 	case Click::kDown_State:
    336 		if (fClick)
    337 			delete fClick;
    338 		fClick = this->findClickHandler(SkIntToScalar(x), SkIntToScalar(y));
    339 		if (fClick)
    340 		{
    341 			SkView::DoClickDown(fClick, x, y);
    342 			handled = true;
    343 		}
    344 		break;
    345 	case Click::kMoved_State:
    346 		if (fClick)
    347 		{
    348 			SkView::DoClickMoved(fClick, x, y);
    349 			handled = true;
    350 		}
    351 		break;
    352 	case Click::kUp_State:
    353 		if (fClick)
    354 		{
    355 			SkView::DoClickUp(fClick, x, y);
    356 			delete fClick;
    357 			fClick = NULL;
    358 			handled = true;
    359 		}
    360 		break;
    361 	}
    362 	return handled;
    363 }
    364 
    365