void MessageDialog::Create() { int const buttonWidth = GetMenuSize(40); int const buttonHeight = GetMenuSize(18); OKButton *button = new OKButton(this); char *caption = "Close"; if( g_app->m_langTable ) caption = LANGUAGEPHRASE("dialog_close"); button->SetShortProperties( caption, (m_w - buttonWidth)/2, m_h - GetMenuSize(30), buttonWidth, buttonHeight ); button->m_fontSize = GetMenuSize(11); RegisterButton( button ); }
//根据Menu内容来绘制菜单内容 void DrawXlibMenu(XlibMenu * menu) { FcitxSkin *sc = &menu->owner->skin; FcitxClassicUI *classicui = menu->owner; Display* dpy = classicui->dpy; GC gc = XCreateGC(dpy, menu->menuWindow, 0, NULL); int i = 0; int fontheight; int iPosY = 0; int dpi = sc->skinFont.respectDPI? menu->owner->dpi: 0; FCITX_UNUSED(dpi); fontheight = FontHeight(menu->owner->menuFont, sc->skinFont.menuFontSize, dpi); SkinImage *background = LoadImage(sc, sc->skinMenu.backImg, false); GetMenuSize(menu); EnlargeCairoSurface(&menu->menu_cs, menu->width, menu->height); if (background) { cairo_t* cr = cairo_create(menu->menu_cs); DrawResizableBackground(cr, background->image, menu->height, menu->width, sc->skinMenu.marginLeft, sc->skinMenu.marginTop, sc->skinMenu.marginRight, sc->skinMenu.marginBottom, sc->skinMenu.fillV, sc->skinMenu.fillH ); cairo_destroy(cr); } iPosY = sc->skinMenu.marginTop; for (i = 0; i < utarray_len(&menu->menushell->shell); i++) { if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_SIMPLE || GetMenuItem(menu->menushell, i)->type == MENUTYPE_SUBMENU) { DisplayText(menu, i, iPosY, fontheight); if (menu->menushell->mark == i) MenuMark(menu, iPosY, i); if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_SUBMENU) DrawArrow(menu, iPosY); iPosY = iPosY + 6 + fontheight; } else if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_DIVLINE) { DrawDivLine(menu, iPosY); iPosY += 5; } } XResizeWindow(dpy, menu->menuWindow, menu->width, menu->height); _CAIRO_SETSIZE(menu->menu_x_cs, menu->width, menu->height); cairo_t* c = cairo_create(menu->menu_x_cs); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(c, menu->menu_cs, 0, 0); cairo_rectangle(c, 0, 0, menu->width, menu->height); cairo_clip(c); cairo_paint(c); cairo_destroy(c); cairo_surface_flush(menu->menu_x_cs); XFreeGC(dpy, gc); }
//根据Menu内容来绘制菜单内容 void DrawXlibMenu(XlibMenu * menu) { FcitxLightUI *lightui = menu->owner; Display* dpy = lightui->dpy; GC gc = XCreateGC( dpy, menu->menuWindow, 0, NULL ); int i=0; int fontheight; int iPosY = 0; fontheight= MenuFontSize; GetMenuSize(menu); DrawResizableBackground(menu->owner, menu->pixmap, menu->height, menu->width, menu->owner->backcolor, menu->owner->bordercolor, gc); iPosY=MenuMarginTop; for (i=0;i<utarray_len(&menu->menushell->shell);i++) { if ( GetMenuShell(menu->menushell, i)->type == MENUTYPE_SIMPLE || GetMenuShell(menu->menushell, i)->type == MENUTYPE_SUBMENU) { DisplayText( menu,i,iPosY); if (menu->menushell->mark == i) MenuMark(menu,iPosY,i); if (GetMenuShell(menu->menushell, i)->type == MENUTYPE_SUBMENU) DrawArrow(menu, iPosY); iPosY=iPosY+6+fontheight; } else if ( GetMenuShell(menu->menushell, i)->type == MENUTYPE_DIVLINE) { DrawDivLine(menu,iPosY); iPosY+=5; } } XResizeWindow(dpy, menu->menuWindow, menu->width, menu->height); XCopyArea (dpy, menu->pixmap, menu->menuWindow, gc, 0, 0, menu->width, menu->height, 0, 0); XFreeGC(dpy, gc); }
void MoveSubMenu(XlibMenu *sub, XlibMenu *parent, int offseth) { int dwidth, dheight; GetScreenSize(parent->owner, &dwidth, &dheight); UpdateMenuShell(sub->menushell); GetMenuSize(sub); sub->iPosX=parent->iPosX + parent->width - MenuMarginRight - 4; sub->iPosY=parent->iPosY + offseth - MenuMarginTop; if ( sub->iPosX + sub->width > dwidth) sub->iPosX=parent->iPosX - sub->width + MenuMarginLeft + 4; if ( sub->iPosY + sub->height > dheight) sub->iPosY = dheight - sub->height; XMoveWindow(parent->owner->dpy, sub->menuWindow, sub->iPosX, sub->iPosY); }
void MoveSubMenu(XlibMenu *sub, XlibMenu *parent, int offseth) { int dwidth, dheight; FcitxSkin *sc = &parent->owner->skin; GetScreenSize(parent->owner, &dwidth, &dheight); FcitxMenuUpdate(sub->menushell); GetMenuSize(sub); sub->iPosX = parent->iPosX + parent->width - sc->skinMenu.marginRight - 4; sub->iPosY = parent->iPosY + offseth - sc->skinMenu.marginTop; if (sub->iPosX + sub->width > dwidth) sub->iPosX = parent->iPosX - sub->width + sc->skinMenu.marginLeft + 4; if (sub->iPosY + sub->height > dheight) sub->iPosY = dheight - sub->height; XMoveWindow(parent->owner->dpy, sub->menuWindow, sub->iPosX, sub->iPosY); }
boolean TrayEventHandler(void *arg, XEvent* event) { TrayWindow *trayWindow = arg; FcitxClassicUI *classicui = trayWindow->owner; FcitxInstance* instance = classicui->owner; Display *dpy = classicui->dpy; if (!classicui->bUseTrayIcon) return false; switch (event->type) { case ClientMessage: if (event->xclient.message_type == trayWindow->atoms[ATOM_MANAGER] && event->xclient.data.l[1] == trayWindow->atoms[ATOM_SELECTION]) { if (trayWindow->window == None) InitTrayWindow(trayWindow); TrayFindDock(dpy, trayWindow); return true; } break; case Expose: if (event->xexpose.window == trayWindow->window) { DrawTrayWindow(trayWindow); } break; case ConfigureNotify: if (trayWindow->window == event->xconfigure.window) { int size = event->xconfigure.height; if (size != trayWindow->size) { trayWindow->size = size; XSizeHints size_hints; size_hints.flags = PWinGravity | PBaseSize; size_hints.base_width = trayWindow->size; size_hints.base_height = trayWindow->size; XSetWMNormalHints(dpy, trayWindow->window, &size_hints); } DrawTrayWindow(trayWindow); return true; } break; case ButtonPress: { if (event->xbutton.window == trayWindow->window) { switch (event->xbutton.button) { case Button1: if (FcitxInstanceGetCurrentState(instance) == IS_CLOSED) { FcitxInstanceEnableIM(instance, FcitxInstanceGetCurrentIC(instance), false); } else { FcitxInstanceCloseIM(instance, FcitxInstanceGetCurrentIC(instance)); } break; case Button3: { XlibMenu *mainMenuWindow = classicui->mainMenuWindow; int dwidth, dheight; FcitxMenuUpdate(mainMenuWindow->menushell); GetScreenSize(classicui, &dwidth, &dheight); GetMenuSize(mainMenuWindow); if (event->xbutton.x_root - event->xbutton.x + mainMenuWindow->width >= dwidth) mainMenuWindow->iPosX = dwidth - mainMenuWindow->width - event->xbutton.x; else mainMenuWindow->iPosX = event->xbutton.x_root - event->xbutton.x; // 面板的高度是可以变动的,需要取得准确的面板高度,才能准确确定右键菜单位置。 if (event->xbutton.y_root + mainMenuWindow->height - event->xbutton.y >= dheight) mainMenuWindow->iPosY = dheight - mainMenuWindow->height - event->xbutton.y - 15; else mainMenuWindow->iPosY = event->xbutton.y_root - event->xbutton.y + 25; // +sc.skin_tray_icon.active_img.height; DrawXlibMenu(mainMenuWindow); DisplayXlibMenu(mainMenuWindow); } break; } return true; } } break; case DestroyNotify: if (event->xdestroywindow.window == trayWindow->dockWindow) { trayWindow->dockWindow = None; trayWindow->bTrayMapped = False; ReleaseTrayWindow(trayWindow); return true; } break; case ReparentNotify: if (event->xreparent.parent == DefaultRootWindow(dpy) && event->xreparent.window == trayWindow->window) { trayWindow->bTrayMapped = False; ReleaseTrayWindow(trayWindow); return true; } break; } return false; }
boolean MenuWindowEventHandler(void *arg, XEvent* event) { XlibMenu* menu = (XlibMenu*) arg; if (event->xany.window == menu->menuWindow) { switch (event->type) { case MapNotify: UpdateMenuShell(menu->menushell); break; case Expose: DrawXlibMenu(menu); break; case LeaveNotify: { int x = event->xcrossing.x_root; int y = event->xcrossing.y_root; if (!IsMouseInOtherMenu(menu, x, y)) { CloseAllSubMenuWindow(menu); } } break; case MotionNotify: { int offseth = 0; GetMenuSize(menu); int i=SelectShellIndex(menu, event->xmotion.x, event->xmotion.y, &offseth); boolean flag = ReverseColor(menu,i); if (!flag) { DrawXlibMenu(menu); } MenuShell *shell = GetMenuShell(menu->menushell, i); if (shell && shell->type == MENUTYPE_SUBMENU && shell->subMenu) { XlibMenu* subxlibmenu = (XlibMenu*) shell->subMenu->uipriv; CloseOtherSubMenuWindow(menu, subxlibmenu); MoveSubMenu(subxlibmenu, menu, offseth); DrawXlibMenu(subxlibmenu); XMapRaised(menu->owner->dpy, subxlibmenu->menuWindow); } if (shell == NULL) CloseOtherSubMenuWindow(menu, NULL); } break; case ButtonPress: { switch (event->xbutton.button) { case Button1: { int offseth; int i=SelectShellIndex(menu, event->xmotion.x, event->xmotion.y, &offseth); if (menu->menushell->MenuAction) { if (menu->menushell->MenuAction(menu->menushell, i)) CloseAllMenuWindow(menu->owner); } } break; case Button3: CloseAllMenuWindow(menu->owner); break; } } break; } return true; } return false; }