struct InspectorElementEntry { EsElement *element; EsRectangle takenBounds, givenBounds; int depth; }; struct InspectorWindow : EsInstance { EsInstance *instance; // The instance being inspected. EsListView *elementList; Array elements; // TODO This is being leaked. InspectorElementEntry hoveredElement; char *cCategoryFilter; intptr_t selectedElement; EsButton *alignH[6]; EsButton *alignV[6]; EsButton *direction[4]; EsTextbox *contentTextbox; EsButton *addChildButton; EsButton *addSiblingButton; EsButton *visualizeRepaints; EsButton *visualizeLayoutBounds; EsButton *visualizePaintSteps; EsListView *listEvents; EsTextbox *textboxCategoryFilter; }; int InspectorElementItemCallback(EsElement *element, EsMessage *message) { InspectorWindow *inspector = (InspectorWindow *) element->instance; if (message->type == ES_MSG_HOVERED_START) { InspectorElementEntry *entry = &inspector->elements[EsListViewGetIndexFromItem(element)]; if (entry->element->parent) entry->element->parent->Repaint(true); else entry->element->Repaint(true); inspector->hoveredElement = *entry; } else if (message->type == ES_MSG_HOVERED_END || message->type == ES_MSG_DESTROY) { EsListViewIndex index = EsListViewGetIndexFromItem(element); InspectorElementEntry *entry = &inspector->elements[index]; if (entry->element->parent) entry->element->parent->Repaint(true); else entry->element->Repaint(true); inspector->hoveredElement = {}; } return 0; } void InspectorUpdateEditor(InspectorWindow *inspector) { EsElement *e = inspector->selectedElement == -1 ? nullptr : inspector->elements[inspector->selectedElement].element; bool isStack = e && e->messageClass == ProcessPanelMessage && !(e->flags & (ES_PANEL_Z_STACK | ES_PANEL_TABLE | ES_PANEL_SWITCHER)); bool alignHLeft = e ? (e->flags & ES_CELL_H_LEFT) : false, alignHRight = e ? (e->flags & ES_CELL_H_RIGHT) : false; bool alignHExpand = e ? (e->flags & ES_CELL_H_EXPAND) : false, alignHShrink = e ? (e->flags & ES_CELL_H_SHRINK) : false; bool alignHPush = e ? (e->flags & ES_CELL_H_PUSH) : false; bool alignVTop = e ? (e->flags & ES_CELL_V_TOP) : false, alignVBottom = e ? (e->flags & ES_CELL_V_BOTTOM) : false; bool alignVExpand = e ? (e->flags & ES_CELL_V_EXPAND) : false, alignVShrink = e ? (e->flags & ES_CELL_V_SHRINK) : false; bool alignVPush = e ? (e->flags & ES_CELL_V_PUSH) : false; bool stackHorizontal = isStack && (e->flags & ES_PANEL_HORIZONTAL); bool stackReverse = isStack && (e->flags & ES_PANEL_REVERSE); EsButtonSetCheck(inspector->alignH[0], (EsCheckState) (e && alignHLeft && !alignHRight), false); EsButtonSetCheck(inspector->alignH[1], (EsCheckState) (e && alignHLeft == alignHRight), false); EsButtonSetCheck(inspector->alignH[2], (EsCheckState) (e && !alignHLeft && alignHRight), false); EsButtonSetCheck(inspector->alignH[3], (EsCheckState) (e && alignHExpand), false); EsButtonSetCheck(inspector->alignH[4], (EsCheckState) (e && alignHShrink), false); EsButtonSetCheck(inspector->alignH[5], (EsCheckState) (e && alignHPush), false); EsButtonSetCheck(inspector->alignV[0], (EsCheckState) (e && alignVTop && !alignVBottom), false); EsButtonSetCheck(inspector->alignV[1], (EsCheckState) (e && alignVTop == alignVBottom), false); EsButtonSetCheck(inspector->alignV[2], (EsCheckState) (e && !alignVTop && alignVBottom), false); EsButtonSetCheck(inspector->alignV[3], (EsCheckState) (e && alignVExpand), false); EsButtonSetCheck(inspector->alignV[4], (EsCheckState) (e && alignVShrink), false); EsButtonSetCheck(inspector->alignV[5], (EsCheckState) (e && alignVPush), false); EsButtonSetCheck(inspector->direction[0], (EsCheckState) (isStack && stackHorizontal && stackReverse), false); EsButtonSetCheck(inspector->direction[1], (EsCheckState) (isStack && stackHorizontal && !stackReverse), false); EsButtonSetCheck(inspector->direction[2], (EsCheckState) (isStack && !stackHorizontal && stackReverse), false); EsButtonSetCheck(inspector->direction[3], (EsCheckState) (isStack && !stackHorizontal && !stackReverse), false); EsElementSetDisabled(inspector->alignH[0], !e); EsElementSetDisabled(inspector->alignH[1], !e); EsElementSetDisabled(inspector->alignH[2], !e); EsElementSetDisabled(inspector->alignH[3], !e); EsElementSetDisabled(inspector->alignH[4], !e); EsElementSetDisabled(inspector->alignH[5], !e); EsElementSetDisabled(inspector->alignV[0], !e); EsElementSetDisabled(inspector->alignV[1], !e); EsElementSetDisabled(inspector->alignV[2], !e); EsElementSetDisabled(inspector->alignV[3], !e); EsElementSetDisabled(inspector->alignV[4], !e); EsElementSetDisabled(inspector->alignV[5], !e); EsElementSetDisabled(inspector->direction[0], !isStack); EsElementSetDisabled(inspector->direction[1], !isStack); EsElementSetDisabled(inspector->direction[2], !isStack); EsElementSetDisabled(inspector->direction[3], !isStack); EsElementSetDisabled(inspector->addChildButton, !isStack); EsElementSetDisabled(inspector->addSiblingButton, !e || !e->parent); EsElementSetDisabled(inspector->textboxCategoryFilter, !e); EsTextboxSelectAll(inspector->contentTextbox); EsTextboxInsert(inspector->contentTextbox, "", 0, false); if (e) { #if 0 for (uintptr_t i = 0; i < sizeof(builtinStyles) / sizeof(builtinStyles[0]); i++) { if (e->currentStyleKey.partHash == CalculateCRC64(EsLiteral(builtinStyles[i]))) { EsTextboxInsert(inspector->styleTextbox, builtinStyles[i], -1, false); break; } } #endif if (e->messageClass == ProcessButtonMessage) { EsButton *button = (EsButton *) e; EsElementSetDisabled(inspector->contentTextbox, false); EsTextboxInsert(inspector->contentTextbox, button->label, button->labelBytes, false); } else if (e->messageClass == ProcessTextDisplayMessage) { EsTextDisplay *display = (EsTextDisplay *) e; EsElementSetDisabled(inspector->contentTextbox, false); EsTextboxInsert(inspector->contentTextbox, display->contents, display->textRuns[display->textRunCount].offset, false); } else { EsElementSetDisabled(inspector->contentTextbox, true); } } else { EsElementSetDisabled(inspector->contentTextbox, true); } } int InspectorElementListCallback(EsElement *element, EsMessage *message) { InspectorWindow *inspector = (InspectorWindow *) element->instance; if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) { int column = message->getContent.columnID, index = message->getContent.index; EsAssert(index >= 0 && index < (int) inspector->elements.Length()); InspectorElementEntry *entry = &inspector->elements[index]; if (column == 0) { EsBufferFormat(message->getContent.buffer, "%z", entry->element->cName); } else if (column == 1) { EsBufferFormat(message->getContent.buffer, "%R", entry->element->GetWindowBounds(false)); } else if (column == 2) { EsMessage m = *message; m.type = ES_MSG_GET_INSPECTOR_INFORMATION; EsMessageSend(entry->element, &m); } return ES_HANDLED; } else if (message->type == ES_MSG_LIST_VIEW_GET_INDENT) { message->getIndent.indent = inspector->elements[message->getIndent.index].depth; return ES_HANDLED; } else if (message->type == ES_MSG_LIST_VIEW_CREATE_ITEM) { message->createItem.item->messageUser = InspectorElementItemCallback; return ES_HANDLED; } else if (message->type == ES_MSG_LIST_VIEW_SELECT) { if (inspector->selectedElement != -1) { inspector->elements[inspector->selectedElement].element->state &= ~UI_STATE_INSPECTING; } inspector->selectedElement = message->selectItem.isSelected ? message->selectItem.index : -1; if (inspector->selectedElement != -1) { EsElement *e = inspector->elements[inspector->selectedElement].element; e->state |= UI_STATE_INSPECTING; InspectorNotifyElementEvent(e, nullptr, "Viewing events from '%z'.\n", e->cName); } InspectorUpdateEditor(inspector); return ES_HANDLED; } else if (message->type == ES_MSG_LIST_VIEW_IS_SELECTED) { message->selectItem.isSelected = message->selectItem.index == inspector->selectedElement; return ES_HANDLED; } return 0; } int InspectorContentTextboxCallback(EsElement *element, EsMessage *message) { InspectorWindow *inspector = (InspectorWindow *) element->instance; if (message->type == ES_MSG_TEXTBOX_EDIT_END) { size_t newContentBytes; char *newContent = EsTextboxGetContents(inspector->contentTextbox, &newContentBytes); EsElement *e = inspector->elements[inspector->selectedElement].element; if (e->messageClass == ProcessButtonMessage) { EsButton *button = (EsButton *) e; HeapDuplicate((void **) &button->label, &button->labelBytes, newContent, newContentBytes); } else if (e->messageClass == ProcessTextDisplayMessage) { EsTextDisplay *display = (EsTextDisplay *) e; EsTextDisplaySetContents(display, newContent, newContentBytes); } else { EsAssert(false); } EsElementUpdateContentSize(e); if (e->parent) EsElementUpdateContentSize(e->parent); EsHeapFree(newContent); return ES_HANDLED; } return 0; } int InspectorTextboxCategoryFilterCallback(EsElement *element, EsMessage *message) { InspectorWindow *inspector = (InspectorWindow *) element->instance; if (message->type == ES_MSG_TEXTBOX_UPDATED) { EsHeapFree(inspector->cCategoryFilter); inspector->cCategoryFilter = EsTextboxGetContents((EsTextbox *) element); } return 0; } InspectorWindow *InspectorGet(EsElement *element) { if (!element->window || !element->instance) return nullptr; APIInstance *instance = (APIInstance *) element->instance->_private; InspectorWindow *inspector = instance->attachedInspector; if (!inspector || inspector->instance->window != element->window) return nullptr; return inspector; } void InspectorNotifyElementEvent(EsElement *element, const char *cCategory, const char *cFormat, ...) { if (~element->state & UI_STATE_INSPECTING) return; InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; if (inspector->cCategoryFilter && inspector->cCategoryFilter[0] && cCategory && EsCRTstrcmp(cCategory, inspector->cCategoryFilter)) return; va_list arguments; va_start(arguments, cFormat); char _buffer[256]; EsBuffer buffer = { .out = (uint8_t *) _buffer, .bytes = sizeof(_buffer) }; if (cCategory) EsBufferFormat(&buffer, "%z: ", cCategory); EsBufferFormatV(&buffer, cFormat, arguments); va_end(arguments); EsListViewIndex index = EsListViewFixedItemInsert(inspector->listEvents); EsListViewFixedItemSetString(inspector->listEvents, index, 0, _buffer, buffer.position); EsListViewScrollToEnd(inspector->listEvents); } void InspectorNotifyElementContentChanged(EsElement *element) { InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; for (uintptr_t i = 0; i < inspector->elements.Length(); i++) { if (inspector->elements[i].element == element) { EsListViewInvalidateContent(inspector->elementList, 0, i); return; } } EsAssert(false); } void InspectorNotifyElementMoved(EsElement *element, EsRectangle takenBounds) { InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; for (uintptr_t i = 0; i < inspector->elements.Length(); i++) { if (inspector->elements[i].element == element) { inspector->elements[i].takenBounds = takenBounds; inspector->elements[i].givenBounds = takenBounds; // TODO. EsListViewInvalidateContent(inspector->elementList, 0, i); return; } } EsAssert(false); } void InspectorNotifyElementDestroyed(EsElement *element) { InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; for (uintptr_t i = 0; i < inspector->elements.Length(); i++) { if (inspector->elements[i].element == element) { if (inspector->selectedElement == (intptr_t) i) { inspector->selectedElement = -1; InspectorUpdateEditor(inspector); } else if (inspector->selectedElement > (intptr_t) i) { inspector->selectedElement--; } EsListViewRemove(inspector->elementList, 0, i, 1); inspector->elements.Delete(i); return; } } EsAssert(false); } void InspectorNotifyElementCreated(EsElement *element) { InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; ptrdiff_t indexInParent = -1; for (uintptr_t i = 0; i < element->parent->children.Length(); i++) { if (element->parent->children[i] == element) { indexInParent = i; break; } } EsAssert(indexInParent != -1); ptrdiff_t insertAfterIndex = -1; for (uintptr_t i = 0; i < inspector->elements.Length(); i++) { if (indexInParent == 0) { if (inspector->elements[i].element == element->parent) { insertAfterIndex = i; break; } } else { if (inspector->elements[i].element == element->parent->children[indexInParent - 1]) { insertAfterIndex = i; int baseDepth = inspector->elements[i++].depth; for (; i < inspector->elements.Length(); i++) { if (inspector->elements[i].depth > baseDepth) { insertAfterIndex++; } else { break; } } break; } } } EsAssert(insertAfterIndex != -1); int depth = 0; EsElement *ancestor = element->parent; while (ancestor) { depth++; ancestor = ancestor->parent; } if (inspector->selectedElement > insertAfterIndex) { inspector->selectedElement++; } InspectorElementEntry entry; entry.element = element; entry.depth = depth; inspector->elements.Insert(entry, insertAfterIndex + 1); EsListViewInsert(inspector->elementList, 0, insertAfterIndex + 1, 1); } void InspectorFindElementsRecursively(InspectorWindow *inspector, EsElement *element, int depth) { InspectorElementEntry entry = {}; entry.element = element; entry.depth = depth; inspector->elements.Add(entry); for (uintptr_t i = 0; i < element->children.Length(); i++) { InspectorFindElementsRecursively(inspector, element->children[i], depth + 1); } } void InspectorRefreshElementList(InspectorWindow *inspector) { EsListViewRemoveAll(inspector->elementList, 0); inspector->elements.Free(); InspectorFindElementsRecursively(inspector, inspector->instance->window, 0); EsListViewInsert(inspector->elementList, 0, 0, inspector->elements.Length()); } void InspectorNotifyElementPainted(EsElement *element, EsPainter *painter) { InspectorWindow *inspector = InspectorGet(element); if (!inspector) return; InspectorElementEntry *entry = inspector->hoveredElement.element ? &inspector->hoveredElement : nullptr; if (!entry) return; EsRectangle bounds = ES_RECT_4(painter->offsetX, painter->offsetX + painter->width, painter->offsetY, painter->offsetY + painter->height); if (entry->element == element) { EsDrawRectangle(painter, bounds, 0x607F7FFF, 0x60FFFF7F, element->style->insets); } else if (entry->element->parent == element) { if ((element->flags & ES_CELL_FILL) != ES_CELL_FILL) { EsRectangle rectangle = entry->givenBounds; rectangle.l += bounds.l, rectangle.r += bounds.l; rectangle.t += bounds.t, rectangle.b += bounds.t; // EsDrawBlock(painter, rectangle, 0x20FF7FFF); } } } #define INSPECTOR_ALIGN_COMMAND(name, clear, set, toggle) \ void name (EsInstance *instance, EsElement *, EsCommand *) { \ InspectorWindow *inspector = (InspectorWindow *) instance; \ EsElement *e = inspector->elements[inspector->selectedElement].element; \ if (toggle) e->flags ^= set; \ else { e->flags &= ~(clear); e->flags |= set; } \ EsElementUpdateContentSize(e); \ if (e->parent) EsElementUpdateContentSize(e->parent); \ inspector->elementList->Repaint(true); \ InspectorUpdateEditor(inspector); \ } INSPECTOR_ALIGN_COMMAND(InspectorHAlignLeft, ES_CELL_H_LEFT | ES_CELL_H_RIGHT, ES_CELL_H_LEFT, false); INSPECTOR_ALIGN_COMMAND(InspectorHAlignCenter, ES_CELL_H_LEFT | ES_CELL_H_RIGHT, ES_CELL_H_LEFT | ES_CELL_H_RIGHT, false); INSPECTOR_ALIGN_COMMAND(InspectorHAlignRight, ES_CELL_H_LEFT | ES_CELL_H_RIGHT, ES_CELL_H_RIGHT, false); INSPECTOR_ALIGN_COMMAND(InspectorHAlignExpand, 0, ES_CELL_H_EXPAND, true); INSPECTOR_ALIGN_COMMAND(InspectorHAlignShrink, 0, ES_CELL_H_SHRINK, true); INSPECTOR_ALIGN_COMMAND(InspectorHAlignPush, 0, ES_CELL_H_PUSH, true); INSPECTOR_ALIGN_COMMAND(InspectorVAlignTop, ES_CELL_V_TOP | ES_CELL_V_BOTTOM, ES_CELL_V_TOP, false); INSPECTOR_ALIGN_COMMAND(InspectorVAlignCenter, ES_CELL_V_TOP | ES_CELL_V_BOTTOM, ES_CELL_V_TOP | ES_CELL_V_BOTTOM, false); INSPECTOR_ALIGN_COMMAND(InspectorVAlignBottom, ES_CELL_V_TOP | ES_CELL_V_BOTTOM, ES_CELL_V_BOTTOM, false); INSPECTOR_ALIGN_COMMAND(InspectorVAlignExpand, 0, ES_CELL_V_EXPAND, true); INSPECTOR_ALIGN_COMMAND(InspectorVAlignShrink, 0, ES_CELL_V_SHRINK, true); INSPECTOR_ALIGN_COMMAND(InspectorVAlignPush, 0, ES_CELL_V_PUSH, true); INSPECTOR_ALIGN_COMMAND(InspectorDirectionLeft, ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_REVERSE, ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_REVERSE, false); INSPECTOR_ALIGN_COMMAND(InspectorDirectionRight, ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_REVERSE, ES_PANEL_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL, false); INSPECTOR_ALIGN_COMMAND(InspectorDirectionUp, ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_REVERSE, ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_REVERSE, false); INSPECTOR_ALIGN_COMMAND(InspectorDirectionDown, ES_PANEL_HORIZONTAL | ES_PANEL_REVERSE | ES_ELEMENT_LAYOUT_HINT_HORIZONTAL | ES_ELEMENT_LAYOUT_HINT_REVERSE, 0, false); void InspectorVisualizeRepaints(EsInstance *instance, EsElement *, EsCommand *) { InspectorWindow *inspector = (InspectorWindow *) instance; EsWindow *window = inspector->instance->window; window->visualizeRepaints = !window->visualizeRepaints; EsButtonSetCheck(inspector->visualizeRepaints, window->visualizeRepaints ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false); } void InspectorVisualizePaintSteps(EsInstance *instance, EsElement *, EsCommand *) { InspectorWindow *inspector = (InspectorWindow *) instance; EsWindow *window = inspector->instance->window; window->visualizePaintSteps = !window->visualizePaintSteps; EsButtonSetCheck(inspector->visualizePaintSteps, window->visualizePaintSteps ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false); } void InspectorVisualizeLayoutBounds(EsInstance *instance, EsElement *, EsCommand *) { InspectorWindow *inspector = (InspectorWindow *) instance; EsWindow *window = inspector->instance->window; window->visualizeLayoutBounds = !window->visualizeLayoutBounds; EsButtonSetCheck(inspector->visualizeLayoutBounds, window->visualizeLayoutBounds ? ES_CHECK_CHECKED : ES_CHECK_UNCHECKED, false); EsElementRepaint(window); } void InspectorAddElement2(EsMenu *menu, EsGeneric context) { InspectorWindow *inspector = (InspectorWindow *) menu->instance; if (inspector->selectedElement == -1) return; EsElement *e = inspector->elements[inspector->selectedElement].element; int asSibling = context.u & 0x80; context.u &= ~0x80; if (asSibling) { EsElementInsertAfter(e); e = e->parent; } if (context.u == 1) { EsButtonCreate(e); } else if (context.u == 2) { EsPanelCreate(e); } else if (context.u == 3) { EsSpacerCreate(e); } else if (context.u == 4) { EsTextboxCreate(e); } else if (context.u == 5) { EsTextDisplayCreate(e); } } void InspectorAddElement(EsInstance *, EsElement *element, EsCommand *) { EsMenu *menu = EsMenuCreate(element, ES_FLAGS_DEFAULT); EsMenuAddItem(menu, 0, "Add button", -1, InspectorAddElement2, element->userData.u | 1); EsMenuAddItem(menu, 0, "Add panel", -1, InspectorAddElement2, element->userData.u | 2); EsMenuAddItem(menu, 0, "Add spacer", -1, InspectorAddElement2, element->userData.u | 3); EsMenuAddItem(menu, 0, "Add textbox", -1, InspectorAddElement2, element->userData.u | 4); EsMenuAddItem(menu, 0, "Add text display", -1, InspectorAddElement2, element->userData.u | 5); EsMenuShow(menu); } void InspectorSetup(EsWindow *window) { InspectorWindow *inspector = (InspectorWindow *) EsHeapAllocate(sizeof(InspectorWindow), true); // TODO Freeing this. inspector->window = window; InstanceSetup(inspector); EsInstanceOpenReference(inspector); inspector->instance = window->instance; window->instance = inspector; inspector->selectedElement = -1; EsSplitter *splitter = EsSplitterCreate(window, ES_CELL_FILL | ES_SPLITTER_VERTICAL); EsPanel *panel1 = EsPanelCreate(splitter, ES_CELL_FILL, ES_STYLE_PANEL_FILLED); EsPanel *panel2 = EsPanelCreate(splitter, ES_CELL_FILL, ES_STYLE_PANEL_FILLED); { EsPanel *toolbar = EsPanelCreate(panel1, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL, ES_STYLE_PANEL_TOOLBAR); inspector->visualizeRepaints = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR, 0, "Visualize repaints"); EsButtonOnCommand(inspector->visualizeRepaints, InspectorVisualizeRepaints); inspector->visualizeLayoutBounds = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR, 0, "Visualize layout bounds"); EsButtonOnCommand(inspector->visualizeLayoutBounds, InspectorVisualizeLayoutBounds); inspector->visualizePaintSteps = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR, 0, "Visualize paint steps"); EsButtonOnCommand(inspector->visualizePaintSteps, InspectorVisualizePaintSteps); EsSpacerCreate(toolbar, ES_CELL_H_FILL); } inspector->elementList = EsListViewCreate(panel1, ES_CELL_FILL | ES_LIST_VIEW_COLUMNS | ES_LIST_VIEW_SINGLE_SELECT); inspector->elementList->messageUser = InspectorElementListCallback; EsListViewRegisterColumn(inspector->elementList, 0, "Name", -1, 0, 300); EsListViewRegisterColumn(inspector->elementList, 1, "Bounds", -1, 0, 200); EsListViewRegisterColumn(inspector->elementList, 2, "Information", -1, 0, 200); EsListViewAddAllColumns(inspector->elementList); EsListViewInsertGroup(inspector->elementList, 0); { EsPanel *toolbar = EsPanelCreate(panel1, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL, ES_STYLE_PANEL_TOOLBAR); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); EsTextDisplayCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Horizontal:"); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); inspector->alignH[0] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignH[0], ES_ICON_ALIGN_HORIZONTAL_LEFT); EsButtonOnCommand(inspector->alignH[0], InspectorHAlignLeft); inspector->alignH[1] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignH[1], ES_ICON_ALIGN_HORIZONTAL_CENTER); EsButtonOnCommand(inspector->alignH[1], InspectorHAlignCenter); inspector->alignH[2] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignH[2], ES_ICON_ALIGN_HORIZONTAL_RIGHT); EsButtonOnCommand(inspector->alignH[2], InspectorHAlignRight); inspector->alignH[3] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Expand"); EsButtonOnCommand(inspector->alignH[3], InspectorHAlignExpand); inspector->alignH[4] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Shrink"); EsButtonOnCommand(inspector->alignH[4], InspectorHAlignShrink); inspector->alignH[5] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Push"); EsButtonOnCommand(inspector->alignH[5], InspectorHAlignPush); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); EsTextDisplayCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Vertical:"); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); inspector->alignV[0] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignV[0], ES_ICON_ALIGN_VERTICAL_TOP); EsButtonOnCommand(inspector->alignV[0], InspectorVAlignTop); inspector->alignV[1] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignV[1], ES_ICON_ALIGN_VERTICAL_CENTER); EsButtonOnCommand(inspector->alignV[1], InspectorVAlignCenter); inspector->alignV[2] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->alignV[2], ES_ICON_ALIGN_VERTICAL_BOTTOM); EsButtonOnCommand(inspector->alignV[2], InspectorVAlignBottom); inspector->alignV[3] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Expand"); EsButtonOnCommand(inspector->alignV[3], InspectorVAlignExpand); inspector->alignV[4] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Shrink"); EsButtonOnCommand(inspector->alignV[4], InspectorVAlignShrink); inspector->alignV[5] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED, 0, "Push"); EsButtonOnCommand(inspector->alignV[5], InspectorVAlignPush); } { EsPanel *toolbar = EsPanelCreate(panel1, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL, ES_STYLE_PANEL_TOOLBAR); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); EsTextDisplayCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Stack:"); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); inspector->direction[0] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->direction[0], ES_ICON_GO_PREVIOUS); EsButtonOnCommand(inspector->direction[0], InspectorDirectionLeft); inspector->direction[1] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->direction[1], ES_ICON_GO_NEXT); EsButtonOnCommand(inspector->direction[1], InspectorDirectionRight); inspector->direction[2] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->direction[2], ES_ICON_GO_UP); EsButtonOnCommand(inspector->direction[2], InspectorDirectionUp); inspector->direction[3] = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_ELEMENT_DISABLED); EsButtonSetIcon(inspector->direction[3], ES_ICON_GO_DOWN); EsButtonOnCommand(inspector->direction[3], InspectorDirectionDown); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 25, 0); inspector->addChildButton = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_BUTTON_DROPDOWN | ES_ELEMENT_DISABLED | ES_BUTTON_COMPACT, 0, "Add child... "); EsButtonOnCommand(inspector->addChildButton, InspectorAddElement); inspector->addSiblingButton = EsButtonCreate(toolbar, ES_BUTTON_TOOLBAR | ES_BUTTON_DROPDOWN | ES_ELEMENT_DISABLED | ES_BUTTON_COMPACT, 0, "Add sibling... "); inspector->addSiblingButton->userData.i = 0x80; EsButtonOnCommand(inspector->addSiblingButton, InspectorAddElement); } { EsPanel *toolbar = EsPanelCreate(panel1, ES_CELL_H_FILL | ES_PANEL_HORIZONTAL, ES_STYLE_PANEL_TOOLBAR); EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 5, 0); EsTextDisplayCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Content:"); inspector->contentTextbox = EsTextboxCreate(toolbar, ES_ELEMENT_DISABLED | ES_TEXTBOX_EDIT_BASED); inspector->contentTextbox->messageUser = InspectorContentTextboxCallback; EsSpacerCreate(toolbar, ES_FLAGS_DEFAULT, 0, 25, 0); EsTextDisplayCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Event category filter:"); inspector->textboxCategoryFilter = EsTextboxCreate(toolbar, ES_ELEMENT_DISABLED); inspector->textboxCategoryFilter->messageUser = InspectorTextboxCategoryFilterCallback; } { inspector->listEvents = EsListViewCreate(panel2, ES_CELL_FILL | ES_LIST_VIEW_CHOICE_SELECT | ES_LIST_VIEW_FIXED_ITEMS, ES_STYLE_LIST_CHOICE_BORDERED); } InspectorRefreshElementList(inspector); APIInstance *instance = (APIInstance *) inspector->instance->_private; instance->attachedInspector = inspector; }