123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #include "precomp.h"
- //PORTABLE
- #include <bfc/wasabi_std.h>
- #include <api/wnd/wndclass/buttbar.h>
- #include <api/wnd/notifmsg.h>
- #include <api/wnd/wndclass/buttwnd.h>
- #include <api/wnd/popup.h>
- #include <api/script/objects/c_script/c_text.h>
- #include <api/script/objects/c_script/h_button.h>
- class ButtHooker : public H_Button {
- public:
- ButtHooker(ButtBar *hangout, ScriptObject *butt) : bb(hangout), H_Button(butt) { }
- void hook_onLeftClick() {
- bb->onLeftPush(0, 0);
- }
- private:
- ButtBar *bb;
- };
- ButtBar::ButtBar(int resizemode) {
- spacer = 0;
- resize_mode = resizemode;
- hooker = NULL;
- if (resize_mode == STACK) {
- setContent(L"wasabi.buttonbar.stack");
- }
- }
- ButtBar::~ButtBar() {
- buttons.deleteAll();
- delete hooker;
- }
- void ButtBar::setResizeMode(int resizemode) {
- if (resize_mode == resizemode) return;
- resize_mode = resizemode;
- if (isPostOnInit()) onResize();
- }
- int ButtBar::onInit() {
- int i;
- BUTTBAR_PARENT::onInit();
- // create the buttons
- for (i = 0; i < buttons.getNumItems(); i++) {
- buttons[i]->init(this);
- if (resize_mode == STACK) {
- if (i != 0) buttons[i]->setVisible(FALSE);
- if (i == 0) setGroupLabel(buttons[i]->getButtonText());
- }
- }
- return 1;
- }
- int ButtBar::addChild(ButtonWnd *child) {
- buttons.addItem(child);
- if (isInited()) {
- child->init(this);
- child->setParent(this);
- onResize();
- if (buttons.getNumItems() == 1)
- setGroupLabel(child->getButtonText());
- }
- return 1;
- }
- int ButtBar::removeChild(ButtonWnd *child) {
- if (!buttons.haveItem(child)) return 0;
- if (isInited()) onResize();
- return 1;
- }
- int ButtBar::getNumChildren() {
- return buttons.getNumItems();
- }
- ButtonWnd *ButtBar::enumChild(int n) {
- return buttons[n];
- }
- int ButtBar::getWidth() {
- int w = 0;
- for (int i = 0; i < buttons.getNumItems(); i++) {
- w += buttons[i]->getWidth()+spacer;
- }
- return w;
- }
- int ButtBar::getHeight() {
- if (resize_mode == STACK) {
- ifc_window *rw = getContentRootWnd();
- return rw->getPreferences(SUGGESTED_H);
- } else {
- int h = 0;
- for (int i = 0; i < buttons.getNumItems(); i++) {
- h = MAX(h, buttons[i]->getHeight()+1);
- }
- return h;
- }
- }
- void ButtBar::onLeftPush(int x, int y)
- {
- if (resize_mode == STACK)
- {
- PopupMenu pop(this);
- foreach(buttons)
- pop.addCommand(buttons.getfor()->getButtonText(), foreach_index);
- endfor
- int r = pop.popAnchored();
- if (r >= 0) {
- buttons[r]->onLeftPush(0, 0);
- setGroupLabel(buttons[r]->getButtonText());
- }
- }
- }
- int ButtBar::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) {
- switch (msg) {
- case ChildNotify::BUTTON_LEFTPUSH: {
- int ret;
- if (ret = onLeftPush(child->getNotifyId())) {
- return ret;
- } else {
- // This won't fit the current notification schema.
- // We _must_ change it -- too many interfaces assume that the
- // button notification is called back through the parent.
- // return notifyParent(msg, p1, p2);
- // So, I made a new basewnd method passNotifyUp() to defer a notification
- // to the current object's notification target.
- return passNotifyUp(child, msg, p1, p2);
- }
- }
- break;
- }
- return BUTTBAR_PARENT::childNotify(child, msg, p1, p2);
- }
- int ButtBar::onResize() {
- BUTTBAR_PARENT::onResize(); // calling your parent is good(tm) =)
- if (!isPostOnInit()) return 0; // that's just an optim, in case someone's dumb and calling us directly when it shouldnt
- switch (resize_mode) {
- case NORMAL: {
- RECT r = clientRect();
- int height = r.bottom - r.top;
- int x = r.left;
- for (int i = 0; i < buttons.getNumItems(); i++) {
- int w = buttons[i]->getWidth()+spacer;
- buttons[i]->resize(x, r.top, w, height);
- x += w;
- if (x > r.right) break;
- }
- }
- break;
- case STRETCH: {
- if (buttons.getNumItems() > 0) {
- RECT r = clientRect();
- int height = r.bottom - r.top;
- int w = (r.right - r.left) / buttons.getNumItems();
- int x = r.left;
- for (int i = 0; i < buttons.getNumItems(); i++) {
- if (i == buttons.getNumItems()-1) w = (r.right - r.left) - x;
- buttons[i]->resize(x, r.top, w, height);
- x += w;
- }
- }
- }
- break;
- case STACK: // no point
- break;
- }
- return 1;
- }
- int ButtBar::onPaint(Canvas *canvas) {
- ASSERT(canvas != NULL);
- if (resize_mode != STACK) {
- BUTTBAR_PARENT::onPaint(canvas);
- renderBaseTexture(canvas, clientRect());
- }
- return 1;
- }
- void ButtBar::setGroupLabel(const wchar_t *l) {
- setName(l);
- onNewContent();
- }
- void ButtBar::onNewContent()
- {
- if (resize_mode != STACK) return;
- ScriptObject *text = findScriptObject(L"buttonbar.text");
- if (text == NULL) return;
- C_Text(text).setText(getNameSafe(L"no tabs"));
- // hook the clicks
- delete hooker;
- ScriptObject *mousetrap = findScriptObject(L"mousetrap");
- hooker = new ButtHooker(this, mousetrap);
- }
|