void EventDispatch::Dispatch() { int ml = Mouse::LButton(); int mr = Mouse::RButton(); int mx = Mouse::X(); int my = Mouse::Y(); int mw = Mouse::Wheel(); EventTarget* mouse_tgt = capture; EventTarget* key_tgt = focus; EventTarget* do_click = 0; if (!mouse_tgt) { ListIter<EventTarget> iter = clients; while (++iter) { EventTarget* test = iter.value(); if (test->IsFormActive()) { if (test->TargetRect().Contains(mx,my)) mouse_tgt = test; if (test->HasFocus()) key_tgt = test; } } } // Mouse Events: if (mouse_tgt != current) { if (current && current->IsEnabled() && current->IsVisible()) current->OnMouseExit(mx,my); current = mouse_tgt; if (current && current->IsEnabled() && current->IsVisible()) current->OnMouseEnter(mx,my); } if (mouse_tgt && mouse_tgt->IsEnabled()) { if (mx != mouse_x || my != mouse_y) mouse_tgt->OnMouseMove(mx,my); if (mw != 0) mouse_tgt->OnMouseWheel(mw); if (ml != mouse_l) { if (ml) { mouse_tgt->OnLButtonDown(mx,my); click_tgt = mouse_tgt; } else { mouse_tgt->OnLButtonUp(mx,my); if (click_tgt == mouse_tgt) { if (click_tgt->TargetRect().Contains(mx,my)) do_click = click_tgt; click_tgt = 0; } } } if (mr != mouse_r) { if (mr) mouse_tgt->OnRButtonDown(mx,my); else mouse_tgt->OnRButtonUp(mx,my); } } mouse_l = ml; mouse_r = mr; mouse_x = mx; mouse_y = my; // Keyboard Events: if (click_tgt && click_tgt != key_tgt) { if (key_tgt) key_tgt->KillFocus(); key_tgt = click_tgt; if (key_tgt != focus) { if (focus) focus->KillFocus(); if (key_tgt && key_tgt->IsEnabled() && key_tgt->IsVisible()) focus = key_tgt; else key_tgt = 0; if (focus) focus->SetFocus(); } } if (key_tgt && key_tgt->IsEnabled()) { int key = 0; int shift = 0; while (GetKeyPlus(key, shift)) { if (key == VK_ESCAPE) { key_tgt->KillFocus(); focus = 0; break; } else if (key == VK_TAB && focus) { int key_index = clients.index(focus) + 1; if (shift & 1) key_index -= 2; if (key_index >= clients.size()) key_index = 0; else if (key_index < 0) key_index = clients.size()-1; if (focus) focus->KillFocus(); focus = clients[key_index]; if (focus) focus->SetFocus(); break; } key_tgt->OnKeyDown(key, shift); } } if (do_click) do_click->OnClick(); }