diff --git a/packages/core/src/Core.ts b/packages/core/src/Core.ts index f42ba179..c4b0c5cb 100644 --- a/packages/core/src/Core.ts +++ b/packages/core/src/Core.ts @@ -213,6 +213,7 @@ export class Core { ); this._debugManager = this._serviceContainer.resolve(DebugManager); + this._debugManager.onInitialize(); } this.initialize(); @@ -488,6 +489,7 @@ export class Core { ); this._instance._debugManager = this._instance._serviceContainer.resolve(DebugManager); + this._instance._debugManager.onInitialize(); } // 更新Core配置 diff --git a/packages/core/src/Core/DI/Decorators.ts b/packages/core/src/Core/DI/Decorators.ts index e25d8703..29996e30 100644 --- a/packages/core/src/Core/DI/Decorators.ts +++ b/packages/core/src/Core/DI/Decorators.ts @@ -1,7 +1,7 @@ /** * 依赖注入装饰器 * - * 提供 @Injectable、@Inject 和 @Updatable 装饰器,用于标记可注入的类和依赖注入点 + * 提供 @Injectable、@InjectProperty 和 @Updatable 装饰器,用于标记可注入的类和依赖注入点 */ import type { ServiceContainer } from '../ServiceContainer'; @@ -13,7 +13,6 @@ import type { IService, ServiceType } from '../ServiceContainer'; type Constructor = abstract new (...args: unknown[]) => unknown; const injectableMetadata = new WeakMap(); -const injectMetadata = new WeakMap | string | symbol>>(); const updatableMetadata = new WeakMap(); /** @@ -67,10 +66,11 @@ export interface UpdatableMetadata { * * @Injectable() * class PhysicsSystem extends EntitySystem { - * constructor( - * @Inject(TimeService) private timeService: TimeService - * ) { - * super(); + * @InjectProperty(TimeService) + * private timeService!: TimeService; + * + * constructor() { + * super(Matcher.empty()); * } * } * ``` @@ -135,27 +135,6 @@ export function Updatable(priority: number = 0): ClassDecorator { } as ClassDecorator; } -/** - * @Inject() 装饰器 - * - * 标记构造函数参数需要注入的服务类型 - * - * @param serviceType 服务类型标识符 - */ -export function Inject(serviceType: ServiceType | string | symbol): ParameterDecorator { - return function (target: object, _propertyKey: string | symbol | undefined, parameterIndex: number) { - // 获取或创建注入元数据 - let params = injectMetadata.get(target as Constructor); - if (!params) { - params = new Map(); - injectMetadata.set(target as Constructor, params); - } - - // 记录参数索引和服务类型的映射 - params.set(parameterIndex, serviceType); - }; -} - /** * @InjectProperty() 装饰器 * @@ -164,6 +143,27 @@ export function Inject(serviceType: ServiceType | string | symbol): Pa * 注入时机:在构造函数执行后、onInitialize() 调用前完成 * * @param serviceType 服务类型 + * + * @example + * ```typescript + * @Injectable() + * class PhysicsSystem extends EntitySystem { + * @InjectProperty(TimeService) + * private timeService!: TimeService; + * + * @InjectProperty(CollisionService) + * private collision!: CollisionService; + * + * constructor() { + * super(Matcher.empty()); + * } + * + * public onInitialize(): void { + * // 此时属性已注入完成,可以安全使用 + * console.log(this.timeService.getDeltaTime()); + * } + * } + * ``` */ export function InjectProperty(serviceType: ServiceType): PropertyDecorator { return function (target: object, propertyKey: string | symbol) { @@ -207,13 +207,14 @@ export function getInjectableMetadata(target: Constructor): InjectableMetadata | } /** - * 获取构造函数参数的注入元数据 + * 获取属性注入元数据 * * @param target 目标类 - * @returns 参数索引到服务类型的映射 + * @returns 属性名到服务类型的映射 */ -export function getInjectMetadata(target: Constructor): Map | string | symbol> { - return injectMetadata.get(target) || new Map(); +export function getPropertyInjectMetadata(target: Constructor): Map> { + const metadata = injectableMetadata.get(target); + return metadata?.properties || new Map(); } /** @@ -232,38 +233,13 @@ export function createInstance( constructor: new (...args: any[]) => T, container: ServiceContainer ): T { - // 获取参数注入元数据 - const injectParams = getInjectMetadata(constructor as Constructor); + // 创建实例(无参数注入) + const instance = new constructor(); - // 解析依赖 - const dependencies: unknown[] = []; + // 注入属性依赖 + injectProperties(instance as object, container); - // 获取构造函数参数数量 - const paramCount = constructor.length; - - for (let i = 0; i < paramCount; i++) { - const serviceType = injectParams.get(i); - - if (serviceType) { - // 如果有显式的@Inject标记,使用标记的类型 - if (typeof serviceType === 'string' || typeof serviceType === 'symbol') { - // 字符串或Symbol类型的服务标识 - throw new Error( - 'String and Symbol service identifiers are not yet supported in constructor injection. ' + - `Please use class types for ${constructor.name} parameter ${i}` - ); - } else { - // 类类型 - dependencies.push(container.resolve(serviceType as ServiceType)); - } - } else { - // 没有@Inject标记,传入undefined - dependencies.push(undefined); - } - } - - // 创建实例 - return new constructor(...dependencies); + return instance; } /** diff --git a/packages/core/src/Core/DI/index.ts b/packages/core/src/Core/DI/index.ts index 43803bd9..5a1040a3 100644 --- a/packages/core/src/Core/DI/index.ts +++ b/packages/core/src/Core/DI/index.ts @@ -6,12 +6,11 @@ export { Injectable, - Inject, InjectProperty, Updatable, isInjectable, getInjectableMetadata, - getInjectMetadata, + getPropertyInjectMetadata, isUpdatable, getUpdatableMetadata, createInstance, diff --git a/packages/core/src/ECS/Decorators/TypeDecorators.ts b/packages/core/src/ECS/Decorators/TypeDecorators.ts index 8e59e8e3..caf62177 100644 --- a/packages/core/src/ECS/Decorators/TypeDecorators.ts +++ b/packages/core/src/ECS/Decorators/TypeDecorators.ts @@ -70,11 +70,14 @@ export interface SystemMetadata { * } * } * - * // 配置更新顺序 + * // 配置更新顺序和依赖注入 * @Injectable() * @ECSSystem('Physics', { updateOrder: 10 }) * class PhysicsSystem extends EntitySystem { - * constructor(@Inject(CollisionSystem) private collision: CollisionSystem) { + * @InjectProperty(CollisionSystem) + * private collision!: CollisionSystem; + * + * constructor() { * super(Matcher.empty().all(Transform, RigidBody)); * } * } diff --git a/packages/core/src/ECS/Scene.ts b/packages/core/src/ECS/Scene.ts index b85b1fe9..fb1a1a1b 100644 --- a/packages/core/src/ECS/Scene.ts +++ b/packages/core/src/ECS/Scene.ts @@ -612,7 +612,7 @@ export class Scene implements IScene { * 在场景中添加一个EntitySystem处理器 * * 支持两种使用方式: - * 1. 传入类型(推荐):自动使用DI创建实例,支持@Injectable和@Inject装饰器 + * 1. 传入类型(推荐):自动使用DI创建实例,支持@Injectable和@InjectProperty装饰器 * 2. 传入实例:直接使用提供的实例 * * @param systemTypeOrInstance 系统类型或系统实例 @@ -623,7 +623,10 @@ export class Scene implements IScene { * // 方式1:传入类型,自动DI(推荐) * @Injectable() * class PhysicsSystem extends EntitySystem { - * constructor(@Inject(CollisionSystem) private collision: CollisionSystem) { + * @InjectProperty(CollisionSystem) + * private collision!: CollisionSystem; + * + * constructor() { * super(Matcher.empty().all(Transform)); * } * } @@ -718,7 +721,10 @@ export class Scene implements IScene { * @Injectable() * @ECSSystem('Physics', { updateOrder: 10 }) * class PhysicsSystem extends EntitySystem implements IService { - * constructor(@Inject(CollisionSystem) private collision: CollisionSystem) { + * @InjectProperty(CollisionSystem) + * private collision!: CollisionSystem; + * + * constructor() { * super(Matcher.empty().all(Transform, RigidBody)); * } * dispose() {} @@ -779,7 +785,7 @@ export class Scene implements IScene { /** * 获取指定类型的EntitySystem处理器 * - * @deprecated 推荐使用依赖注入代替此方法。使用 `scene.services.resolve(SystemType)` 或在System构造函数中使用 `@Inject(SystemType)` 装饰器。 + * @deprecated 推荐使用依赖注入代替此方法。使用 `scene.services.resolve(SystemType)` 或使用 `@InjectProperty(SystemType)` 装饰器。 * * @param type 处理器类型 * @returns 处理器实例,如果未找到则返回null @@ -788,8 +794,11 @@ export class Scene implements IScene { * ```typescript * @Injectable() * class MySystem extends EntitySystem { - * constructor(@Inject(PhysicsSystem) private physics: PhysicsSystem) { - * super(); + * @InjectProperty(PhysicsSystem) + * private physics!: PhysicsSystem; + * + * constructor() { + * super(Matcher.empty()); * } * } * ``` diff --git a/packages/core/src/Utils/Debug/DebugManager.ts b/packages/core/src/Utils/Debug/DebugManager.ts index d4772615..226c5c0d 100644 --- a/packages/core/src/Utils/Debug/DebugManager.ts +++ b/packages/core/src/Utils/Debug/DebugManager.ts @@ -13,7 +13,7 @@ import type { IService } from '../../Core/ServiceContainer'; import type { IUpdatable } from '../../Types/IUpdatable'; import { SceneManager } from '../../ECS/SceneManager'; import { PerformanceMonitor } from '../PerformanceMonitor'; -import { Injectable, Inject, Updatable } from '../../Core/DI/Decorators'; +import { Injectable, InjectProperty, Updatable } from '../../Core/DI/Decorators'; import { DebugConfigService } from './DebugConfigService'; /** @@ -24,19 +24,26 @@ import { DebugConfigService } from './DebugConfigService'; @Injectable() @Updatable() export class DebugManager implements IService, IUpdatable { - private config: IECSDebugConfig; - private webSocketManager: WebSocketManager; - private entityCollector: EntityDataCollector; - private systemCollector: SystemDataCollector; - private performanceCollector: PerformanceDataCollector; - private componentCollector: ComponentDataCollector; - private sceneCollector: SceneDataCollector; - private sceneManager: SceneManager; - private performanceMonitor: PerformanceMonitor; + private config!: IECSDebugConfig; + private webSocketManager!: WebSocketManager; + private entityCollector!: EntityDataCollector; + private systemCollector!: SystemDataCollector; + private performanceCollector!: PerformanceDataCollector; + private componentCollector!: ComponentDataCollector; + private sceneCollector!: SceneDataCollector; + + @InjectProperty(SceneManager) + private sceneManager!: SceneManager; + + @InjectProperty(PerformanceMonitor) + private performanceMonitor!: PerformanceMonitor; + + @InjectProperty(DebugConfigService) + private configService!: DebugConfigService; private frameCounter: number = 0; private lastSendTime: number = 0; - private sendInterval: number; + private sendInterval: number = 0; private isRunning: boolean = false; private originalConsole = { log: console.log.bind(console), @@ -46,14 +53,8 @@ export class DebugManager implements IService, IUpdatable { error: console.error.bind(console) }; - constructor( - @Inject(SceneManager) sceneManager: SceneManager, - @Inject(PerformanceMonitor) performanceMonitor: PerformanceMonitor, - @Inject(DebugConfigService) configService: DebugConfigService - ) { - this.config = configService.getConfig(); - this.sceneManager = sceneManager; - this.performanceMonitor = performanceMonitor; + public onInitialize(): void { + this.config = this.configService.getConfig(); // 初始化数据收集器 this.entityCollector = new EntityDataCollector(); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8f203399..791a6a00 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -19,12 +19,14 @@ export * from './Plugins'; // 依赖注入 export { Injectable, - Inject, + InjectProperty, Updatable, registerInjectable, createInstance, + injectProperties, isUpdatable, - getUpdatableMetadata + getUpdatableMetadata, + getPropertyInjectMetadata } from './Core/DI'; export type { InjectableMetadata, UpdatableMetadata } from './Core/DI'; diff --git a/packages/core/tests/Core/DI.test.ts b/packages/core/tests/Core/DI.test.ts index 1607eb79..35680b9d 100644 --- a/packages/core/tests/Core/DI.test.ts +++ b/packages/core/tests/Core/DI.test.ts @@ -1,4 +1,4 @@ -import { Injectable, Inject, isInjectable, getInjectMetadata, createInstance, registerInjectable } from '../../src/Core/DI'; +import { Injectable, InjectProperty, isInjectable, getPropertyInjectMetadata, createInstance, registerInjectable } from '../../src/Core/DI'; import { ServiceContainer } from '../../src/Core/ServiceContainer'; import type { IService } from '../../src/Core/ServiceContainer'; @@ -14,9 +14,8 @@ class SimpleService implements IService { @Injectable() class DependentService implements IService { - constructor( - @Inject(SimpleService) public simpleService: SimpleService - ) {} + @InjectProperty(SimpleService) + public simpleService!: SimpleService; dispose() { // 清理资源 @@ -25,10 +24,11 @@ class DependentService implements IService { @Injectable() class MultiDependencyService implements IService { - constructor( - @Inject(SimpleService) public service1: SimpleService, - @Inject(DependentService) public service2: DependentService - ) {} + @InjectProperty(SimpleService) + public service1!: SimpleService; + + @InjectProperty(DependentService) + public service2!: DependentService; dispose() { // 清理资源 @@ -58,18 +58,18 @@ describe('DI - 依赖注入装饰器测试', () => { }); }); - describe('@Inject 装饰器', () => { - test('应该记录参数注入元数据', () => { - const metadata = getInjectMetadata(DependentService as any); + describe('@InjectProperty 装饰器', () => { + test('应该记录属性注入元数据', () => { + const metadata = getPropertyInjectMetadata(DependentService as any); expect(metadata.size).toBe(1); - expect(metadata.get(0)).toBe(SimpleService); + expect(metadata.get('simpleService')).toBe(SimpleService); }); - test('应该记录多个参数的注入元数据', () => { - const metadata = getInjectMetadata(MultiDependencyService as any); + test('应该记录多个属性的注入元数据', () => { + const metadata = getPropertyInjectMetadata(MultiDependencyService as any); expect(metadata.size).toBe(2); - expect(metadata.get(0)).toBe(SimpleService); - expect(metadata.get(1)).toBe(DependentService); + expect(metadata.get('service1')).toBe(SimpleService); + expect(metadata.get('service2')).toBe(DependentService); }); }); diff --git a/packages/core/tests/ECS/EntitySystemDI.test.ts b/packages/core/tests/ECS/EntitySystemDI.test.ts index f02802e5..efbd8a58 100644 --- a/packages/core/tests/ECS/EntitySystemDI.test.ts +++ b/packages/core/tests/ECS/EntitySystemDI.test.ts @@ -3,7 +3,7 @@ import { EntitySystem } from '../../src/ECS/Systems/EntitySystem'; import { Entity } from '../../src/ECS/Entity'; import { Component } from '../../src/ECS/Component'; import { Matcher } from '../../src/ECS/Utils/Matcher'; -import { Injectable, Inject, InjectProperty } from '../../src/Core/DI'; +import { Injectable, InjectProperty } from '../../src/Core/DI'; import { Core } from '../../src/Core'; import type { IService } from '../../src/Core/ServiceContainer'; import { ECSSystem } from '../../src/ECS/Decorators'; @@ -82,9 +82,10 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('Physics') class PhysicsSystem extends EntitySystem implements IService { - constructor( - @Inject(CollisionSystem) public collision: CollisionSystem - ) { + @InjectProperty(CollisionSystem) + public collision!: CollisionSystem; + + constructor() { super(Matcher.empty().all(Transform, Velocity)); } @@ -124,7 +125,10 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('B') class SystemB extends EntitySystem implements IService { - constructor(@Inject(SystemA) public systemA: SystemA) { + @InjectProperty(SystemA) + public systemA!: SystemA; + + constructor() { super(Matcher.empty()); } override dispose() {} @@ -133,10 +137,13 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('C') class SystemC extends EntitySystem implements IService { - constructor( - @Inject(SystemA) public systemA: SystemA, - @Inject(SystemB) public systemB: SystemB - ) { + @InjectProperty(SystemA) + public systemA!: SystemA; + + @InjectProperty(SystemB) + public systemB!: SystemB; + + constructor() { super(Matcher.empty()); } override dispose() {} @@ -166,7 +173,10 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('Physics', { updateOrder: 10 }) class PhysicsSystem extends EntitySystem implements IService { - constructor(@Inject(CollisionSystem) public collision: CollisionSystem) { + @InjectProperty(CollisionSystem) + public collision!: CollisionSystem; + + constructor() { super(Matcher.empty().all(Transform, Velocity)); } override dispose() {} @@ -175,7 +185,10 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('Render', { updateOrder: 20 }) class RenderSystem extends EntitySystem implements IService { - constructor(@Inject(PhysicsSystem) public physics: PhysicsSystem) { + @InjectProperty(PhysicsSystem) + public physics!: PhysicsSystem; + + constructor() { super(Matcher.empty().all(Transform)); } override dispose() {} @@ -346,7 +359,7 @@ describe('EntitySystem - 依赖注入测试', () => { }); describe('Issue #76 场景验证', () => { - test('应该消除硬编码依赖,使用构造函数注入', () => { + test('应该消除硬编码依赖,使用属性注入', () => { @Injectable() @ECSSystem('TimeService') class TimeService extends EntitySystem implements IService { @@ -378,10 +391,13 @@ describe('EntitySystem - 依赖注入测试', () => { @Injectable() @ECSSystem('Physics') class PhysicsSystem extends EntitySystem implements IService { - constructor( - @Inject(TimeService) private time: TimeService, - @Inject(CollisionService) private collision: CollisionService - ) { + @InjectProperty(TimeService) + private time!: TimeService; + + @InjectProperty(CollisionService) + private collision!: CollisionService; + + constructor() { super(Matcher.empty().all(Transform, Velocity)); } @@ -544,49 +560,5 @@ describe('EntitySystem - 依赖注入测试', () => { expect(consumer.getInitializeValue()).toBe(42); }); - - test('属性注入可以与构造函数注入混合使用', () => { - @Injectable() - @ECSSystem('A') - class ServiceA extends EntitySystem implements IService { - public valueA = 'A'; - constructor() { - super(Matcher.empty()); - } - override dispose() {} - } - - @Injectable() - @ECSSystem('B') - class ServiceB extends EntitySystem implements IService { - public valueB = 'B'; - constructor() { - super(Matcher.empty()); - } - override dispose() {} - } - - @Injectable() - @ECSSystem('Mixed') - class MixedSystem extends EntitySystem implements IService { - @InjectProperty(ServiceB) - serviceB!: ServiceB; - - constructor(@Inject(ServiceA) public serviceA: ServiceA) { - super(Matcher.empty()); - } - - protected override onInitialize(): void { - expect(this.serviceA).toBeInstanceOf(ServiceA); - expect(this.serviceB).toBeInstanceOf(ServiceB); - expect(this.serviceA.valueA).toBe('A'); - expect(this.serviceB.valueB).toBe('B'); - } - - override dispose() {} - } - - scene.registerSystems([ServiceA, ServiceB, MixedSystem]); - }); }); }); diff --git a/packages/editor-app/src/components/inspectors/common/ComponentItem.tsx b/packages/editor-app/src/components/inspectors/common/ComponentItem.tsx index fc4b24e7..5e774848 100644 --- a/packages/editor-app/src/components/inspectors/common/ComponentItem.tsx +++ b/packages/editor-app/src/components/inspectors/common/ComponentItem.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { ChevronDown, ChevronRight } from 'lucide-react'; +import { ChevronDown, ChevronRight, Settings } from 'lucide-react'; import { PropertyContext, PropertyRendererRegistry } from '@esengine/editor-core'; import { Core } from '@esengine/ecs-framework'; @@ -38,6 +38,7 @@ export function ComponentItem({ component, decimalPlaces = 4 }: ComponentItemPro }} > {isExpanded ? : } + void; readonly?: boolean; -}> = ({ label, value, onChange, readonly }) => ( -
- {label}: + axis: 'x' | 'y' | 'z' | 'w'; +}> = ({ label, value, onChange, readonly, axis }) => ( +
+ {label} onChange(parseFloat(e.target.value) || 0)} disabled={readonly} step={0.1} - style={{ - width: '60px', - padding: '2px 4px', - backgroundColor: '#2a2a2a', - border: '1px solid #444', - borderRadius: '3px', - color: '#e0e0e0', - fontSize: '11px' - }} + className="property-input property-input-number property-input-number-compact" />
); @@ -47,18 +40,20 @@ export class Vector2FieldEditor implements IFieldEditor { return (
-
+
onChange({ ...v, x })} readonly={context.readonly} + axis="x" /> onChange({ ...v, y })} readonly={context.readonly} + axis="y" />
@@ -81,24 +76,27 @@ export class Vector3FieldEditor implements IFieldEditor { return (
-
+
onChange({ ...v, x })} readonly={context.readonly} + axis="x" /> onChange({ ...v, y })} readonly={context.readonly} + axis="y" /> onChange({ ...v, z })} readonly={context.readonly} + axis="z" />
@@ -121,33 +119,37 @@ export class Vector4FieldEditor implements IFieldEditor { return (
-
+
onChange({ ...v, x })} readonly={context.readonly} + axis="x" /> onChange({ ...v, y })} readonly={context.readonly} + axis="y" /> onChange({ ...v, z })} readonly={context.readonly} + axis="z" /> onChange({ ...v, w })} readonly={context.readonly} + axis="w" />
); } -} \ No newline at end of file +} diff --git a/packages/editor-app/src/infrastructure/property-renderers/ComponentRenderer.tsx b/packages/editor-app/src/infrastructure/property-renderers/ComponentRenderer.tsx index 19a1942b..7c67ecc4 100644 --- a/packages/editor-app/src/infrastructure/property-renderers/ComponentRenderer.tsx +++ b/packages/editor-app/src/infrastructure/property-renderers/ComponentRenderer.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { ChevronDown, ChevronRight } from 'lucide-react'; +import { ChevronDown, ChevronRight, Settings } from 'lucide-react'; import { IPropertyRenderer, PropertyContext, PropertyRendererRegistry } from '@esengine/editor-core'; import { Core } from '@esengine/ecs-framework'; @@ -43,6 +43,7 @@ export class ComponentRenderer implements IPropertyRenderer { }} > {isExpanded ? : } + = ({ label, value, axis, decimals }) => ( +
+ {label} + + {formatNumber(value, decimals)} + +
+); + export class Vector2Renderer implements IPropertyRenderer { readonly id = 'app.vector2'; readonly name = 'Vector2 Renderer'; @@ -44,9 +57,10 @@ export class Vector2Renderer implements IPropertyRenderer { return (
- - ({formatNumber(value.x, decimals)}, {formatNumber(value.y, decimals)}) - +
+ + +
); } @@ -74,9 +88,11 @@ export class Vector3Renderer implements IPropertyRenderer { return (
- - ({formatNumber(value.x, decimals)}, {formatNumber(value.y, decimals)}, {formatNumber(value.z, decimals)}) - +
+ + + +
); } @@ -108,21 +124,16 @@ export class ColorRenderer implements IPropertyRenderer { return (
-
+
- - rgba({r}, {g}, {b}, {value.a.toFixed(2)}) + + {colorHex.toUpperCase()}
); } -} \ No newline at end of file +} diff --git a/packages/editor-app/src/styles/FlexLayoutDock.css b/packages/editor-app/src/styles/FlexLayoutDock.css index bf57177b..e7d77fb5 100644 --- a/packages/editor-app/src/styles/FlexLayoutDock.css +++ b/packages/editor-app/src/styles/FlexLayoutDock.css @@ -100,12 +100,20 @@ } .flexlayout__tab_button_content { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 120px; font-size: 12px; font-weight: 400; letter-spacing: 0.3px; } .flexlayout__tab_button--selected .flexlayout__tab_button_content { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 120px; font-weight: 500; } diff --git a/packages/editor-app/src/styles/PropertyInspector.css b/packages/editor-app/src/styles/PropertyInspector.css index 9d9dd913..21062efe 100644 --- a/packages/editor-app/src/styles/PropertyInspector.css +++ b/packages/editor-app/src/styles/PropertyInspector.css @@ -104,9 +104,9 @@ background-repeat: no-repeat; background-position: right 6px center; padding-right: 24px; - appearance: none; -webkit-appearance: none; -moz-appearance: none; + appearance: none; } .property-input-select:hover { @@ -286,10 +286,13 @@ .property-input-number-compact { flex: 1; - min-width: 32px; - text-align: center; - padding: 2px 4px; - font-size: 10px; + min-width: 24px; + max-width: 40px; + text-align: right; + padding: 1px 4px; + font-size: 11px; + height: 18px; + line-height: 16px; } .property-vector-expanded { @@ -338,6 +341,12 @@ border: 1px solid rgba(59, 130, 246, 0.3); } +.property-vector-axis-w { + background: rgba(168, 85, 247, 0.2); + color: #c084fc; + border: 1px solid rgba(168, 85, 247, 0.3); +} + .property-field:focus-within { background: rgba(255, 255, 255, 0.04); } @@ -357,6 +366,7 @@ input[type="number"].property-input { -moz-appearance: textfield; + appearance: textfield; } input[type="number"].property-input::-webkit-outer-spin-button, diff --git a/packages/editor-app/src/styles/SceneHierarchy.css b/packages/editor-app/src/styles/SceneHierarchy.css index 0146c590..e9559837 100644 --- a/packages/editor-app/src/styles/SceneHierarchy.css +++ b/packages/editor-app/src/styles/SceneHierarchy.css @@ -29,6 +29,11 @@ color: var(--color-text-primary); text-transform: uppercase; letter-spacing: 0.05em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 1; + min-width: 0; } .scene-name-container {