📄 i_combo.cpp
字号:
// Zinc Application Framework - I_COMBO.CPP// Copyright (c) 1990-1998 Zinc Software, Inc.// Copyright (c) 1999-2003 Wind River Systems, Inc./*modification history--------------------01q,19jun03,jlb Fix SPR 71147 - correction of combo box height01p,07may01,wdf Changed copyright date.01o,21nov00,wdf Fixed SPR# 36092. Viewonly combo box is not cleared when last item is deleted.01n,23oct00,wdf Changed copyright date.01m,20oct00,wdf Fixed crash problem on SH7750.01l,19oct00,bbj Fix focus problem01k,22sep00,bbj Fix for view only combo with UGL windowing01j,21jul00,bbj Switch to using UGL windows01i,06jul00,bbj reentrancy protection under ZAF_RTOS vs. ZAF_REENTRANT01h,04apr00,jom Remove redundant editMode code01g,24feb00,wdf Added code to Event() function to call event listeners.01f,28jan00,wdf Made changes for drawhook.01e,15oct99,wdf Fixed problem of combo not showing focus after an item was selected.01d,21sep99,bbj Interop--switch to EventManager(), WindowManager() accessors01c,19aug99,bbj Add multithread protection01b,10aug99,bbj Remove unused static members01a,27jul99,wdf Documented code, removed commented code, unneeded functions and #defines*/#include <zinc/generic/i_combo.hpp>#include <zinc/z_app.hpp>#include <zinc/z_ctype.hpp>#define USE_RAW_KEYS#include <zinc/z_keymap.hpp>#include <zinc/z_lang.hpp>#include <zinc/z_mouse2.hpp>#include <zinc/z_string.hpp>#include <zinc/z_utils.hpp>// ----- ZafComboBox ------------------------------------------------------////////////////////////////////////////////////////////////////////////////////// ZafComboBox::Add - Adds object to the combo list.//// This function overloads base ZafList::Add() functionality to// handle advanced addition operations typical of derived ZafWindow classes.// For objects added to ZafWindow, these three operations are performed:// - they are added to the list of support or non-support children (either the // support member or the base ZafList part of the class, respectively)// - their parent pointer is set to point to the ZafWindow object// - they are updated on the screen if the parent window is already visible // to the user// // RETURNS: a typesafe ZafWindowObject pointer, which is generally the object // that was passed to the Add() function, but can be null if the object either // currently resides within another window or is an invalid type of Add() // operation.//ZafWindowObject *ZafComboBox::Add(ZafWindowObject *object, ZafWindowObject *position){ // Add the item to the list. return (list->Add(object, position));}////////////////////////////////////////////////////////////////////////////////// ZafComboBox::ConvertCoordinates - converts the object's coordinates to// a new type.//// This function converts zafRegion using ConvertRegion() with the specified// coordinate type.//void ZafComboBox::ConvertCoordinates(ZafCoordinateType newType){ if (zafRegion.coordinateType != newType) { if (maxListHeight != -1) { maxListHeight = (int)display->ConvertYValue(maxListHeight, zafRegion.coordinateType, newType); listHeight = maxListHeight; } else listHeight = (int)display->ConvertYValue(listHeight, zafRegion.coordinateType, newType); if (listWidth != -1) listWidth = (int)display->ConvertXValue(listWidth, zafRegion.coordinateType, newType); ZafWindow::ConvertCoordinates(newType); }}ZafEventType ZafComboBox::DispatchMouseEvent(const ZafEventStruct &event){ // This object behaves as an atom. return (ZafWindowObject::DispatchMouseEvent(event));}////////////////////////////////////////////////////////////////////////////////// ZafComboBox::DragDropEvent - handles drag drop events.//// This function is used internally by ZAF as a dispatch function for system// defined drag/drop messages and should not normally be overloaded by the// programmer. These messages include:// - S_DRAG_DEFAULT// - S_DRAG_MOVE// - S_DRAG_COPY// - S_DRAG_LINK// - S_DROP_DEFAULT// - S_DROP_COPY// - S_DROP_MOVE// - S_DROP_LINK// - S_BEGIN_DRAG// - S_END_DRAG// Whenever an object receives a drag/drop sequence of messages, the messages// are first intercepted in the object抯 Event() function. To allow for more// encapsulation and a more efficient handling of similar drag/drop// functionality, ZAF defines DragDropEvent() which may be called by the base// ZafWindowObject class whenever one of the aforementioned messages is// generated.//// The programmer should not call DragDropEvent(), but it is used internally // by ZAF. When deriving to intercept drag/drop events, the programmer should// always use the Event() function itself.//// RETURNS: event.type if processing is successful. Otherwise, S_ERROR or // S_UNKNOWN may be returned, indicating the object either detected an error // on the message, or that the function did not recognize the specified // message.//ZafEventType ZafComboBox::DragDropEvent(const ZafEventStruct &event){ ZafEventType ccode = event.type; switch (ccode) { case S_BEGIN_DRAG: if (list->Current()) list->Current()->SetSelected(true); ZafWindowObject::DragDropEvent(event); break; case S_DROP_DEFAULT: ccode = S_DROP_MOVE; // Fall through to S_DROP_MOVE. case S_DROP_COPY: case S_DROP_MOVE: if (Disabled() || !AcceptDrop() || WindowManager()->dragObject == this) return (S_ERROR); else if (WindowManager()->dragObject->IsA(ID_ZAF_LIST)) { // Move the selected objects. ZafWindow *dragList = DynamicPtrCast(WindowManager()->dragObject, ZafWindow); ZafWindowObject *object; if (dragList->IsA(ID_ZAF_COMBO_BOX)) object = DynamicPtrCast(dragList, ZafComboBox)->First(); else object = dragList->First(); while (object) { ZafWindowObject *temp = object->Next(); if (object->Selected()) { if (ccode == S_DROP_COPY) { ZafWindowObject *newObject = object->Duplicate(); newObject->SetSelected(false); Add(newObject); } else { dragList->Subtract(object); object->SetSelected(false); Add(object); } } object = temp; } } else if (OSDraw() && !ViewOnly()) ccode = ZafWindowObject::DragDropEvent(event); else ccode = S_ERROR; break; default: ccode = ZafWindow::DragDropEvent(event); break; } return (ccode);}////////////////////////////////////////////////////////////////////////////////// ZafComboBox::Draw - Draws the combobox object.//// Draw() is called whenever the system needs the object to update part, // or all of its information to the screen.//// RETURNS: Draw() returns S_ERROR if some error occurs; otherwise it // returns ccode.//#if defined(ZAF_DEFAULT_DRAW)ZafEventType ZafComboBox::ClassDraw(const ZafEventStruct &event, ZafEventType ccode){ ZafWindow::ClassDraw(event, ccode); return (ccode);}ZafEventType ZafComboBox::DrawFocus(ZafRegionStruct &, ZafEventType ccode){ return (ccode);}#endif////////////////////////////////////////////////////////////////////////////////// ZafComboBox::Event - Processes events for the combo box object.//// This function provides the core connection between event driven // environment specific architectures and the object-oriented architecture // supported by ZAF. This function receives four general types of events:// - ZAF system events represented by S_* messages.// - ZAF notification events represented by N_* messages.// - ZAF logical interpreted events represented by L_* messages.// - Environment specific events where event.type is E_OSEVENT and the // environment// specific message is specified by event.osEvent.//// Some types of events are dispatched to other functions. These functions // are DragDropEvent(), MoveEvent(), and ScrollEvent(). The programmer should// not call these specialized functions, but they are used internally by ZAF. // When deriving to intercept events, the programmer should always use the // Event() function itself.//// Events that are tagged with "event.type == E_OSEVENT" are dispatched// directly to the underlying operating environment.//// Events not handled by this function may be passed to the base class's // Evnet() function to be handled.//// RETURNS: The event, S_ERROR, or S_UNKNOWN message.// ZafEventType ZafComboBox::Event(const ZafEventStruct &event){ ZafEventType ccode = LogicalEvent(event); // Initialize the autoListener. This will call any preprocessing listeners providing // listenerStackCount = 1. When it is destroyed any postprocessing listeners will be // called if the listenerStackCount = 1. ZafAutoListener autoListener(this, event, ccode); // If an event listener processed the event and the library should do nothing with it return. if (event.processed) return (ccode); // Check for zinc events. switch (ccode) { // ----- Create messages ----- case S_INITIALIZE: if (!comboButton) { comboButton = new ZafComboButton; ZafWindow::Add(comboButton); comboButton->Event(event); } comboButton->SetSystemObject(SystemObject()); if (!comboString && (OSDraw() && !viewOnly)) { comboString = new ZafComboString; ZafWindow::Add(comboString); comboString->Event(event); } if ((viewOnly || !OSDraw()) && comboString) { ZafWindow::Subtract(comboString); delete comboString; comboString = ZAF_NULLP(ZafWindowObject); } if (comboString && list->current) comboString->SetText(list->Current()->Text()); list->Event(event); ccode = ZafWindow::Event(event); break; case L_VIEW: case L_CONTINUE_SELECT: case L_END_SELECT: if (Draggable() && ccode != L_VIEW && !WindowManager()->dragObject) ZafWindowObject::Event(event); if (WindowManager()->dragObject) ZafWindowObject::Event(event); else { ZafPositionStruct mousePosition = event.position; ZafRegionStruct windowClient = ClientRegion(); if (windowClient.Overlap(mousePosition)) { // If the mouse is over the client region, convert to the client // region's coordinates. mousePosition.column -= windowClient.left; mousePosition.line -= windowClient.top; // Cast away the constness so we can have event.position relative // to the client region. ((ZafEventStruct &)event).position = mousePosition; // The combo string is the only possible client object. ZafWindowObject *object = ComboFirst(); if (object && object->Visible() && object->zafRegion.Overlap(mousePosition)) { // If the string is being overlapped for the first time // let it set the mouse cursor without making it the // window manager's mouseObject (that would mess up // help tips if the combo box had one). if (ccode == L_VIEW && mouseObject != object) { ZafEventStruct mouseEvent = event; mouseEvent.type = N_MOUSE_ENTER; object->Event(mouseEvent); mouseObject = object; } else ccode = object->Event(event); } } else if (comboButton->zafRegion.Overlap(mousePosition)) { // If the button is being overlapped for the first time // let it set the mouse cursor without making it the // window manager's mouseObject (that would mess up // help tips if the combo box had one). if (ccode == L_VIEW && mouseObject != comboButton) { ZafEventStruct mouseEvent = event; mouseEvent.type = N_MOUSE_ENTER; comboButton->Event(mouseEvent); mouseObject = comboButton; } else ccode = comboButton->Event(event); } else { // If nothing is overlapped, reset the mouse cursor. if (ccode == L_VIEW) { mouseObject = ZAF_NULLP(ZafWindowObject); EventManager()->SetDeviceState(E_MOUSE, DM_VIEW); } else ccode = ZafWindow::Event(event); } } break; case L_BEGIN_SELECT: if (Draggable()) ZafWindow::Event(event); // Open the drop-down list if a click occurs anywhere on the combo-box. if (!viewOnly && OSDraw()) { ZafPositionStruct mousePosition = event.position; ZafRegionStruct windowClient = ClientRegion(); if (windowClient.Overlap(mousePosition)) { // If the mouse is over the client region, convert to the client // region's coordinates. mousePosition.column -= windowClient.left; mousePosition.line -= windowClient.top; // Cast away the constness so we can have event.position relative // to the client region. ((ZafEventStruct &)event).position = mousePosition; // The combo string is the only possible client object. ZafWindowObject *object = ComboFirst(); if (object && object->Visible() && object->zafRegion.Overlap(mousePosition)) return (object->Event(event)); } else if (comboButton->zafRegion.Overlap(mousePosition)) return (comboButton->Event(event)); else return (ZafWindow::Event(event)); } // Continue to L_SELECT. case L_SELECT: { if (ccode == L_SELECT && event.type == E_KEY) { if (WindowManager()->First() != list && event.rawCode != F4) { (this->*memberUserFunction)(event, L_SELECT); break; } } if (WindowManager()->First() == list) { WindowManager()->Event(S_CLOSE_TEMPORARY); Event(N_CLOSE_COMBO_LIST); break; } // Put up drop-down list. int height; if (!list->First()) height = listHeight; else { // Make sure the item has a valid height. list->Event(N_SIZE); listHeight = list->Count() * list->First()->zafRegion.Height() + 2*display->preSpace; height = ZafMin(listHeight, maxListHeight); } int width; if (listWidth == -1) width = zafRegion.Width(); else width = listWidth; ZafPositionStruct origin; origin.column = zafRegion.left; origin.line = zafRegion.bottom; origin.coordinateType = zafRegion.coordinateType; origin = parent->ConvertToOSPosition(this, &origin); ZafRegionStruct listRegion; listRegion.Assign(origin.column, origin.line, width, height, origin.coordinateType); list->SetRegion(listRegion); if (list->zafRegion.bottom > Display()->lines - 1) list->zafRegion.VtShift(-(list->zafRegion.Height() + zafRegion.Height())); list->SetModal(false); ZafWindow *scrollBar = DynamicPtrCast(list->SupportFirst(), ZafWindow); if (scrollBar) scrollBar->SetTemporary(false); list->overlapped = false; WindowManager()->Add(list); list->Event(S_VSCROLL_CHECK); Event(N_OPEN_COMBO_LIST); } break; case N_CLOSE_COMBO_LIST: if (comboString) comboString->Event(S_CURRENT); break; case N_MOUSE_ENTER: ZafWindow::Event(event); mouseObject = ZAF_NULLP(ZafWindowObject); break; case S_NON_CURRENT: case S_CURRENT: { bool _focus = focus; current = comboString; ZafWindow::Event(event); if (ccode == S_CURRENT && focus && comboString) comboString->SetFocus(true); else if (ccode == S_NON_CURRENT && !focus && comboString) comboString->SetFocus(false); if (_focus != focus) Redisplay(); } break; case L_UP: case L_DOWN: list->Event(event); break; case L_NEXT: case L_PREVIOUS: ccode = S_UNKNOWN; break; case E_KEY: if (comboString) comboString->Event(event); MatchInput(event.key.value); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -