void ExpandTree::pack(const pixel2& pos, const pixel2& dims,
		const double2& dpmm, double pixelRatio, bool clamp) {
		update(AlloyApplicationContext().get());
		drawRegion->dimensions = CoordPX(
			aly::max(getBounds().dimensions,
				root.getBounds().dimensions
				+ pixel2(Composite::scrollBarSize)));
		Composite::pack(pos, dims, dpmm, pixelRatio, clamp);
	}
std::shared_ptr<Composite>& AlloyContext::getGlassPane() {
	if (glassPane.get() == nullptr) {
		glassPane = std::shared_ptr<Composite>(
				new Composite("Glass Pane", CoordPX(0, 0),
						CoordPercent(1.0f, 1.0f)));
		glassPane->backgroundColor = MakeColor(
				theme.DARKEST.toSemiTransparent(0.5f));
	}
	return glassPane;
}
	ExpandTree::ExpandTree(const std::string& name, const AUnit2D& pos,
		const AUnit2D& dims) :
		Composite(name, pos, dims), selectedItem(nullptr), dirty(true) {
		setScrollEnabled(true);
		setAlwaysShowVerticalScrollBar(true);
		drawRegion = DrawPtr(
			new Draw("Tree Region", CoordPX(0.0f, 0.0f),
				CoordPercent(1.0f, 1.0f)));
		drawRegion->onDraw = [this](AlloyContext* context, const box2px& bounds) {
			root.draw(this, context, bounds.position);
		};
		drawRegion->onMouseOver =
			[this](AlloyContext* context, const InputEvent& e) {
			box2px box = drawRegion->getBounds();
			overArrow = false;
			selectedItem = root.locate(context, e.cursor - box.position,overArrow);
			return false;
		};
		drawRegion->onMouseDown =
			[this](AlloyContext* context, const InputEvent& e) {
			if (e.button == GLFW_MOUSE_BUTTON_LEFT) {
				if (selectedItem != nullptr) {
					if ((isOverArrow()|| !selectedItem->onSelect)&&(selectedItem->onExpand || selectedItem->hasChildren())) {
						selectedItem->setExpanded(!selectedItem->isExpanded());
					}
					else {
						if (selectedItem->onSelect) {
							selectedItem->onSelect(selectedItem, e);
						}
					}
					setDirty(true);
					update(context);
					return true;
				}
			}
			return false;
		};
		Composite::add(drawRegion);
	}
void Application::run(int swapInterval) {
    const double POLL_INTERVAL_SEC = 0.5f;

    context->makeCurrent();
    if (!init(rootRegion)) {
        throw std::runtime_error("Error occurred in application init()");
    }
    rootRegion.add(getContext()->getGlassPane());
    if (showDebugIcon) {
        GlyphRegionPtr debug = MakeGlyphRegion(
                                   createAwesomeGlyph(0xf188, FontStyle::Outline, 20),
                                   CoordPercent(1.0f, 1.0f), CoordPX(20, 20), RGBA(0, 0, 0, 0),
                                   RGBA(64, 64, 64, 128), RGBA(192, 192, 192, 128), UnitPX(0));

        debug->setOrigin(Origin::BottomRight);
        debug->onMouseDown =
        [this,debug](AlloyContext* context,const InputEvent& e) {
            if(e.button==GLFW_MOUSE_BUTTON_LEFT) {
                context->toggleDebug();
                debug->foregroundColor=context->isDebugEnabled()?MakeColor(255,64,64,255):MakeColor(64,64,64,128);
                context->setMouseFocusObject(nullptr);
                return true;
            }
            return false;
        };
        rootRegion.add(debug);
    }

    //First pack triggers computation of aspect ratios  for components.
    rootRegion.pack(context.get());
    context->getGlassPane()->setVisible(false);
    context->requestPack();
    glfwSwapInterval(swapInterval);
    glfwSetTime(0);
    uint64_t frameCounter = 0;
    std::chrono::steady_clock::time_point endTime;
    std::chrono::steady_clock::time_point lastFpsTime =
        std::chrono::steady_clock::now();
    if (!forceClose) {
        glfwShowWindow(context->window);
    } else {
        context->executeDeferredTasks();
        context->dirtyUI = true;
        context->dirtyLayout = true;
        draw();
        context->dirtyUI = true;
        context->dirtyLayout = true;
        context->update(rootRegion);
    }
    do {
        //Events could have modified layout! Pack before draw to make sure things are correctly positioned.
        if (context->dirtyLayout) {
            context->dirtyLayout = false;
            context->dirtyCursorLocator = true;
            rootRegion.pack();
        }
        draw();
        context->update(rootRegion);
        double elapsed =
            std::chrono::duration<double>(endTime - lastFpsTime).count();
        frameCounter++;
        if (elapsed > POLL_INTERVAL_SEC) {
            frameRate = (float) (frameCounter / elapsed);
            lastFpsTime = endTime;
            frameCounter = 0;
        }
        glfwSwapBuffers(context->window);
        glfwPollEvents();
        for (std::exception_ptr e : caughtExceptions) {
            std::rethrow_exception(e);
        }
        if (glfwWindowShouldClose(context->offscreenWindow)) {
            context->setOffScreenVisible(false);
        }
    } while (!glfwWindowShouldClose(context->window) && !forceClose);
}