Android: Made Fl_Rect virtual. Maybe a bad idea?
Also, added rectangular clipping which works. Expanding now to a more complex clipping scheme to make multiple windows work. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12739 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
0b1fd7ee37
commit
88ce4aec17
@ -60,14 +60,16 @@ public:
|
||||
Fl_Rect (const Fl_Widget* const widget)
|
||||
: x_(widget->x()), y_(widget->y()), w_(widget->w()), h_(widget->h()) {}
|
||||
|
||||
virtual ~Fl_Rect() { }
|
||||
|
||||
/** Return 1 if the rectangle is empty, width or height are 0 */
|
||||
int is_empty() { return (w_<=0)||(h_<=0); }
|
||||
|
||||
/** Set the position and size */
|
||||
void set(int x, int y, int w, int h) { x_=x; y_=y; w_=w; h_=h; }
|
||||
virtual void set(int x, int y, int w, int h) { x_=x; y_=y; w_=w; h_=h; }
|
||||
|
||||
/** Clone another rectangle */
|
||||
void set(Fl_Rect *r) { x_=r->x_; y_=r->y_; w_=r->w_; h_=r->h_; }
|
||||
virtual void set(Fl_Rect *r) { x_=r->x_; y_=r->y_; w_=r->w_; h_=r->h_; }
|
||||
|
||||
/** return 0 if the rectangles are different, or 1 if they are the same */
|
||||
int equals(int x, int y, int w, int h) { return ( (x_==x) && (y_==y) && (w_==w) && (h_==h) ); }
|
||||
|
@ -21,35 +21,42 @@
|
||||
#include <FL/Enumerations.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
Fl_Window *win;
|
||||
|
||||
Fl_Window *win, *win2, *win3;
|
||||
Fl_Button *btn;
|
||||
|
||||
|
||||
class MyButton : public Fl_Button
|
||||
{
|
||||
public:
|
||||
MyButton(int x, int y, int w, int h, const char *l) : Fl_Button(x, y, w, h, l) { }
|
||||
void draw() {
|
||||
fl_push_clip(x(), y(), w()/2, h()/2);
|
||||
fl_push_clip(x(), y(), w()*2/3, h()*2/3);
|
||||
Fl_Button::draw();
|
||||
fl_pop_clip();
|
||||
}
|
||||
};
|
||||
|
||||
int h(void*, void*)
|
||||
{
|
||||
Fl_Android_Application::log_w("App global event %p", Fl::event());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Fl::add_system_handler(h, 0);
|
||||
win = new Fl_Window(10, 10, 600, 400, "Hallo");
|
||||
btn = new MyButton(190, 200, 280, 35, "Hello, Android!");
|
||||
win2 = new Fl_Window(100, 50, 150, 200, "on bottom");
|
||||
win2->color(FL_BLUE);
|
||||
win2->end();
|
||||
win2->show();
|
||||
|
||||
win = new Fl_Window(50, 150, 500, 400, "Hallo");
|
||||
btn = new MyButton((win->w()-280)/2, 200, 280, 35, "Hello, Android!");
|
||||
btn->color(FL_LIGHT2);
|
||||
win->show(argc, argv);
|
||||
|
||||
/*
|
||||
win3 = new Fl_Window(300, 50, 150, 200, "on top");
|
||||
win3->color(FL_RED);
|
||||
win3->end();
|
||||
win3->show();
|
||||
*/
|
||||
Fl::run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,9 @@
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOG_TAG "FLTK"
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGV(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
|
||||
static const char *LOG_TAG = "FLTK";
|
||||
|
||||
|
||||
// The ANativeActivity object instance that this app is running in.
|
||||
ANativeActivity *Fl_Android_Application::pActivity = 0L;
|
||||
@ -175,7 +173,7 @@ int8_t Fl_Android_Application::read_cmd()
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
LOGE("No data on command pipe!");
|
||||
log_e("No data on command pipe!");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -187,7 +185,7 @@ void Fl_Android_Application::print_cur_config()
|
||||
AConfiguration_getLanguage(pConfig, lang);
|
||||
AConfiguration_getCountry(pConfig, country);
|
||||
|
||||
LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
|
||||
log_v("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
|
||||
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
|
||||
"modetype=%d modenight=%d",
|
||||
AConfiguration_getMcc(pConfig),
|
||||
@ -216,14 +214,14 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case APP_CMD_INPUT_CHANGED:
|
||||
LOGV("APP_CMD_INPUT_CHANGED\n");
|
||||
log_v("APP_CMD_INPUT_CHANGED\n");
|
||||
pthread_mutex_lock(&pMutex);
|
||||
if (pInputQueue != NULL) {
|
||||
AInputQueue_detachLooper(pInputQueue);
|
||||
}
|
||||
pInputQueue = pPendingInputQueue;
|
||||
if (pInputQueue != NULL) {
|
||||
LOGV("Attaching input queue to looper");
|
||||
log_v("Attaching input queue to looper");
|
||||
AInputQueue_attachLooper(pInputQueue,
|
||||
pMsgPipeLooper, LOOPER_ID_INPUT, NULL,
|
||||
&pInputPollSource);
|
||||
@ -233,7 +231,7 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd)
|
||||
break;
|
||||
|
||||
case APP_CMD_INIT_WINDOW:
|
||||
LOGV("APP_CMD_INIT_WINDOW\n");
|
||||
log_v("APP_CMD_INIT_WINDOW\n");
|
||||
// tell the main thread that we received the window handle
|
||||
pthread_mutex_lock(&pMutex);
|
||||
pNativeWindow = pPendingWindow;
|
||||
@ -250,7 +248,7 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd)
|
||||
break;
|
||||
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGV("APP_CMD_TERM_WINDOW\n");
|
||||
log_v("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_cond_broadcast(&pCond);
|
||||
break;
|
||||
|
||||
@ -258,7 +256,7 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd)
|
||||
case APP_CMD_START:
|
||||
case APP_CMD_PAUSE:
|
||||
case APP_CMD_STOP:
|
||||
LOGV("activityState=%d\n", cmd);
|
||||
log_v("activityState=%d\n", cmd);
|
||||
pthread_mutex_lock(&pMutex);
|
||||
pActivityState = cmd;
|
||||
pthread_cond_broadcast(&pCond);
|
||||
@ -266,14 +264,14 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd)
|
||||
break;
|
||||
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
LOGV("APP_CMD_CONFIG_CHANGED\n");
|
||||
log_v("APP_CMD_CONFIG_CHANGED\n");
|
||||
AConfiguration_fromAssetManager(pConfig,
|
||||
pActivity->assetManager);
|
||||
print_cur_config();
|
||||
break;
|
||||
|
||||
case APP_CMD_DESTROY:
|
||||
LOGV("APP_CMD_DESTROY\n");
|
||||
log_v("APP_CMD_DESTROY\n");
|
||||
pDestroyRequested = 1;
|
||||
// FIXME: see Fl::program_should_quit()
|
||||
break;
|
||||
@ -292,7 +290,7 @@ void Fl_Android_Application::post_exec_cmd(int8_t cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGV("APP_CMD_TERM_WINDOW\n");
|
||||
log_v("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_mutex_lock(&pMutex);
|
||||
pNativeWindow = NULL;
|
||||
pthread_cond_broadcast(&pCond);
|
||||
@ -300,7 +298,7 @@ void Fl_Android_Application::post_exec_cmd(int8_t cmd)
|
||||
break;
|
||||
|
||||
case APP_CMD_SAVE_STATE:
|
||||
LOGV("APP_CMD_SAVE_STATE\n");
|
||||
log_v("APP_CMD_SAVE_STATE\n");
|
||||
pthread_mutex_lock(&pMutex);
|
||||
pStateSaved = 1;
|
||||
pthread_cond_broadcast(&pCond);
|
||||
@ -334,7 +332,6 @@ void Fl_Android_Application::process_input(struct android_poll_source* source)
|
||||
{
|
||||
AInputEvent* event = NULL;
|
||||
while (AInputQueue_getEvent(pInputQueue, &event) >= 0) {
|
||||
//LOGV("New input event: type=%d\n", AInputEvent_getType(event));
|
||||
if (AInputQueue_preDispatchEvent(pInputQueue, event)) {
|
||||
continue;
|
||||
}
|
||||
@ -502,7 +499,7 @@ bool Fl_Android_Application::screen_is_locked()
|
||||
void Fl_Android_Activity::write_cmd(int8_t cmd)
|
||||
{
|
||||
if (write(pMsgWritePipe, &cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
|
||||
log_e("Failure writing android_app cmd: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,7 +753,7 @@ void Fl_Android_Activity::create(ANativeActivity* activity, void* savedState,
|
||||
|
||||
int msgpipe[2];
|
||||
if (pipe(msgpipe)) {
|
||||
LOGE("could not create pipe: %s", strerror(errno));
|
||||
log_e("could not create pipe: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
pMsgReadPipe = msgpipe[0];
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
class Fl_Android_Window_Driver;
|
||||
|
||||
|
||||
/**
|
||||
* The Fl_Rect_Region is based on Fl_Rect with additional functionality for clipping.
|
||||
*/
|
||||
@ -52,6 +55,8 @@ public:
|
||||
*/
|
||||
Fl_Rect_Region(int x, int y, int w, int h) : Fl_Rect(x, y, w, h) {}
|
||||
int intersect_with(Fl_Rect_Region *r);
|
||||
virtual void print();
|
||||
|
||||
static int min(int a, int b) { return (a<b) ? a : b; }
|
||||
static int max(int a, int b) { return (a>b) ? a : b; }
|
||||
};
|
||||
@ -79,10 +84,16 @@ public:
|
||||
Fl_Complex_Region() : Fl_Rect_Region(), pSubregion(0L), pNext(0L) { }
|
||||
Fl_Complex_Region(int x, int y, int w, int h) : Fl_Rect_Region(x, y, w, h), pSubregion(0L), pNext(0L) { }
|
||||
~Fl_Complex_Region();
|
||||
void set(Fl_Rect *rect);
|
||||
virtual void set(int x, int y, int w, int h);
|
||||
virtual void set(Fl_Rect *rect);
|
||||
void subtract(Fl_Rect*);
|
||||
void intersect(Fl_Rect*);
|
||||
void clone(Fl_Complex_Region*);
|
||||
char is_simple() { return pSubregion==0; }
|
||||
char is_complex() { return pSubregion!=0; }
|
||||
void print();
|
||||
protected:
|
||||
void print_data(int indent);
|
||||
Fl_Complex_Region *pSubregion;
|
||||
Fl_Complex_Region *pNext;
|
||||
};
|
||||
@ -112,7 +123,8 @@ protected:
|
||||
POINT *p;
|
||||
#endif
|
||||
public:
|
||||
Fl_Android_Graphics_Driver() : pWindowRegion(0L) {}
|
||||
Fl_Android_Graphics_Driver();
|
||||
~Fl_Android_Graphics_Driver();
|
||||
#if 0
|
||||
Fl_GDI_Graphics_Driver() {mask_bitmap_ = NULL; gc_ = NULL; p_size = 0; p = NULL; depth = -1; origins = NULL;}
|
||||
virtual ~Fl_GDI_Graphics_Driver() { if (p) free(p); delete[] origins;}
|
||||
@ -190,7 +202,6 @@ protected:
|
||||
void restore_clip();
|
||||
void clip_region(Fl_Region r);
|
||||
Fl_Region clip_region();
|
||||
Fl_Rect_Region *pWindowRegion;
|
||||
#if 0
|
||||
virtual Fl_Region scale_clip(float f);
|
||||
// --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
|
||||
@ -227,6 +238,16 @@ protected:
|
||||
|
||||
#endif
|
||||
|
||||
int render_letter(int xx, int yy, uint32_t c);
|
||||
void make_current(Fl_Window*);
|
||||
|
||||
int32_t pStride;
|
||||
uint16_t *pBits;
|
||||
|
||||
// Fl_Rect_Region pScreenRegion;
|
||||
Fl_Rect_Region *pWindowRegion;
|
||||
Fl_Complex_Region *pDesktopRegion;
|
||||
Fl_Complex_Region *pClippingRegion;
|
||||
};
|
||||
|
||||
|
||||
|
@ -36,6 +36,56 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
|
||||
}
|
||||
|
||||
|
||||
Fl_Android_Graphics_Driver::Fl_Android_Graphics_Driver() :
|
||||
pStride(0), pBits(0),
|
||||
pWindowRegion(new Fl_Rect_Region()),
|
||||
pDesktopRegion(new Fl_Complex_Region()),
|
||||
pClippingRegion(new Fl_Complex_Region())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Fl_Android_Graphics_Driver::~Fl_Android_Graphics_Driver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
|
||||
{
|
||||
Fl_Android_Application::log_i("------------ make current \"%s\"", win->label());
|
||||
|
||||
// The Stride is the offset between lines in the graphics buffer
|
||||
pStride = Fl_Android_Application::graphics_buffer().stride;
|
||||
// Bits is the memory address of the top left corner of the window
|
||||
pBits = ((uint16_t*)(Fl_Android_Application::graphics_buffer().bits))
|
||||
+ win->x_root() + pStride * win->y_root();
|
||||
|
||||
// TODO: set the clipping area
|
||||
// set the clipping area to the physical screen size in window coordinates
|
||||
pWindowRegion->set(-win->x(), -win->y(), 600, 800);
|
||||
Fl_Rect_Region wr(0, 0, win->w(), win->h());
|
||||
pWindowRegion->intersect_with(&wr);
|
||||
pWindowRegion->print();
|
||||
|
||||
pDesktopRegion->set(pWindowRegion);
|
||||
|
||||
// remove all window rectangles that are positioned on top of this window
|
||||
// TODO: this region is expensive to calculate. Cache it for each window and recalculate when windows move, show, hide, or change order
|
||||
Fl_Window *wTop = Fl::first_window();
|
||||
while (wTop) {
|
||||
if (wTop==win) break;
|
||||
Fl_Rect r(wTop->x(), wTop->y(), wTop->w(), wTop->h());
|
||||
pDesktopRegion->subtract(&r);
|
||||
wTop = Fl::next_window(wTop);
|
||||
}
|
||||
|
||||
// TODO: we can optimize this by using some "copy on write" system
|
||||
pClippingRegion->clone(pDesktopRegion);
|
||||
pClippingRegion->print();
|
||||
Fl_Android_Application::log_i("------------ make current done");
|
||||
}
|
||||
|
||||
|
||||
static uint16_t make565(int red, int green, int blue)
|
||||
{
|
||||
return (uint16_t)( ((red << 8) & 0xf800) |
|
||||
@ -53,15 +103,14 @@ static uint16_t make565(Fl_Color crgba)
|
||||
((crgba >>11) & 0x001f) );
|
||||
}
|
||||
|
||||
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) {
|
||||
if (pWindowRegion) {
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with(pWindowRegion)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
} else {
|
||||
rectf_unclipped(x, y, w, h);
|
||||
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h)
|
||||
{
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with((Fl_Rect_Region*)pClippingRegion)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
// TODO: create a complex region by intersecting r with the pClippingRegion
|
||||
// TODO: walk the region and draw all rectangles
|
||||
|
||||
/*
|
||||
* rectf(x, y, w, h) {
|
||||
@ -95,8 +144,8 @@ void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, floa
|
||||
// TODo: clip the rectangle to all parts of the current clipping region
|
||||
|
||||
uint16_t cc = make565(color());
|
||||
uint32_t ss = Fl_Android_Application::graphics_buffer().stride;
|
||||
uint16_t *bits = (uint16_t*)Fl_Android_Application::graphics_buffer().bits;
|
||||
int32_t ss = pStride;
|
||||
uint16_t *bits = pBits;
|
||||
uint32_t xx = (uint32_t)x;
|
||||
uint32_t yy = (uint32_t)y;
|
||||
uint32_t ww = (uint32_t)w;
|
||||
@ -119,8 +168,8 @@ void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1)
|
||||
w = x-x1;
|
||||
x = x1;
|
||||
}
|
||||
uint32_t ss = Fl_Android_Application::graphics_buffer().stride;
|
||||
uint16_t *bits = (uint16_t*)Fl_Android_Application::graphics_buffer().bits;
|
||||
int32_t ss = pStride;
|
||||
uint16_t *bits = pBits;
|
||||
uint32_t xx = (uint32_t)x;
|
||||
uint32_t yy = (uint32_t)y;
|
||||
uint32_t ww = (uint32_t)w;
|
||||
@ -140,8 +189,8 @@ void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1)
|
||||
h = y-y1;
|
||||
y = y1;
|
||||
}
|
||||
uint32_t ss = Fl_Android_Application::graphics_buffer().stride;
|
||||
uint16_t *bits = (uint16_t*)Fl_Android_Application::graphics_buffer().bits;
|
||||
int32_t ss = pStride;
|
||||
uint16_t *bits = pBits;
|
||||
uint32_t xx = (uint32_t)x;
|
||||
uint32_t yy = (uint32_t)y;
|
||||
uint32_t hh = (uint32_t)h;
|
||||
@ -160,7 +209,7 @@ void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1)
|
||||
|
||||
unsigned char ttf_buffer[1<<25];
|
||||
|
||||
static int render_letter(int xx, int yy, uint32_t c)
|
||||
int Fl_Android_Graphics_Driver::render_letter(int xx, int yy, uint32_t c)
|
||||
{
|
||||
static bool once = 0;
|
||||
static stbtt_fontinfo font;
|
||||
@ -210,8 +259,8 @@ if (once==0) {
|
||||
// rrrr.rggg.gggb.bbbb
|
||||
xx += dx; yy += dy;
|
||||
uint16_t cc = make565(fl_color()), cc12 = (cc&0xf7de)>>1, cc14 = (cc12&0xf7de)>>1, cc34 = cc12+cc14;
|
||||
uint32_t ss = Fl_Android_Application::graphics_buffer().stride;
|
||||
uint16_t *bits = (uint16_t*)Fl_Android_Application::graphics_buffer().bits;
|
||||
int32_t ss = pStride;
|
||||
uint16_t *bits = pBits;
|
||||
uint32_t ww = w;
|
||||
uint32_t hh = h;
|
||||
unsigned char *s = bitmap;
|
||||
@ -512,6 +561,7 @@ void Fl_GDI_Graphics_Driver::set_current_() {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
@ -51,6 +51,13 @@ int Fl_Rect_Region::intersect_with(Fl_Rect_Region *a)
|
||||
}
|
||||
|
||||
|
||||
void Fl_Rect_Region::print()
|
||||
{
|
||||
Fl_Android_Application::log_i("-------- begin rect");
|
||||
Fl_Android_Application::log_i("Rect %d %d %d %d", x(), y(), w(), h());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Fl_Complex_Region::~Fl_Complex_Region()
|
||||
{
|
||||
@ -59,6 +66,17 @@ Fl_Complex_Region::~Fl_Complex_Region()
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::set(int x, int y, int w, int h)
|
||||
{
|
||||
// TODO: refactor the next four lines out, repeating
|
||||
delete pSubregion;
|
||||
pSubregion = 0L;
|
||||
delete pNext;
|
||||
pNext = 0L;
|
||||
Fl_Rect_Region::set(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::set(Fl_Rect *rect)
|
||||
{
|
||||
delete pSubregion;
|
||||
@ -68,6 +86,92 @@ void Fl_Complex_Region::set(Fl_Rect *rect)
|
||||
Fl_Rect_Region::set(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a rectangle from this region.
|
||||
*
|
||||
* This operation may create multiple new subregions, but possibly also remove
|
||||
* subregions.
|
||||
*
|
||||
* @param x, y, w, h rectangular region that will be subtracted
|
||||
*/
|
||||
void Fl_Complex_Region::subtract(Fl_Rect *r)
|
||||
{
|
||||
Fl_Android_Application::log_i("------------ subtract");
|
||||
this->print();
|
||||
Fl_Android_Application::log_i("--------");
|
||||
Fl_Android_Application::log_i("Rect %d %d %d %d", r->x(), r->y(), r->w(), r->h());
|
||||
// ----
|
||||
this->print();
|
||||
Fl_Android_Application::log_i("------------ subtract done");
|
||||
// FIXME: implement
|
||||
int x = 3;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::intersect(Fl_Rect*)
|
||||
{
|
||||
// FIXME: implement
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::clone(Fl_Complex_Region *r)
|
||||
{
|
||||
// FIXME: implement
|
||||
// make this region simple and copy the bounding box
|
||||
set(r);
|
||||
if (r->pSubregion) {
|
||||
pSubregion = new Fl_Complex_Region();
|
||||
pSubregion->clone(r->pSubregion);
|
||||
}
|
||||
if (r->pNext) {
|
||||
pNext = new Fl_Complex_Region();
|
||||
pNext->clone(r->pNext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::print_data(int indent)
|
||||
{
|
||||
static const char *space = " ";
|
||||
if (pSubregion) {
|
||||
Fl_Android_Application::log_i("%sBBox %d %d %d %d", space+16-indent, x(), y(), w(), h());
|
||||
pSubregion->print_data(indent+1);
|
||||
} else {
|
||||
Fl_Android_Application::log_i("%sRect %d %d %d %d", space+16-indent, x(), y(), w(), h());
|
||||
}
|
||||
if (pNext) {
|
||||
pNext->print_data(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::print()
|
||||
{
|
||||
Fl_Android_Application::log_i("-------- begin region");
|
||||
print_data(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::restore_clip()
|
||||
{
|
||||
fl_clip_state_number++;
|
||||
|
||||
// TODO: we can optimize this by using some "copy on write" system
|
||||
Fl_Android_Application::log_i("------------ restore_clip");
|
||||
pDesktopRegion->print();
|
||||
//pClippingRegion->set(pWindowRegion);
|
||||
pClippingRegion->clone(pDesktopRegion);
|
||||
|
||||
Fl_Region b = rstack[rstackptr];
|
||||
if (b) {
|
||||
pClippingRegion->intersect_with(b);
|
||||
pClippingRegion->print();
|
||||
}
|
||||
Fl_Android_Application::log_i("------------ restore_clip done");
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::clip_region(Fl_Region r)
|
||||
{
|
||||
@ -78,25 +182,12 @@ void Fl_Android_Graphics_Driver::clip_region(Fl_Region r)
|
||||
restore_clip();
|
||||
}
|
||||
|
||||
|
||||
Fl_Region Fl_Android_Graphics_Driver::clip_region()
|
||||
{
|
||||
return rstack[rstackptr];
|
||||
}
|
||||
|
||||
void Fl_Android_Graphics_Driver::restore_clip()
|
||||
{
|
||||
fl_clip_state_number++;
|
||||
Fl_Window *win = Fl_Window::current();
|
||||
Fl_Rect_Region a(0, 0, win->w(), win->h());
|
||||
|
||||
Fl_Region b = rstack[rstackptr];
|
||||
if (b) {
|
||||
// FIXME: scaling!
|
||||
a.intersect_with(b);
|
||||
}
|
||||
pWindowRegion = b;
|
||||
// FIXME: intersect with complex window region
|
||||
}
|
||||
|
||||
void Fl_Android_Graphics_Driver::push_clip(int x, int y, int w, int h)
|
||||
{
|
||||
@ -115,6 +206,7 @@ void Fl_Android_Graphics_Driver::push_clip(int x, int y, int w, int h)
|
||||
restore_clip();
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::push_no_clip()
|
||||
{
|
||||
if (rstackptr < region_stack_max) rstack[++rstackptr] = 0;
|
||||
@ -122,6 +214,7 @@ void Fl_Android_Graphics_Driver::push_no_clip()
|
||||
restore_clip();
|
||||
}
|
||||
|
||||
|
||||
void Fl_Android_Graphics_Driver::pop_clip()
|
||||
{
|
||||
if (rstackptr > 0) {
|
||||
@ -237,42 +330,6 @@ int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
- Pushes an empty clip region onto the stack so nothing will be clipped.
|
||||
virtual void push_no_clip() {}
|
||||
- Intersects the current clip region with a rectangle and pushes this new region onto the stack.
|
||||
virtual void push_clip(int x, int y, int w, int h) {}
|
||||
- Restores the previous clip region.
|
||||
virtual void pop_clip() {}
|
||||
- Does the rectangle intersect the current clip region? 0=no, 1=all, 2=partially
|
||||
virtual int not_clipped(int x, int y, int w, int h) {return 1;}
|
||||
- Intersects the rectangle with the current clip region and returns the bounding box of the result.
|
||||
Returns 1 if rect changed, W and H are 0 if there is no rect
|
||||
virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {return 0;}
|
||||
- Undoes any clobbering of clip done by your program
|
||||
virtual void restore_clip();
|
||||
|
||||
virtual Fl_Region clip_region(); // has default implementation
|
||||
virtual void clip_region(Fl_Region r); // has default implementation
|
||||
|
||||
fl_push_clip(x,y,w,h) -> driver
|
||||
fl_pop_clip() -> driver
|
||||
fl_push_no_clip() -> driver
|
||||
fl_not_clipped(int x, int y, int w, int h) -> driver
|
||||
fl_clip_box(int x , int y, int w, int h, int& X, int& Y, int& W, int& H) -> driver
|
||||
fl_restore_clip() -> driver
|
||||
|
||||
fl_clip_region(Fl_Region r) -> driver
|
||||
fl_clip_region() -> driver
|
||||
|
||||
virtual Fl_Region scale_clip(float f) { return 0; }
|
||||
void unscale_clip(Fl_Region r);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
@ -116,22 +116,38 @@ int Fl_Android_Screen_Driver::handle_keyboard_event(AInputEvent *event)
|
||||
|
||||
int Fl_Android_Screen_Driver::handle_mouse_event(AInputEvent *event)
|
||||
{
|
||||
Fl::e_x = Fl::e_x_root = (int)(AMotionEvent_getX(event, 0) * 600 /
|
||||
ANativeWindow_getWidth(Fl_Android_Application::native_window()));
|
||||
Fl::e_y = Fl::e_y_root = (int)(AMotionEvent_getY(event, 0) * 800 /
|
||||
ANativeWindow_getHeight(Fl_Android_Application::native_window()));
|
||||
int ex = Fl::e_x_root = (int)(AMotionEvent_getX(event, 0) * 600 /
|
||||
ANativeWindow_getWidth(Fl_Android_Application::native_window()));
|
||||
int ey = Fl::e_y_root = (int)(AMotionEvent_getY(event, 0) * 800 /
|
||||
ANativeWindow_getHeight(Fl_Android_Application::native_window()));
|
||||
|
||||
// FIXME: find the window in which the event happened
|
||||
Fl_Window *win = Fl::first_window();
|
||||
while (win) {
|
||||
if (ex>=win->x() && ex<win->x()+win->w() && ey>=win->y() && ey<win->y()+win->h())
|
||||
break;
|
||||
win = Fl::next_window(win);
|
||||
}
|
||||
|
||||
if (win) {
|
||||
Fl::e_x = ex-win->x();
|
||||
Fl::e_y = ey-win->y();
|
||||
} else {
|
||||
Fl::e_x = ex;
|
||||
Fl::e_y = ey;
|
||||
}
|
||||
|
||||
Fl::e_state = FL_BUTTON1;
|
||||
Fl::e_keysym = FL_Button + 1;
|
||||
if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN) {
|
||||
Fl::e_is_click = 1;
|
||||
Fl::handle(FL_PUSH, Fl::first_window());
|
||||
Fl_Android_Application::log_i("Mouse push %d at %d, %d", Fl::event_button(), Fl::event_x(),
|
||||
Fl::event_y());
|
||||
Fl::handle(FL_PUSH, win);
|
||||
Fl_Android_Application::log_i("Mouse push %d at %d, %d", Fl::event_button(), Fl::event_x(), Fl::event_y());
|
||||
} else if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_MOVE) {
|
||||
Fl::handle(FL_DRAG, Fl::first_window());
|
||||
Fl::handle(FL_DRAG, win);
|
||||
} else if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_UP) {
|
||||
Fl::e_state = 0;
|
||||
Fl::handle(FL_RELEASE, Fl::first_window());
|
||||
Fl::handle(FL_RELEASE, win);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -93,7 +93,14 @@ void Fl_Android_Window_Driver::expose_all()
|
||||
|
||||
void Fl_Android_Window_Driver::make_current()
|
||||
{
|
||||
// FXIME: that is quite a cludge:
|
||||
((Fl_Android_Screen_Driver*)Fl::screen_driver())->pScreenContentChanged = true;
|
||||
|
||||
Fl_Android_Graphics_Driver *gd = dynamic_cast<Fl_Android_Graphics_Driver*>(fl_graphics_driver);
|
||||
if (gd) {
|
||||
gd->make_current(pWindow);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user