From c998c6165508aa7541a4b05acd9068aa4cdf63e3 Mon Sep 17 00:00:00 2001 From: Nishi Date: Wed, 29 Apr 2026 03:41:00 +0900 Subject: [PATCH] mouse and stuff --- examples/basic/periodic.c | 11 ++ include/Mw/LowLevel/Haiku.h | 36 ++++++- src/backend/haiku.cc | 197 ++++++++++++++++++++++++++++++++++-- src/widget/menu.c | 2 +- 4 files changed, 231 insertions(+), 15 deletions(-) diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c index cc55882..7ecb1d9 100644 --- a/examples/basic/periodic.c +++ b/examples/basic/periodic.c @@ -151,6 +151,7 @@ int main() { int index; MwMenu m, m2; void* v; + MwRect rc; MwLibraryInit(); @@ -158,6 +159,16 @@ int main() { MwNtitle, "Milsko Periodic Table", NULL); + MwGetScreenSize(window, &rc); + if(rc.height < 800) { + MwVaApply(window, + MwNx, (rc.width - (rc.height - 64)) / 2, + MwNy, (rc.height - (rc.height - 64)) / 2, + MwNwidth, rc.height - 64, + MwNheight, rc.height - 64, + NULL); + } + px = MwLoadIcon(window, MwIconError); menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0); diff --git a/include/Mw/LowLevel/Haiku.h b/include/Mw/LowLevel/Haiku.h index a231d01..eeafb69 100644 --- a/include/Mw/LowLevel/Haiku.h +++ b/include/Mw/LowLevel/Haiku.h @@ -33,14 +33,21 @@ class MwView : public BView { public: MwLL handle; BLocker* locker; + uint32 buttons; MwView(MwLL handle, BRect rc, uint32 resizingMode, uint32 flags); ~MwView(); void MessageReceived(BMessage* message); void PostMessage(BMessage* message); + void PostMessage(uint32 command); + void Invalidate(); + void AttachedToWindow(); void Draw(BRect updateRect); + void MouseDown(BPoint point); + void MouseUp(BPoint point); + void MouseMoved(BPoint point, uint32 transit, const BMessage* message); void SetColor(MwLLColor color); }; @@ -51,9 +58,12 @@ class MwWindow : public BWindow { void MessageReceived(BMessage* message); }; + +typedef BBitmap MwBBitmap; #else typedef void MwApplication; typedef void MwView; +typedef void MwBBitmap; #endif typedef union _MwLLHaikuEvent MwLLHaikuEvent; @@ -63,11 +73,17 @@ enum BAPP_MW_WHAT { }; enum BVIEW_MW_WHAT { - BVIEW_MW_RESIZE = 0, + BVIEW_MW_DESTROY = 0, + BVIEW_MW_DETACH, + BVIEW_MW_RESIZE, BVIEW_MW_MOVE, + BVIEW_MW_SHOW, + BVIEW_MW_HIDE, BVIEW_MW_SET_COLOR, BVIEW_MW_POLYGON, - BVIEW_MW_BITMAP + BVIEW_MW_LINE, + BVIEW_MW_BITMAP, + BVIEW_MW_RENDER }; enum BWIN_MW_WHAT { @@ -75,11 +91,21 @@ enum BWIN_MW_WHAT { }; enum MwLLHAIKU_EVENT { - MwLLHAIKU_EVENT_DRAW = 0 + MwLLHAIKU_EVENT_DRAW = 0, + MwLLHAIKU_EVENT_MOUSEDOWN, + MwLLHAIKU_EVENT_MOUSEUP, + MwLLHAIKU_EVENT_MOUSEMOVED +}; + +struct _MwLLHaikuEventMouse { + int type; + MwPoint point; + int button; }; union _MwLLHaikuEvent { - int type; + int type; + struct _MwLLHaikuEventMouse mouse; }; struct _MwLLHaiku { @@ -105,7 +131,7 @@ struct _MwLLHaikuColor { struct _MwLLHaikuPixmap { struct _MwLLCommonPixmap common; - BBitmap* bitmap; + MwBBitmap* bitmap; }; MWDECL int MwLLHaikuCallInit(void); diff --git a/src/backend/haiku.cc b/src/backend/haiku.cc index d372669..1ad864d 100644 --- a/src/backend/haiku.cc +++ b/src/backend/haiku.cc @@ -49,8 +49,11 @@ MwView::MwView(MwLL handle, BRect frame, uint32 resizingMode, uint32 flags) : BV this->locker = new BLocker(); this->SetDrawingMode(B_OP_OVER); + this->SetLineMode(B_BUTT_CAP, B_BUTT_JOIN); this->SetViewColor(255, 0, 0); + + this->buttons = 0; } MwView::~MwView(){ @@ -59,13 +62,28 @@ MwView::~MwView(){ void MwView::MessageReceived(BMessage* message) { switch(message->what) { + case BVIEW_MW_DESTROY: + { + this->RemoveSelf(); + delete this; + break; + } + case BVIEW_MW_DETACH: + { + this->RemoveSelf(); + break; + } case BVIEW_MW_RESIZE: { int width, height; if(message->FindInt32("view-width", &width) != B_OK) break; if(message->FindInt32("view-height", &height) != B_OK) break; - this->ResizeTo(width, height); + if(this->handle->haiku.app == NULL){ + this->ResizeTo(width, height); + }else{ + this->Window()->ResizeTo(width, height); + } break; } case BVIEW_MW_MOVE: { @@ -74,7 +92,25 @@ void MwView::MessageReceived(BMessage* message) { if(message->FindInt32("view-x", &x) != B_OK) break; if(message->FindInt32("view-y", &y) != B_OK) break; - this->MoveTo(x, y); + if(this->handle->haiku.app == NULL){ + this->MoveTo(x, y); + }else{ + this->Window()->MoveTo(x, y); + } + break; + } + case BVIEW_MW_SHOW: + { + if(this->Window() == NULL){ + this->handle->haiku.parent->haiku.view->AddChild(this); + } + break; + } + case BVIEW_MW_HIDE: + { + if(this->Window() != NULL){ + this->RemoveSelf(); + } break; } case BVIEW_MW_SET_COLOR: @@ -94,15 +130,28 @@ void MwView::MessageReceived(BMessage* message) { { int i; BPoint p; - BPoint points[128]; + BPoint points[32]; - for(i = 0; message->FindPoint("view-point", i, &p) == B_OK; i++){ + for(i = 0; i < 32 && message->FindPoint("view-point", i, &p) == B_OK; i++){ points[i] = p; } this->FillPolygon(points, i); break; } + case BVIEW_MW_LINE: + { + int i; + BPoint p; + BPoint points[2]; + + for(i = 0; i < 2 && message->FindPoint("view-point", i, &p) == B_OK; i++){ + points[i] = p; + } + + this->StrokeLine(points[0], points[1]); + break; + } case BVIEW_MW_BITMAP: { BRect rc; @@ -114,6 +163,11 @@ void MwView::MessageReceived(BMessage* message) { this->DrawBitmap(bitmap, rc); break; } + case BVIEW_MW_RENDER: + { + this->Invalidate(); + break; + } default: { BView::MessageReceived(message); break; @@ -129,6 +183,20 @@ void MwView::PostMessage(BMessage* message){ this->Window()->PostMessage(©); } +void MwView::PostMessage(uint32 command){ + BMessage msg(command); + + this->PostMessage(&msg); +} + +void MwView::Invalidate(){ + this->Draw(BRect(0, 0, 0, 0)); +} + +void MwView::AttachedToWindow(){ + this->SetOrigin(0, 0); +} + void MwView::Draw(BRect updateRect){ MwLLHaikuEvent ev; @@ -141,6 +209,71 @@ void MwView::Draw(BRect updateRect){ this->locker->Unlock(); } +void MwView::MouseDown(BPoint point){ + MwLLHaikuEvent ev; + uint32 btn; + BPoint p; + + this->GetMouse(&p, &btn, false); + + this->SetMouseEventMask(B_LOCK_WINDOW_FOCUS); + + ev.type = MwLLHAIKU_EVENT_MOUSEDOWN; + ev.mouse.point.x = point.x; + ev.mouse.point.y = point.y; + + if((btn & B_PRIMARY_MOUSE_BUTTON) && !(this->buttons & B_PRIMARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_LEFT; + }else if((btn & B_SECONDARY_MOUSE_BUTTON) && !(this->buttons & B_SECONDARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_RIGHT; + }else if((btn & B_TERTIARY_MOUSE_BUTTON) && !(this->buttons & B_TERTIARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_MIDDLE; + } + this->buttons = btn; + + this->locker->Lock(); + arrput(this->handle->haiku.events, ev); + this->locker->Unlock(); +} + +void MwView::MouseUp(BPoint point){ + MwLLHaikuEvent ev; + uint32 btn; + BPoint p; + + this->GetMouse(&p, &btn, false); + + ev.type = MwLLHAIKU_EVENT_MOUSEUP; + ev.mouse.point.x = point.x; + ev.mouse.point.y = point.y; + + if(!(btn & B_PRIMARY_MOUSE_BUTTON) && (this->buttons & B_PRIMARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_LEFT; + }else if(!(btn & B_SECONDARY_MOUSE_BUTTON) && (this->buttons & B_SECONDARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_RIGHT; + }else if(!(btn & B_TERTIARY_MOUSE_BUTTON) && (this->buttons & B_TERTIARY_MOUSE_BUTTON)){ + ev.mouse.button = MwMOUSE_MIDDLE; + } + this->buttons = btn; + + this->locker->Lock(); + arrput(this->handle->haiku.events, ev); + this->locker->Unlock(); +} + +void MwView::MouseMoved(BPoint point, uint32 transit, const BMessage* message){ + MwLLHaikuEvent ev; + + ev.type = MwLLHAIKU_EVENT_MOUSEMOVED; + ev.mouse.point.x = point.x; + ev.mouse.point.y = point.y; + ev.mouse.button = 0; + + this->locker->Lock(); + arrput(this->handle->haiku.events, ev); + this->locker->Unlock(); +} + void MwView::SetColor(MwLLColor color){ BMessage msg(BVIEW_MW_SET_COLOR); @@ -248,6 +381,8 @@ MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { void MwLLDestroyImpl(MwLL handle) { MwLLDestroyCommon(handle); + handle->haiku.view->PostMessage(BVIEW_MW_DESTROY); + if(handle->haiku.app != NULL) { status_t exit_value; @@ -256,7 +391,6 @@ void MwLLDestroyImpl(MwLL handle) { delete handle->haiku.app; } - delete handle->haiku.view; free(handle); } @@ -277,7 +411,21 @@ void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor c handle->haiku.view->PostMessage(&msg); } -void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {} +void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { + int i; + BMessage msg(BVIEW_MW_LINE); + + for(i = 0; i < 2; i++){ + BPoint p(points[i].x, points[i].y); + + fix_point(&p, handle->haiku.view); + + msg.AddPoint("view-point", p); + } + + handle->haiku.view->SetColor(color); + handle->haiku.view->PostMessage(&msg); +} void MwLLBeginDrawImpl(MwLL handle) {} @@ -339,6 +487,8 @@ void MwLLSetWHImpl(MwLL handle, int w, int h) { msg.AddInt32("view-height", h); handle->haiku.view->PostMessage(&msg); + + MwLLDispatch(handle, resize, NULL); } void MwLLSetTitleImpl(MwLL handle, const char* title) { @@ -366,9 +516,21 @@ void MwLLNextEventImpl(MwLL handle) { handle->haiku.view->locker->Lock(); while(arrlen(handle->haiku.events) > 0){ MwLLHaikuEvent* ev = &handle->haiku.events[0]; + MwMouse m; + + if(ev->type == MwLLHAIKU_EVENT_MOUSEDOWN || ev->type == MwLLHAIKU_EVENT_MOUSEUP){ + m.point = ev->mouse.point; + m.button = ev->mouse.button; + } if(ev->type == MwLLHAIKU_EVENT_DRAW){ MwLLDispatch(handle, draw, NULL); + }else if(ev->type == MwLLHAIKU_EVENT_MOUSEDOWN){ + MwLLDispatch(handle, down, &m); + }else if(ev->type == MwLLHAIKU_EVENT_MOUSEUP){ + MwLLDispatch(handle, up, &m); + }else if(ev->type == MwLLHAIKU_EVENT_MOUSEMOVED){ + MwLLDispatch(handle, move, &ev->mouse.point); } arrdel(handle->haiku.events, 0); @@ -434,13 +596,21 @@ void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {} -void MwLLForceRenderImpl(MwLL handle) {} +void MwLLForceRenderImpl(MwLL handle) { + handle->haiku.view->PostMessage(BVIEW_MW_RENDER); +} void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {} void MwLLDetachImpl(MwLL handle, MwPoint* point) {} -void MwLLShowImpl(MwLL handle, int show) {} +void MwLLShowImpl(MwLL handle, int show) { + if(show){ + handle->haiku.view->PostMessage(BVIEW_MW_SHOW); + }else{ + handle->haiku.view->PostMessage(BVIEW_MW_HIDE); + } +} void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {} @@ -464,7 +634,16 @@ void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {} void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {} -void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {} +void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { + BScreen* screen = new BScreen(); + + if(screen->IsValid()){ + rect->width = screen->Frame().Width(); + rect->height = screen->Frame().Height(); + } + + delete screen; +} void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { (void)handle; diff --git a/src/widget/menu.c b/src/widget/menu.c index a7232a6..edadf40 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -97,7 +97,7 @@ static void destroy(MwWidget handle) { p2.x = p.x - 5; \ p2.y = p.y + th / 2 + 5; \ \ - m->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, 0, 0, 0); \ + m->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, MwGetInteger(handle, MwNheight), 0, 0); \ MwSubMenuAppear(m->sub[i]->wsub, m->sub[i], &p2, 0); static void draw(MwWidget handle) {