diff --git a/Makefile b/Makefile index c6373f369..4e345b451 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ UI_SOURCES := $(wildcard src/interface/*.cpp) UI_OBJS := $(patsubst src/interface/%.cpp,build/obj/ui/%.o,$(UI_SOURCES)) UI_PREREQ := $(patsubst build/obj/ui/%.o,build/obj/ui/%.powder.exe.o,$(UI_OBJS)) -CFLAGS := -Iincludes/ -Idata/ -DWIN32 -OFLAGS := -O3 -ffast-math -ftree-vectorize -funsafe-math-optimizations -fkeep-inline-functions +CFLAGS := -Iincludes/ -Idata/ -DWIN32 -DWINCONSOLE +OFLAGS := #-O3 -ffast-math -ftree-vectorize -funsafe-math-optimizations -fkeep-inline-functions LFLAGS := -lmingw32 -lregex -lws2_32 -lSDLmain -lpthread -lSDL -lm -lbz2 # -mwindows CFLAGS += $(OFLAGS) diff --git a/PowderToy++.files b/PowderToy++.files index 62d6e2aad..f4bdd2f5c 100644 --- a/PowderToy++.files +++ b/PowderToy++.files @@ -124,7 +124,6 @@ C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/interface/Component.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/interface/Panel.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/interface/Sandbox.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/interface/State.cpp -C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/interface/Window.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/Air.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/Graphics.cpp C:/Users/Simon/Projects/FacialTurd-PowderToypp/src/Gravity.cpp @@ -139,3 +138,16 @@ src/GameSession.cpp includes/GameSession.h src/Console.cpp includes/Console.h +includes/interface/Engine.h +includes/interface/Platform.h +src/interface/State.cpp +src/interface/Sandbox.cpp +src/interface/Panel.cpp +src/interface/Engine.cpp +src/interface/ControlFactory.cpp +src/interface/Component.cpp +src/interface/Button.cpp +includes/interface/Point.h +includes/Singleton.h +src/interface/Label.cpp +includes/interface/Label.h diff --git a/includes/Console.h b/includes/Console.h index 806c4db1b..657f93545 100644 --- a/includes/Console.h +++ b/includes/Console.h @@ -12,29 +12,33 @@ class ConsoleCommand private: std::string * command; int returnStatus; - std::string * error; + std::string * returnString; public: void SetCommand(std::string * command); void SetError(std::string * error); std::string * GetCommand(); std::string * GetError(); ConsoleCommand(); - ConsoleCommand(std::string * command, int returnStatus, std::string * error = new std::string("")); + ConsoleCommand(std::string * command, int returnStatus, std::string * returnString = new std::string("")); }; class Console { private: + bool sound_enable; + bool file_script; std::vector * previousCommands; std::string * lastError; ui::Sandbox * sandbox; Simulation * sim; public: virtual void Tick(float * dt); - int ParseType(std::string * type); + int ParseType(char * txt); + int ParsePartref(char * txt); + int ParseCoords(char * coords, int *x, int *y); virtual void ConsoleShown(); virtual void ConsoleHidden(); - virtual int ProcessCommand(std::string * command); + virtual int ProcessCommand(char * console); virtual std::string * GetLastError(); virtual std::vector * GetPreviousCommands(); Console(ui::Sandbox * sandbox); diff --git a/includes/Singleton.h b/includes/Singleton.h new file mode 100644 index 000000000..6b2214eb3 --- /dev/null +++ b/includes/Singleton.h @@ -0,0 +1,16 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + +template + +class Singleton +{ +public: + static T& Ref() + { + static T instance; + return instance; + } +}; + +#endif // SINGLETON_H diff --git a/includes/interface.old/Button.h b/includes/interface.old/Button.h new file mode 100644 index 000000000..1b2900e29 --- /dev/null +++ b/includes/interface.old/Button.h @@ -0,0 +1,42 @@ +/* + * Button.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef BUTTON_H_ +#define BUTTON_H_ + +#include + +#include "Component.h" + +namespace ui +{ + class Button : public Component + { + public: + Button(int x, int y, int width, int height, const std::string& buttonText); + + bool Toggleable; + + std::string ButtonText; + + virtual void OnMouseClick(int x, int y, unsigned int button); + virtual void OnMouseUnclick(int x, int y, unsigned int button); + virtual void OnMouseUp(int x, int y, unsigned int button); + + virtual void OnMouseEnter(int x, int y, int dx, int dy); + virtual void OnMouseLeave(int x, int y, int dx, int dy); + + virtual void Draw(void* userdata); + + inline bool GetState() { return state; } + virtual void DoAction(); //action of button what ever it may be + + protected: + bool isButtonDown, state, isMouseInside; + }; +} +#endif /* BUTTON_H_ */ diff --git a/includes/interface.old/Component.h b/includes/interface.old/Component.h new file mode 100644 index 000000000..a4d02dbc7 --- /dev/null +++ b/includes/interface.old/Component.h @@ -0,0 +1,53 @@ +/* + * Component.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef COMPONENT_H_ +#define COMPONENT_H_ + +namespace ui +{ + class State; + + class Component + { + public: + Component(int x, int y, int width, int height); + virtual ~Component(); + + inline void LocalizePoint(int& x, int& y) { x -= X; y -= Y; } //convert a global point (point on the state) to a point based on component's position + inline void GlobalizePoint(int& x, int& y) { x += X; y += Y; } //convert a local point based on component's position to a global point on the state + + bool Focused; + bool Visible; + bool Enabled; + int Width; + int Height; + int X; + int Y; + + virtual void Tick(float dt); + virtual void Draw(void* userdata); + + virtual void OnMouseEnter(int localx, int localy, int dx, int dy); + virtual void OnMouseLeave(int localx, int localy, int dx, int dy); + virtual void OnMouseMoved(int localx, int localy, int dx, int dy); + virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); + virtual void OnMouseHover(int localx, int localy); + virtual void OnMouseDown(int localx, int localy, unsigned int button); + virtual void OnMouseUp(int localx, int localy, unsigned int button); + virtual void OnMouseClick(int localx, int localy, unsigned int button); + virtual void OnMouseUnclick(int localx, int localy, unsigned int button); + virtual void OnMouseWheel(int localx, int localy, int d); + virtual void OnMouseWheelInside(int localx, int localy, int d); + virtual void OnMouseWheelFocused(int localx, int localy, int d); + virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + + State* Parent; + }; +} +#endif /* COMPONENT_H_ */ diff --git a/includes/interface.old/ControlFactory.h b/includes/interface.old/ControlFactory.h new file mode 100644 index 000000000..8bfd7806a --- /dev/null +++ b/includes/interface.old/ControlFactory.h @@ -0,0 +1,15 @@ +#ifndef CONTROLFACTORY_H +#define CONTROLFACTORY_H + +#include "Panel.h" +#include "Window.h" +#include "GameSession.h" + +class ControlFactory +{ +public: + static ui::Panel * MainMenu(GameSession * session, int x, int y, int width, int height); + +}; + +#endif // CONTROLFACTORY_H diff --git a/includes/interface.old/Panel.h b/includes/interface.old/Panel.h new file mode 100644 index 000000000..9549ff4ac --- /dev/null +++ b/includes/interface.old/Panel.h @@ -0,0 +1,22 @@ +/* + * Panel.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef PANEL_H_ +#define PANEL_H_ + +#include "interface/Component.h" + +namespace ui { + +class Panel: public ui::Component { +public: + Panel(int x, int y, int width, int height); + virtual ~Panel(); +}; + +} /* namespace ui */ +#endif /* PANEL_H_ */ diff --git a/includes/interface.old/Sandbox.h b/includes/interface.old/Sandbox.h new file mode 100644 index 000000000..32a047127 --- /dev/null +++ b/includes/interface.old/Sandbox.h @@ -0,0 +1,36 @@ +/* + * Sandbox.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef SANDBOX_H_ +#define SANDBOX_H_ + +#include "Component.h" +#include "Simulation.h" +#include "Renderer.h" + +namespace ui { + +class Sandbox: public ui::Component { +private: + int lastCoordX, lastCoordY; + int activeElement; + bool isMouseDown; + Renderer * ren; + Simulation * sim; +public: + Sandbox(); + virtual Simulation * GetSimulation(); + virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); + virtual void OnMouseDown(int localx, int localy, unsigned int button); + virtual void OnMouseUp(int localx, int localy, unsigned int button); + virtual void Draw(void* userdata); + virtual void Tick(float delta); + virtual ~Sandbox(); +}; + +} /* namespace ui */ +#endif /* SANDBOX_H_ */ diff --git a/includes/interface.old/State.h b/includes/interface.old/State.h new file mode 100644 index 000000000..00df19916 --- /dev/null +++ b/includes/interface.old/State.h @@ -0,0 +1,61 @@ +/* + * State.h + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#ifndef STATE_H_ +#define STATE_H_ + +#include + +#include "interface/Component.h" + +namespace ui { + +class State +{ +public: + State(int w, int h); + virtual ~State(); + + bool AllowExclusiveDrawing; //false will not call draw on objects outside of bounds + + virtual void Tick(float dt); + virtual void Draw(void* userdata); + + virtual void OnMouseMove(int x, int y); + virtual void OnMouseDown(int x, int y, unsigned int button); + virtual void OnMouseUp(int x, int y, unsigned int button); + virtual void OnMouseWheel(int x, int y, int d); + virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + + virtual void Add(Component *child); + virtual void Remove(Component *child); + + inline bool IsFocused(Component* c) { return (c == focusedComponent_); } + inline int GetMouseX() { return mouseX; } + inline int GetMouseY() { return mouseY; } + inline int GetWidth() { return width; } + inline int GetHeight() { return height; } + +protected: + std::vector Components; + + int width; + int height; + + int mouseX; + int mouseY; + int mouseXP; + int mouseYP; + +private: + Component* focusedComponent_; + +}; + +} /* namespace ui */ +#endif /* STATE_H_ */ diff --git a/includes/interface/Window.h b/includes/interface.old/Window.h similarity index 100% rename from includes/interface/Window.h rename to includes/interface.old/Window.h diff --git a/includes/interface/Button.h b/includes/interface/Button.h index 1b2900e29..86688cf2a 100644 --- a/includes/interface/Button.h +++ b/includes/interface/Button.h @@ -17,7 +17,12 @@ namespace ui class Button : public Component { public: - Button(int x, int y, int width, int height, const std::string& buttonText); + Button(State* parent_state, std::string buttonText); + + Button(Point position, Point size, std::string buttonText); + + Button(std::string buttonText); + virtual ~Button(); bool Toggleable; @@ -25,12 +30,12 @@ namespace ui virtual void OnMouseClick(int x, int y, unsigned int button); virtual void OnMouseUnclick(int x, int y, unsigned int button); - virtual void OnMouseUp(int x, int y, unsigned int button); + //virtual void OnMouseUp(int x, int y, unsigned int button); - virtual void OnMouseEnter(int x, int y, int dx, int dy); - virtual void OnMouseLeave(int x, int y, int dx, int dy); + virtual void OnMouseEnter(int x, int y); + virtual void OnMouseLeave(int x, int y); - virtual void Draw(void* userdata); + virtual void Draw(const Point& screenPos); inline bool GetState() { return state; } virtual void DoAction(); //action of button what ever it may be diff --git a/includes/interface/Component.h b/includes/interface/Component.h index a4d02dbc7..5759c082e 100644 --- a/includes/interface/Component.h +++ b/includes/interface/Component.h @@ -1,53 +1,204 @@ -/* - * Component.h - * - * Created on: Jan 8, 2012 - * Author: Simon - */ +#pragma once -#ifndef COMPONENT_H_ -#define COMPONENT_H_ +#include "Point.h" +#include "State.h" +#include "Platform.h" namespace ui { - class State; - - class Component + class State; + class Panel; + + /* class Component + * + * An interactive UI component that can be added to a state or an XComponent*. + * *See sys::XComponent + */ + class Component { public: - Component(int x, int y, int width, int height); + Component(State* parent_state); + Component(Point position, Point size); + Component(); virtual ~Component(); + + void* UserData; + inline State* const GetParentState() const { return parentstate_; } + bool IsFocused() const; - inline void LocalizePoint(int& x, int& y) { x -= X; y -= Y; } //convert a global point (point on the state) to a point based on component's position - inline void GlobalizePoint(int& x, int& y) { x += X; y += Y; } //convert a local point based on component's position to a global point on the state - - bool Focused; + Point Position; + Point Size; + bool Locked; bool Visible; - bool Enabled; - int Width; - int Height; - int X; - int Y; + /* See the parent of this component. + * If new_parent is NULL, this component will have no parent. (THIS DOES NOT delete THE COMPONENT. See XComponent::RemoveChild) + */ + void SetParentState(State* state); + void SetParent(Panel* new_parent); + + //Get the parent component. + inline Panel* const GetParent() const { return _parent; } + + //UI functions: + /* + void Tick(float dt); + void Draw(const Point& screenPos); + + void OnMouseHover(int localx, int localy); + void OnMouseMoved(int localx, int localy, int dx, int dy); + void OnMouseMovedInside(int localx, int localy, int dx, int dy); + void OnMouseEnter(int localx, int localy); + void OnMouseLeave(int localx, int localy); + void OnMouseDown(int x, int y, unsigned int button); + void OnMouseUp(int x, int y, unsigned int button); + void OnMouseClick(int localx, int localy, unsigned int button); + void OnMouseUnclick(int localx, int localy, unsigned int button); + void OnMouseWheel(int localx, int localy, int d); + void OnMouseWheelInside(int localx, int localy, int d); + void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + */ + + /// + // Called: Every tick. + // Params: + // dt: The change in time. + /// virtual void Tick(float dt); - virtual void Draw(void* userdata); - - virtual void OnMouseEnter(int localx, int localy, int dx, int dy); - virtual void OnMouseLeave(int localx, int localy, int dx, int dy); - virtual void OnMouseMoved(int localx, int localy, int dx, int dy); - virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); + + /// + // Called: When ready to draw. + // Params: + // None + /// + virtual void Draw(const Point& screenPos); + + + + + /// + // Called: When the mouse is currently hovering over the item. (Called every tick) + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + /// virtual void OnMouseHover(int localx, int localy); - virtual void OnMouseDown(int localx, int localy, unsigned int button); - virtual void OnMouseUp(int localx, int localy, unsigned int button); - virtual void OnMouseClick(int localx, int localy, unsigned int button); - virtual void OnMouseUnclick(int localx, int localy, unsigned int button); + + /// + // Called: When the mouse moves. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseMoved(int localx, int localy, int dx, int dy); + + /// + // Called: When the mouse moves. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); + + /// + // Called: When the mouse moves on top of the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // dx: Mouse X delta. + // dy: Mouse Y delta. + /// + virtual void OnMouseEnter(int localx, int localy); + + /// + // Called: When the mouse leaves the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + /// + virtual void OnMouseLeave(int localx, int localy); + + /// + // Called: When a mouse button is pressed. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being held down. + /// + virtual void OnMouseDown(int x, int y, unsigned button); + + /// + // Called: When a mouse button is released. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being released. + /// + virtual void OnMouseUp(int x, int y, unsigned button); + + /// + // Called: When a mouse button is pressed on top of the item. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being held down. + /// + virtual void OnMouseClick(int localx, int localy, unsigned button); + + /// + // Called: When a mouse button is released on top of the item. + // Params: + // x: X position of the mouse. + // y: Y position of the mouse. + // button: The button that is being released. + /// + virtual void OnMouseUnclick(int localx, int localy, unsigned button); + + /// + // Called: When the mouse wheel moves/changes. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // d: The mouse wheel movement value. + /// virtual void OnMouseWheel(int localx, int localy, int d); + + /// + // Called: When the mouse wheel moves/changes on top of the item. + // Params: + // localx: Local mouse X position. + // localy: Local mouse Y position. + // d: The mouse wheel movement value. + /// virtual void OnMouseWheelInside(int localx, int localy, int d); - virtual void OnMouseWheelFocused(int localx, int localy, int d); + + /// + // Called: When a key is pressed. + // Params: + // key: The value of the key that is being pressed. + // shift: Shift key is down. + // ctrl: Control key is down. + // alt: Alternate key is down. + /// virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + + /// + // Called: When a key is released. + // Params: + // key: The value of the key that is being released. + // shift: Shift key is released. + // ctrl: Control key is released. + // alt: Alternate key is released. + /// virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); - State* Parent; + private: + State* parentstate_; + Panel* _parent; }; } -#endif /* COMPONENT_H_ */ diff --git a/includes/interface/ControlFactory.h b/includes/interface/ControlFactory.h index 8bfd7806a..ba5f43bf5 100644 --- a/includes/interface/ControlFactory.h +++ b/includes/interface/ControlFactory.h @@ -2,7 +2,7 @@ #define CONTROLFACTORY_H #include "Panel.h" -#include "Window.h" +#include "Engine.h" #include "GameSession.h" class ControlFactory diff --git a/includes/interface/Engine.h b/includes/interface/Engine.h new file mode 100644 index 000000000..682a09d47 --- /dev/null +++ b/includes/interface/Engine.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include "Singleton.h" +#include "Platform.h" +#include "State.h" +#include "Graphics.h" + +namespace ui +{ + class State; + + /* class Engine + * + * Controls the User Interface. + * Send user inputs to the Engine and the appropriate controls and components will interact. + */ + class Engine: public Singleton + { + public: + Engine(); + ~Engine(); + + void onMouseMove(int x, int y); + void onMouseClick(int x, int y, unsigned button); + void onMouseUnclick(int x, int y, unsigned button); + void onMouseWheel(int x, int y, int delta); + void onKeyPress(int key, bool shift, bool ctrl, bool alt); + void onKeyRelease(int key, bool shift, bool ctrl, bool alt); + void onResize(int newWidth, int newHeight); + void onClose(); + + void Begin(int width, int height, SDL_Surface * surface); + inline bool Running() { return running_; } + void Exit(); + + void Tick(float dt); + void Draw(); + + inline int GetMouseX() { return mousex_; } + inline int GetMouseY() { return mousey_; } + inline int GetWidth() { return width_; } + inline int GetHeight() { return height_; } + + inline void SetSize(int width, int height); + + void SetState(State* state); + inline State* GetState() { return state_; } + Graphics * g; + private: + State* statequeued_; + State* state_; + + bool running_; + + int mousex_; + int mousey_; + int mousexp_; + int mouseyp_; + int width_; + int height_; + }; + +} diff --git a/includes/interface/Label.h b/includes/interface/Label.h new file mode 100644 index 000000000..216895684 --- /dev/null +++ b/includes/interface/Label.h @@ -0,0 +1,26 @@ +#ifndef LABEL_H +#define LABEL_H + +#include + +#include "Component.h" + +namespace ui +{ + class Label : public Component + { + public: + Label(State* parent_state, std::string labelText); + + Label(Point position, Point size, std::string labelText); + + Label(std::string labelText); + virtual ~Label(); + + std::string LabelText; + + virtual void Draw(const Point& screenPos); + }; +} + +#endif // LABEL_H diff --git a/includes/interface/Panel.h b/includes/interface/Panel.h index 9549ff4ac..7c9adabf2 100644 --- a/includes/interface/Panel.h +++ b/includes/interface/Panel.h @@ -1,22 +1,136 @@ -/* - * Panel.h - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#ifndef PANEL_H_ -#define PANEL_H_ +#pragma once +#include +//#include "Platform.h" +#include "interface/Point.h" +#include "interface/State.h" #include "interface/Component.h" -namespace ui { +namespace ui +{ + /* class XComponent + * + * An eXtension of the Component class. + * Adds the ability to have child components. + * + * See sys::Component + */ +class Component; + class Panel : public Component + { + public: + friend class Component; -class Panel: public ui::Component { -public: - Panel(int x, int y, int width, int height); - virtual ~Panel(); -}; + Panel(State* parent_state); + Panel(Point position, Point size); + Panel(); + virtual ~Panel(); + + /* Add a child component. + * Similar to XComponent::SetParent + * + * If the component is already parented, then this will become the new parent. + */ + void AddChild(Component* c); + + // Remove child from component. This DOES NOT free the component from memory. + void RemoveChild(Component* c); + + // Remove child from component. This WILL free the component from memory unless told otherwise. + void RemoveChild(unsigned idx, bool freeMem = true); + + //Grab the number of children this component owns. + int GetChildCount(); + + //Get child of this component by index. + Component* GetChild(unsigned idx); + + void Tick(float dt); + void Draw(const Point& screenPos); + + void OnMouseHover(int localx, int localy); + void OnMouseMoved(int localx, int localy, int dx, int dy); + void OnMouseMovedInside(int localx, int localy, int dx, int dy); + void OnMouseEnter(int localx, int localy); + void OnMouseLeave(int localx, int localy); + void OnMouseDown(int x, int y, unsigned button); + void OnMouseUp(int x, int y, unsigned button); + void OnMouseClick(int localx, int localy, unsigned button); + void OnMouseUnclick(int localx, int localy, unsigned button); + void OnMouseWheel(int localx, int localy, int d); + void OnMouseWheelInside(int localx, int localy, int d); + void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + + protected: + // child components + std::vector children; + + //UI functions: + /* + void XTick(float dt); + void XDraw(const Point& screenPos); + + void XOnMouseHover(int localx, int localy); + void XOnMouseMoved(int localx, int localy, int dx, int dy); + void XOnMouseMovedInside(int localx, int localy, int dx, int dy); + void XOnMouseEnter(int localx, int localy); + void XOnMouseLeave(int localx, int localy); + void XOnMouseDown(int x, int y, unsigned int button); + void XOnMouseUp(int x, int y, unsigned int button); + void XOnMouseClick(int localx, int localy, unsigned int button); + void XOnMouseUnclick(int localx, int localy, unsigned int button); + void XOnMouseWheel(int localx, int localy, int d); + void XOnMouseWheelInside(int localx, int localy, int d); + void XOnKeyPress(int key, bool shift, bool ctrl, bool alt); + void XOnKeyRelease(int key, bool shift, bool ctrl, bool alt); + */ + + // Overridable. Called by XComponent::Tick() + virtual void XTick(float dt); + + // Overridable. Called by XComponent::Draw() + virtual void XDraw(const Point& screenPos); + + + // Overridable. Called by XComponent::XOnMouseHover() + virtual void XOnMouseHover(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseMoved() + virtual void XOnMouseMoved(int localx, int localy, int dx, int dy); + + // Overridable. Called by XComponent::OnMouseMovedInside() + virtual void XOnMouseMovedInside(int localx, int localy, int dx, int dy); + + // Overridable. Called by XComponent::OnMouseEnter() + virtual void XOnMouseEnter(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseLeave() + virtual void XOnMouseLeave(int localx, int localy); + + // Overridable. Called by XComponent::OnMouseDown() + virtual void XOnMouseDown(int x, int y, unsigned button); + + // Overridable. Called by XComponent::OnMouseUp() + virtual void XOnMouseUp(int x, int y, unsigned button); + + // Overridable. Called by XComponent::OnMouseClick() + virtual void XOnMouseClick(int localx, int localy, unsigned button); + + // Overridable. Called by XComponent::OnMouseUnclick() + virtual void XOnMouseUnclick(int localx, int localy, unsigned button); + + // Overridable. Called by XComponent::OnMouseWheel() + virtual void XOnMouseWheel(int localx, int localy, int d); + + // Overridable. Called by XComponent::OnMouseWheelInside() + virtual void XOnMouseWheelInside(int localx, int localy, int d); + + // Overridable. Called by XComponent::OnKeyPress() + virtual void XOnKeyPress(int key, bool shift, bool ctrl, bool alt); + + // Overridable. Called by XComponent::OnKeyRelease() + virtual void XOnKeyRelease(int key, bool shift, bool ctrl, bool alt); + }; -} /* namespace ui */ -#endif /* PANEL_H_ */ +} diff --git a/includes/interface/Platform.h b/includes/interface/Platform.h new file mode 100644 index 000000000..c57dca6ec --- /dev/null +++ b/includes/interface/Platform.h @@ -0,0 +1,108 @@ +#pragma once + + +/* ***** Platform-ness ***** */ + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32_LEAN_AND_MEAN) +# define IEF_PLATFORM_WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +#elif defined(linux) || defined(_linux) || defined(__linux) +# define IEF_PLATFORM_LINUX + +#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh) +# define IEF_PLATFORM_MACOSX + +//#elif defined(__FreeBSD__) || define(__FreeBSD_kernel__) +//# define IEF_PLATFORM_FREEBSD + +#else +# error Operating System not supported. +#endif + + +/* ***** Endian-ness ***** */ + +#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__) +# define IEF_ENDIAN_BIG + +#else +# define IEF_ENDIAN_LITTLE +#endif + + +/* ***** Debug-ness ***** */ + +#if !defined(NDEBUG) || defined(_DEBUG) +# define IEF_DEBUG +#endif + + +/* ***** Primitive Types ***** */ + +#ifndef NULL +# define NULL 0 +#endif + +#include +namespace sys +{ + +#if UCHAR_MAX == 0xFF //char + typedef signed char s8; + typedef unsigned char u8; +#else +# error No 8-Bit Integer supported. +#endif +#if USHRT_MAX == 0xFFFF //short + typedef signed short s16; + typedef unsigned short u16; +#elif UINT_MAX == 0xFFFF + typedef signed int s16; + typedef unsigned int u16; +#elif ULONG_MAX == 0xFFFF + typedef signed long s16; + typedef unsigned long u16; + #else + # error No 16-Bit Integer supported. + #endif + #if USHRT_MAX == 0xFFFFFFFF //int + typedef signed short s32; + typedef unsigned short u32; +#elif UINT_MAX == 0xFFFFFFFF + typedef signed int s32; + typedef unsigned int u32; +#elif ULONG_MAX == 0xFFFFFFFF + typedef signed long s32; + typedef unsigned long u32; + #else + # error No 32-Bit Integer supported. + #endif +#if UINT_MAX == 0xFFFFFFFFFFFFFFFF //long + typedef signed int s64; + typedef unsigned int u64; +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF + typedef signed long s64; + typedef unsigned long u64; +#elif ULLONG_MAX == 0xFFFFFFFFFFFFFFFF + typedef signed long long s64; + typedef unsigned long long u64; +#else +# pragma message("Warning: 64-bit not supported. s64 and u64 defined as 32-bit.") + typedef s32 s64; + typedef u32 u64; +#endif +//floating +typedef float f32; +typedef double f64; +//misc +typedef u8 byte; +typedef u8 ubyte; +typedef s8 sbyte; +typedef s64 llong; +typedef s64 sllong; +typedef u64 ullong; +typedef char* cstring; + +} //namespace sys diff --git a/includes/interface/Point.h b/includes/interface/Point.h new file mode 100644 index 000000000..0d0250cbc --- /dev/null +++ b/includes/interface/Point.h @@ -0,0 +1,136 @@ +#pragma once +#include "Platform.h" + +namespace ui +{ + +//Lightweight 2D Int32/Float32 Point struct for UI +struct Point +{ +#if ENABLE_FLOAT_UI +# define POINT_T float +#else +# define POINT_T int +#endif + + POINT_T X; + POINT_T Y; + + Point(POINT_T x, POINT_T y) + : X(x) + , Y(y) + { + } + + inline Point operator - () const + { + return Point(-X, -Y); + } + + inline Point operator + (const Point& v) const + { + return Point(X + v.X, Y + v.Y); + } + + inline Point operator - (const Point& v) const + { + return Point(X - v.X, Y - v.Y); + } + + inline Point operator * (const Point& v) const + { + return Point(X * v.X, Y * v.Y); + } + + inline Point operator * (int v) const + { + return Point(X * static_cast(v), Y * static_cast(v)); + } + + inline Point operator * (float v) const + { + return Point(X * static_cast(v), Y * static_cast(v)); + } + + inline Point operator / (const Point& v) const + { + return Point(X / v.X, Y / v.Y); + } + + inline Point operator / (int v) const + { + return Point(X / static_cast(v), Y / static_cast(v)); + } + + inline Point operator / (float v) const + { + return Point(X / static_cast(v), Y / static_cast(v)); + } + + inline void operator += (const Point& v) + { + X += v.X; + Y += v.Y; + } + + inline void operator -= (const Point& v) + { + X -= v.X; + Y -= v.Y; + } + + inline void operator *= (const Point& v) + { + X *= v.X; + Y *= v.Y; + } + + inline void operator *= (int v) + { + X *= static_cast(v); + Y *= static_cast(v); + } + + inline void operator *= (float v) + { + X *= static_cast(v); + Y *= static_cast(v); + } + + inline void operator /= (const Point& v) + { + X /= v.X; + Y /= v.Y; + } + + inline void operator /= (int v) + { + X /= static_cast(v); + Y /= static_cast(v); + } + + inline void operator /= (float v) + { + X /= static_cast(v); + Y /= static_cast(v); + } + + inline bool operator == (const Point& v) const + { + return (X == v.X && Y == v.Y); + } + + inline bool operator != (const Point& v) const + { + return (X != v.X || Y != v.Y); + } + + inline void operator = (const Point& v) + { + X = v.X; + Y = v.Y; + } + +}; + +} diff --git a/includes/interface/Sandbox.h b/includes/interface/Sandbox.h index 32a047127..f4daa87e9 100644 --- a/includes/interface/Sandbox.h +++ b/includes/interface/Sandbox.h @@ -8,6 +8,8 @@ #ifndef SANDBOX_H_ #define SANDBOX_H_ +#include +#include "Point.h" #include "Component.h" #include "Simulation.h" #include "Renderer.h" @@ -18,16 +20,17 @@ class Sandbox: public ui::Component { private: int lastCoordX, lastCoordY; int activeElement; + std::queue pointQueue; bool isMouseDown; Renderer * ren; Simulation * sim; public: Sandbox(); virtual Simulation * GetSimulation(); - virtual void OnMouseMovedInside(int localx, int localy, int dx, int dy); - virtual void OnMouseDown(int localx, int localy, unsigned int button); - virtual void OnMouseUp(int localx, int localy, unsigned int button); - virtual void Draw(void* userdata); + virtual void OnMouseMoved(int localx, int localy, int dx, int dy); + virtual void OnMouseClick(int localx, int localy, unsigned int button); + virtual void OnMouseUnclick(int localx, int localy, unsigned int button); + virtual void Draw(const Point& screenPos); virtual void Tick(float delta); virtual ~Sandbox(); }; diff --git a/includes/interface/State.h b/includes/interface/State.h index 00df19916..75e969d82 100644 --- a/includes/interface/State.h +++ b/includes/interface/State.h @@ -1,61 +1,77 @@ -/* - * State.h - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - -#ifndef STATE_H_ -#define STATE_H_ +#pragma once #include -#include "interface/Component.h" +#include "Engine.h" +#include "Component.h" +#include "Platform.h" -namespace ui { - -class State +namespace ui { -public: - State(int w, int h); - virtual ~State(); + class Engine; + class Component; + + /* class State + * + * A UI state. Contains all components. + */ + class State + { + public: + State(); + virtual ~State(); - bool AllowExclusiveDrawing; //false will not call draw on objects outside of bounds + bool AllowExclusiveDrawing; //false will not call draw on objects outside of bounds - virtual void Tick(float dt); - virtual void Draw(void* userdata); + // Add Component to state + void AddComponent(Component* c); + + // Get the number of components this state has. + unsigned GetComponentCount(); + + // Get component by index. (See GetComponentCount()) + Component* GetComponent(unsigned idx); + + // Remove a component from state. NOTE: This DOES NOT free component from memory. + void RemoveComponent(Component* c); + + // Remove a component from state. NOTE: This WILL free component from memory. + void RemoveComponent(unsigned idx); + + void DoInitialized(); + void DoExit(); + void DoTick(float dt); + void DoDraw(); - virtual void OnMouseMove(int x, int y); - virtual void OnMouseDown(int x, int y, unsigned int button); - virtual void OnMouseUp(int x, int y, unsigned int button); - virtual void OnMouseWheel(int x, int y, int d); - virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); - virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); + void DoMouseMove(int x, int y, int dx, int dy); + void DoMouseDown(int x, int y, unsigned button); + void DoMouseUp(int x, int y, unsigned button); + void DoMouseWheel(int x, int y, int d); + void DoKeyPress(int key, bool shift, bool ctrl, bool alt); + void DoKeyRelease(int key, bool shift, bool ctrl, bool alt); - virtual void Add(Component *child); - virtual void Remove(Component *child); + bool IsFocused(const Component* c) const; + void FocusComponent(Component* c); - inline bool IsFocused(Component* c) { return (c == focusedComponent_); } - inline int GetMouseX() { return mouseX; } - inline int GetMouseY() { return mouseY; } - inline int GetWidth() { return width; } - inline int GetHeight() { return height; } + void* UserData; -protected: - std::vector Components; + protected: + virtual void OnInitialized() {} + virtual void OnExit() {} + virtual void OnTick(float dt) {} + virtual void OnDraw() {} - int width; - int height; + virtual void OnMouseMove(int x, int y, int dx, int dy) {} + virtual void OnMouseDown(int x, int y, unsigned button) {} + virtual void OnMouseUp(int x, int y, unsigned button) {} + virtual void OnMouseWheel(int x, int y, int d) {} + virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt) {} + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt) {} - int mouseX; - int mouseY; - int mouseXP; - int mouseYP; + private: + std::vector Components; + Component* focusedComponent_; -private: - Component* focusedComponent_; + }; -}; - -} /* namespace ui */ -#endif /* STATE_H_ */ +} diff --git a/src/Console.cpp b/src/Console.cpp index 6bf8ce65f..f861fd1c4 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -1,29 +1,21 @@ #include +#include #include "Console.h" -int Console::ParseType(std::string * type) +int Console::ParsePartref(char * txt) { - char * txt = (char *)type->c_str(); - int i = -1; - // alternative names for some elements - if (*type == "C4") i = PT_PLEX; - else if (*type == "C5") i = PT_C5; - else if (*type == "NONE") i = PT_NONE; - if (i>=0 && iptypes[i].enabled) - { - (*lastError) = ""; - return i; - } - for (i=1; iptypes[i].name)==0 && sim->ptypes[i].enabled) - { - (*lastError) = ""; - return i; - } - } - (*lastError) = "Particle type not recognised"; - return -1; + +} + +int Console::ParseCoords(char * coords, int *x, int *y) +{ + +} + +int Console::ParseType(char * txt) +{ + } void Console::Tick(float * dt) @@ -41,7 +33,7 @@ void Console::ConsoleHidden() } -int Console::ProcessCommand(std::string * command) +int Console::ProcessCommand(char * console) { } diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index 49dac73c0..7ede4d5c1 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -1,32 +1,52 @@ #include #include +#include +#include +#include #include "Config.h" #include "Simulation.h" #include "Renderer.h" #include "Graphics.h" #include "Air.h" -#include "interface/Window.h" +#include "interface/Engine.h" #include "interface/Button.h" #include "interface/Sandbox.h" #include "interface/Panel.h" #include "interface/ControlFactory.h" +#include "interface/Point.h" +#include "interface/Label.h" #include "GameSession.h" +using namespace std; + SDL_Surface * SDLOpen() { +#if defined(WIN32) && defined(WINCONSOLE) + FILE * console = fopen("CON", "w" ); +#endif if (SDL_Init(SDL_INIT_VIDEO)<0) { fprintf(stderr, "Initializing SDL: %s\n", SDL_GetError()); return 0; } +#if defined(WIN32) && defined(WINCONSOLE) + //On Windows, SDL redirects stdout to stdout.txt, which can be annoying when debugging, here we redirect back to the console + if (console) + { + freopen("CON", "w", stdout); + freopen("con", "w", stderr); + fclose(console); + } +#endif atexit(SDL_Quit); return SDL_SetVideoMode(XRES + BARSIZE, YRES + MENUSIZE, 32, SDL_SWSURFACE); } int SDLPoll(SDL_Event * event) { + event->type = 0; while (SDL_PollEvent(event)) { switch (event->type) @@ -40,20 +60,24 @@ int SDLPoll(SDL_Event * event) int main(int argc, char * argv[]) { - int mouseX, mouseY, mouseButton, lastMouseButton; + int elapsedTime = 0, currentTime = 0, lastTime = 0, currentFrame = 0; + float fps, fpsLimit, delta; //Renderer * ren; - Graphics * g = new Graphics(); - g->AttachSDLSurface(SDLOpen()); //Simulation * sim = new Simulation(); //ren = new Renderer(g, sim); GameSession * gameSession = new GameSession(); - ui::Window * window = new ui::Window(); + ui::Engine * engine = &ui::Engine::Ref();//new ui::Engine(); + ui::State * engineState = new ui::State(); ui::Sandbox * sandbox = new ui::Sandbox(); - ui::Button * button = new ui::Button(100, 100, 100, 100, "poP"); - window->Add(sandbox); - window->Add(button); + ui::Button * button = new ui::Button(ui::Point(100, 100), ui::Point(100, 100), std::string("poP")); + ui::Label * fpsLabel = new ui::Label(ui::Point(2, 2), ui::Point(200, 14), std::string("FPS: 0")); + engine->Begin(XRES, YRES, SDLOpen()); + engine->SetState(engineState); + engineState->AddComponent(fpsLabel); + engineState->AddComponent(sandbox); + engineState->AddComponent(button); //window->Add(ControlFactory::MainMenu(gameSession, 0, 0, 200, 200)); SDL_Event event; @@ -67,34 +91,32 @@ int main(int argc, char * argv[]) case SDL_KEYUP: break; case SDL_MOUSEMOTION: - window->OnMouseMove(event.motion.x, event.motion.y); + engine->onMouseMove(event.motion.x, event.motion.y); break; case SDL_MOUSEBUTTONDOWN: - window->OnMouseDown(event.motion.x, event.motion.y, event.button.button); + engine->onMouseClick(event.motion.x, event.motion.y, event.button.button); break; case SDL_MOUSEBUTTONUP: - window->OnMouseUp(event.motion.x, event.motion.y, event.button.button); + engine->onMouseUnclick(event.motion.x, event.motion.y, event.button.button); break; } - window->Tick(1.0f); - window->Draw(g); - /*sim->update_particles(); - sim->air->update_air(); - mouseButton = SDL_GetMouseState(&mouseX, &mouseY); - if(mouseButton) - { - sim->create_parts(mouseX, mouseY, 4, 4, (rand()%4)+1, 0); - } - if(mouseButton==4 && !lastMouseButton) - { - sim->sys_pause = !sim->sys_pause; - } - //ren->render_parts(); - //ren->render_fire(); + fpsLabel->LabelText = ""; + stringstream fpsText; + fpsText << "FPS: " << fps; + fpsLabel->LabelText = fpsText.str(); + engine->Tick(delta); + engine->Draw(); - ren->g->clearrect(0, 0, XRES+BARSIZE, YRES+MENUSIZE);*/ - g->Blit(); - g->Clear(); + currentFrame++; + currentTime = SDL_GetTicks(); + elapsedTime = currentTime - lastTime; + if(elapsedTime>=1000) + { + fps = (((float)currentFrame)/((float)elapsedTime))*1000.0f; + currentFrame = 0; + lastTime = currentTime; + delta = 60.0f/fps; + } } } diff --git a/src/interface.old/Button.cpp b/src/interface.old/Button.cpp new file mode 100644 index 000000000..a357c363d --- /dev/null +++ b/src/interface.old/Button.cpp @@ -0,0 +1,127 @@ +/* + * Button.cpp + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#include + +#include "interface/Button.h" +#include "Graphics.h" + +namespace ui { + +Button::Button(int x, int y, int width, int height, const std::string& buttonText): + Component(x, y, width, height), + Toggleable(false), + ButtonText(buttonText), + isMouseInside(false), + isButtonDown(false), + state(false) +{ + +} + +void Button::Draw(void* userdata) +{ + Graphics * g = reinterpret_cast(userdata); + //TODO: Cache text location, that way we don't have the text alignment code here + if(isButtonDown) + { + g->fillrect(X, Y, Width, Height, 255, 255, 255, 255); + g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 0, 0, 0, 255); + } + else + { + if(isMouseInside) + g->fillrect(X, Y, Width, Height, 20, 20, 20, 255); + g->drawrect(X, Y, Width, Height, 255, 255, 255, 255); + g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 255, 255, 255, 255); + } + /*sf::RenderWindow* rw = reinterpret_cast(userdata); //it better be a RenderWindow or so help your god + + //Draw component here + sf::Text textGraphic(ButtonText); + textGraphic.SetCharacterSize(11); + if(isButtonDown) + textGraphic.SetColor(sf::Color::Black); + else + textGraphic.SetColor(sf::Color::White); + sf::FloatRect tempRect = textGraphic.GetRect(); + textGraphic.SetPosition(ceil(X + Width/2 - tempRect.Width/2), ceil(Y + Height/2 - tempRect.Height/2)); + + if(isMouseInside) + { + if(isButtonDown) + rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::White, 2.f, sf::Color::Black)); + else + rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::Black, 2.f, sf::Color::White)); + } + else + { + if(isButtonDown) + rw->Draw(sf::Shape::Rectangle(X+2, Y+2, Width-4, Width-4, sf::Color::White, 2.f, sf::Color::Black)); + else + rw->Draw(sf::Shape::Rectangle(X+1, Y+1, Width-2, Width-2, sf::Color::Black, 1.f, sf::Color::White)); + } + + rw->Draw(textGraphic);*/ +} + +void Button::OnMouseUnclick(int x, int y, unsigned int button) +{ + if(button != 1) + { + return; //left click only! + } + + if(isButtonDown) + { + if(state) + { + state = false; + } + else + { + if(Toggleable) + { + state = true; + } + DoAction(); + } + } + + isButtonDown = false; +} + +void Button::OnMouseUp(int x, int y, unsigned int button) //mouse unclick is called before this +{ + if(button != 1) return; //left click only! + + isButtonDown = false; +} + +void Button::OnMouseClick(int x, int y, unsigned int button) +{ + if(button != 1) return; //left click only! + + isButtonDown = true; +} + +void Button::OnMouseEnter(int x, int y, int dx, int dy) +{ + isMouseInside = true; +} + +void Button::OnMouseLeave(int x, int y, int dx, int dy) +{ + isMouseInside = false; +} + +void Button::DoAction() +{ + std::cout << "Do action!"<Add(new ui::Button(0, 0, 20, 20, "Turd")); + return mainMenu; +} diff --git a/src/interface.old/Panel.cpp b/src/interface.old/Panel.cpp new file mode 100644 index 000000000..164bfa305 --- /dev/null +++ b/src/interface.old/Panel.cpp @@ -0,0 +1,23 @@ +/* + * Panel.cpp + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#include "interface/Panel.h" + +namespace ui { + +Panel::Panel(int x, int y, int width, int height): + Component(x, y, width, height) +{ + // TODO Auto-generated constructor stub + +} + +Panel::~Panel() { + // TODO Auto-generated destructor stub +} + +} /* namespace ui */ diff --git a/src/interface.old/Sandbox.cpp b/src/interface.old/Sandbox.cpp new file mode 100644 index 000000000..5e29bae04 --- /dev/null +++ b/src/interface.old/Sandbox.cpp @@ -0,0 +1,76 @@ +/* + * Sandbox.cpp + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#include + +#include "Config.h" + +#include "interface/Sandbox.h" +#include "interface/Component.h" +#include "Renderer.h" +#include "Simulation.h" + +namespace ui { + +Sandbox::Sandbox(): + Component(0, 0, XRES, YRES), + ren(NULL), + isMouseDown(false), + activeElement(1) +{ + sim = new Simulation(); +} + +Simulation * Sandbox::GetSimulation() +{ + return sim; +} + +void Sandbox::OnMouseMovedInside(int localx, int localy, int dx, int dy) +{ + if(isMouseDown) + { + sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); + lastCoordX = localx; + lastCoordY = localy; + } +} + +void Sandbox::OnMouseDown(int localx, int localy, unsigned int button) +{ + sim->create_line(localx, localy, localx, localy, 2, 2, activeElement, 0); + lastCoordX = localx; + lastCoordY = localy; + isMouseDown = true; +} + +void Sandbox::OnMouseUp(int localx, int localy, unsigned int button) +{ + sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); + lastCoordX = localx; + lastCoordY = localy; + isMouseDown = false; +} + +void Sandbox::Draw(void* userdata) +{ + Graphics * g = reinterpret_cast(userdata); + if(!ren) + ren = new Renderer(g, sim); + ren->render_parts(); +} + +void Sandbox::Tick(float delta) +{ + sim->update_particles(); +} + +Sandbox::~Sandbox() { + // TODO Auto-generated destructor stub +} + +} /* namespace ui */ diff --git a/src/interface.old/State.cpp b/src/interface.old/State.cpp new file mode 100644 index 000000000..28287510b --- /dev/null +++ b/src/interface.old/State.cpp @@ -0,0 +1,233 @@ +/* + * State.cpp + * + * Created on: Jan 8, 2012 + * Author: Simon + */ + +#include +#include +#include + +#include "interface/State.h" + +namespace ui { + +State::State(int w, int h): + mouseX(0), + mouseY(0), + mouseXP(0), + mouseYP(0), + width(w), + height(h), + Components() +{ +} + +State::~State() +{ + //Components.~vector(); // just in case // devnote : Nope.jpg Nate :3 -frankbro +} + +void State::Add(Component* child) +{ + Components.push_back(child); + child->Parent = this; +} + +void State::Remove(Component* child) +{ + for(int i = 0; i < Components.size(); i++) + if(Components[i] == child) + { + Components.erase(Components.begin() + i); + break; + } +} + +void State::Draw(void* userdata) +{ + //draw + for(int i = 0; i < Components.size(); i++) + { + if(Components[i]->Visible) + { + if(AllowExclusiveDrawing) + { + Components[i]->Draw(userdata); + } + else if( + Components[i]->X + Components[i]->Width >= 0 && + Components[i]->Y + Components[i]->Height >= 0 && + Components[i]->X < width && + Components[i]->Y < height ) + { + Components[i]->Draw(userdata); + } + } + } +} + +void State::Tick(float dt) +{ + //on mouse hover + for(int i = 0; i < Components.size(); i++) + if( mouseX >= Components[i]->X && + mouseY >= Components[i]->Y && + mouseX < Components[i]->X + Components[i]->Width && + mouseY < Components[i]->Y + Components[i]->Height ) + { + if(Components[i]->Enabled) + { + Components[i]->OnMouseHover(mouseX, mouseY); + } + break; + } + + //tick + for(int i = 0; i < Components.size(); i++) + Components[i]->Tick(dt); +} + +void State::OnKeyPress(int key, bool shift, bool ctrl, bool alt) +{ + //on key press + if(focusedComponent_ != NULL) + if(focusedComponent_->Enabled) + focusedComponent_->OnKeyPress(key, shift, ctrl, alt); +} + +void State::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) +{ + //on key unpress + if(focusedComponent_ != NULL) + if(focusedComponent_->Enabled) + focusedComponent_->OnKeyRelease(key, shift, ctrl, alt); +} + +void State::OnMouseDown(int x, int y, unsigned int button) +{ + //on mouse click + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + { + Components[i]->OnMouseClick(x - Components[i]->X, y - Components[i]->Y, button); + this->focusedComponent_ = Components[i]; //set this component as the focused component + break; + } + + //on mouse down + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + Components[i]->OnMouseDown(x - Components[i]->X, y - Components[i]->Y, button); +} + +void State::OnMouseMove(int x, int y) +{ + //update mouse coords + mouseX = x; + mouseY = y; + + //on mouse move (if true, and inside) + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + { + int localX = x - Components[i]->X; + int localY = y - Components[i]->Y; + int localXP = mouseXP - Components[i]->X; + int localYP = mouseYP - Components[i]->Y; + int dx = x - mouseXP; + int dy = x - mouseYP; + + Components[i]->OnMouseMoved(localX, localY, dx, dy); + + //is the mouse inside + if(localX >= 0 && + localY >= 0 && + localX < Components[i]->Width && + localY < Components[i]->Height ) + { + //was the mouse outside last tick? + if(localXP < 0 || + localXP >= Components[i]->Width || + localYP < 0 || + localYP >= Components[i]->Height ) + { + Components[i]->OnMouseEnter(localX, localY, dx, dy); + } + + Components[i]->OnMouseMovedInside(localX, localY, dx, dy); + + break; //found the top-most component under mouse, break that shit + } + //not inside, let's see if it used to be inside last tick + else if (localXP >= 0 && + localYP >= 0 && + localXP < Components[i]->Width && + localYP < Components[i]->Height ) + { + Components[i]->OnMouseLeave(localX, localY, x - mouseXP, y - mouseYP); + } + } + else //is locked + { + int localX = x - Components[i]->X; + int localY = y - Components[i]->Y; + + //is the mouse inside + if(localX >= 0 && + localY >= 0 && + localX < Components[i]->Width && + localY < Components[i]->Height ) + { + break; //it's the top-most component under the mouse, we don't want to go under it. + } + } + // end of for loop here + + //set the previous mouse coords + mouseXP = x; + mouseYP = y; +} + +void State::OnMouseUp(int x, int y, unsigned int button) +{ + //on mouse unclick + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + { + Components[i]->OnMouseUnclick(x - Components[i]->X, y - Components[i]->Y, button); + break; + } + + //on mouse up + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + Components[i]->OnMouseUp(x - Components[i]->X, y - Components[i]->Y, button); +} + +void State::OnMouseWheel(int x, int y, int d) +{ + //focused mouse wheel + if(focusedComponent_ != NULL) + focusedComponent_->OnMouseWheelFocused(x - focusedComponent_->X, y - focusedComponent_->Y, d); + + //mouse wheel inside + for(int i = Components.size() - 1; i > -1 ; i--) + if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + { + if(Components[i]->Enabled) + Components[i]->OnMouseWheelInside(x - Components[i]->X, y - Components[i]->Y, d); + break; //found top-most component under mouse + } + + //on mouse wheel + for(int i = Components.size() - 1; i > -1 ; i--) + if(Components[i]->Enabled) + Components[i]->OnMouseWheel(x - Components[i]->X, y - Components[i]->Y, d); +} + + +} /* namespace ui */ diff --git a/src/interface/Window.cpp b/src/interface.old/Window.cpp similarity index 100% rename from src/interface/Window.cpp rename to src/interface.old/Window.cpp diff --git a/src/interface/Button.cpp b/src/interface/Button.cpp index a357c363d..e34f66c4b 100644 --- a/src/interface/Button.cpp +++ b/src/interface/Button.cpp @@ -12,32 +12,49 @@ namespace ui { -Button::Button(int x, int y, int width, int height, const std::string& buttonText): - Component(x, y, width, height), - Toggleable(false), - ButtonText(buttonText), - isMouseInside(false), - isButtonDown(false), - state(false) +Button::Button(State* parent_state, std::string buttonText): + Component(parent_state), + ButtonText(buttonText), + isMouseInside(false), + isButtonDown(false) { } -void Button::Draw(void* userdata) +Button::Button(Point position, Point size, std::string buttonText): + Component(position, size), + ButtonText(buttonText), + isMouseInside(false), + isButtonDown(false) { - Graphics * g = reinterpret_cast(userdata); + +} + +Button::Button(std::string buttonText): + Component(), + ButtonText(buttonText), + isMouseInside(false), + isButtonDown(false) +{ + +} + +void Button::Draw(const Point& screenPos) +{ + Graphics * g = ui::Engine::Ref().g; + // = reinterpret_cast(userdata); //TODO: Cache text location, that way we don't have the text alignment code here if(isButtonDown) { - g->fillrect(X, Y, Width, Height, 255, 255, 255, 255); - g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 0, 0, 0, 255); + g->fillrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255); + g->drawtext(Position.X+(Size.X-Graphics::textwidth((char *)ButtonText.c_str()))/2, Position.Y+(Size.Y-10)/2, ButtonText, 0, 0, 0, 255); } else { if(isMouseInside) - g->fillrect(X, Y, Width, Height, 20, 20, 20, 255); - g->drawrect(X, Y, Width, Height, 255, 255, 255, 255); - g->drawtext(X+(Width-Graphics::textwidth((char *)ButtonText.c_str()))/2, Y+(Height-10)/2, ButtonText, 255, 255, 255, 255); + g->fillrect(Position.X, Position.Y, Size.X, Size.Y, 20, 20, 20, 255); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255); + g->drawtext(Position.X+(Size.X-Graphics::textwidth((char *)ButtonText.c_str()))/2, Position.Y+(Size.Y-10)/2, ButtonText, 255, 255, 255, 255); } /*sf::RenderWindow* rw = reinterpret_cast(userdata); //it better be a RenderWindow or so help your god @@ -71,6 +88,7 @@ void Button::Draw(void* userdata) void Button::OnMouseUnclick(int x, int y, unsigned int button) { + std::cout << "Unclick!" << std::endl; if(button != 1) { return; //left click only! @@ -78,44 +96,35 @@ void Button::OnMouseUnclick(int x, int y, unsigned int button) if(isButtonDown) { - if(state) - { - state = false; - } - else - { - if(Toggleable) - { - state = true; - } - DoAction(); - } + DoAction(); } isButtonDown = false; } -void Button::OnMouseUp(int x, int y, unsigned int button) //mouse unclick is called before this -{ - if(button != 1) return; //left click only! +//void Button::OnMouseUp(int x, int y, unsigned int button) //mouse unclick is called before this +//{ + // if(button != 1) return; //left click only! - isButtonDown = false; -} +// isButtonDown = false; +//} void Button::OnMouseClick(int x, int y, unsigned int button) { + std::cout << "Click!" << std::endl; if(button != 1) return; //left click only! - isButtonDown = true; } -void Button::OnMouseEnter(int x, int y, int dx, int dy) +void Button::OnMouseEnter(int x, int y) { + std::cout << "Enter!"<IsFocused(this); +} + +void Component::SetParentState(State* state) +{ + parentstate_ = state; +} + +void Component::SetParent(Panel* new_parent) +{ + if(new_parent == NULL) + { + if(_parent != NULL) + { + // remove from current parent and send component to parent state + for(int i = 0; i < _parent->GetChildCount(); ++i) + { + if(_parent->GetChild(i) == this) + { + // remove ourself from parent component + _parent->RemoveChild(i, false); + + // add ourself to the parent state + GetParentState()->AddComponent(this); + + //done in this loop. + break; + } + } + } + } + else + { + // remove from parent state (if in parent state) and place in new parent + GetParentState()->RemoveComponent(this); + new_parent->children.push_back(this); + } + this->_parent = new_parent; +} + +// ***** OVERRIDEABLES ***** +// Kept empty. + +void Component::Draw(const Point& screenPos) { } @@ -39,23 +101,11 @@ void Component::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) { } -void Component::OnMouseEnter(int localx, int localy, int dx, int dy) +void Component::OnMouseClick(int localx, int localy, unsigned button) { } -void Component::OnMouseLeave(int localx, int localy, int dx, int dy) -{ -} - -void Component::OnMouseClick(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseUnclick(int localx, int localy, unsigned int button) -{ -} - -void Component::OnMouseDown(int localx, int localy, unsigned int button) +void Component::OnMouseDown(int x, int y, unsigned button) { } @@ -71,7 +121,19 @@ void Component::OnMouseMovedInside(int localx, int localy, int dx, int dy) { } -void Component::OnMouseUp(int localx, int localy, unsigned int button) +void Component::OnMouseEnter(int localx, int localy) +{ +} + +void Component::OnMouseLeave(int localx, int localy) +{ +} + +void Component::OnMouseUnclick(int localx, int localy, unsigned button) +{ +} + +void Component::OnMouseUp(int x, int y, unsigned button) { } @@ -83,7 +145,7 @@ void Component::OnMouseWheelInside(int localx, int localy, int d) { } -void Component::OnMouseWheelFocused(int localx, int localy, int d) +Component::~Component() { + } -} /* namespace ui */ diff --git a/src/interface/ControlFactory.cpp b/src/interface/ControlFactory.cpp index 300ceba94..25822cdbe 100644 --- a/src/interface/ControlFactory.cpp +++ b/src/interface/ControlFactory.cpp @@ -1,11 +1,12 @@ +#include "interface/Point.h" #include "interface/ControlFactory.h" #include "interface/Button.h" #include "interface/Panel.h" -#include "interface/Window.h" +#include "interface/Engine.h" ui::Panel * ControlFactory::MainMenu(GameSession * session, int x, int y, int width, int height) { - ui::Panel * mainMenu = new ui::Panel(x, y, width, height); + ui::Panel * mainMenu = new ui::Panel(ui::Point(x, y), ui::Point(width, height)); //mainMenu->Add(new ui::Button(0, 0, 20, 20, "Turd")); return mainMenu; } diff --git a/src/interface/Engine.cpp b/src/interface/Engine.cpp new file mode 100644 index 000000000..4468561b4 --- /dev/null +++ b/src/interface/Engine.cpp @@ -0,0 +1,138 @@ +#include "interface/Platform.h" +#include "interface/Engine.h" +#include "interface/State.h" +#include "Graphics.h" + +using namespace ui; + +Engine::Engine() +: + g(NULL), +state_(NULL), +statequeued_(NULL), +mousex_(0), +mousey_(0), +mousexp_(0), +mouseyp_(0) +{ +} + +Engine::~Engine() +{ + if(state_ != NULL) + delete state_; +} + +void Engine::Begin(int width, int height, SDL_Surface * surface) +{ + g = new Graphics(); + g->AttachSDLSurface(surface); + //engine is now ready + running_ = true; + + width_ = width; + height_ = height; +} + +void Engine::Exit() +{ + running_ = false; +} + +void Engine::SetState(State * state) +{ + if(state_) //queue if currently in a state + statequeued_ = state; + else + { + state_ = state; + if(state_) + state_->DoInitialized(); + } +} + +void Engine::SetSize(int width, int height) +{ + width_ = width; + height_ = height; +} + +void Engine::Tick(float dt) +{ + if(state_ != NULL) + state_->DoTick(dt); + + if(statequeued_ != NULL) + { + if(state_ != NULL) + { + state_->DoExit(); + delete state_; + state_ = NULL; + } + state_ = statequeued_; + statequeued_ = NULL; + + if(state_ != NULL) + state_->DoInitialized(); + } +} + +void Engine::Draw() +{ + if(state_) + state_->DoDraw(); + g->Blit(); + g->Clear(); +} + +void Engine::onKeyPress(int key, bool shift, bool ctrl, bool alt) +{ + if(state_) + state_->DoKeyPress(key, shift, ctrl, alt); +} + +void Engine::onKeyRelease(int key, bool shift, bool ctrl, bool alt) +{ + if(state_) + state_->DoKeyRelease(key, shift, ctrl, alt); +} + +void Engine::onMouseClick(int x, int y, unsigned button) +{ + if(state_) + state_->DoMouseDown(x, y, button); +} + +void Engine::onMouseUnclick(int x, int y, unsigned button) +{ + if(state_) + state_->DoMouseUp(x, y, button); +} + +void Engine::onMouseMove(int x, int y) +{ + mousex_ = x; + mousey_ = y; + if(state_) + state_->DoMouseMove(x, y, mousex_ - mousexp_, mousey_ - mouseyp_); + mousexp_ = x; + mouseyp_ = y; +} + +void Engine::onMouseWheel(int x, int y, int delta) +{ + if(state_) + state_->DoMouseWheel(x, y, delta); +} + +void Engine::onResize(int newWidth, int newHeight) +{ + SetSize(newWidth, newHeight); +} + +void Engine::onClose() +{ + if(state_) + state_->DoExit(); +} diff --git a/src/interface/Label.cpp b/src/interface/Label.cpp new file mode 100644 index 000000000..3a5ea854b --- /dev/null +++ b/src/interface/Label.cpp @@ -0,0 +1,38 @@ +#include +#include "interface/Point.h" +#include "interface/Label.h" + +using namespace ui; + +Label::Label(State* parent_state, std::string labelText): + Component(parent_state), + LabelText(labelText) +{ + +} + +Label::Label(Point position, Point size, std::string labelText): + Component(position, size), + LabelText(labelText) +{ + +} + +Label::Label(std::string labelText): + Component(), + LabelText(labelText) +{ + +} + +Label::~Label() +{ + +} + + +void Label::Draw(const Point& screenPos) +{ + Graphics * g = ui::Engine::Ref().g; + g->drawtext(Position.X+(Size.X-Graphics::textwidth((char *)LabelText.c_str()))/2, Position.Y+(Size.Y-10)/2, LabelText, 255, 255, 255, 255); +} diff --git a/src/interface/Panel.cpp b/src/interface/Panel.cpp index 164bfa305..e44663a7b 100644 --- a/src/interface/Panel.cpp +++ b/src/interface/Panel.cpp @@ -1,23 +1,392 @@ -/* - * Panel.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ +#pragma once +#include +//#include "Platform.h" #include "interface/Panel.h" -namespace ui { +#include "interface/Point.h" +#include "interface/State.h" +#include "interface/Component.h" -Panel::Panel(int x, int y, int width, int height): - Component(x, y, width, height) +using namespace ui; + +Panel::Panel(State* parent_state): + Component(parent_state) { - // TODO Auto-generated constructor stub } -Panel::~Panel() { - // TODO Auto-generated destructor stub +Panel::Panel(Point position, Point size): + Component(position, size) +{ + } -} /* namespace ui */ +Panel::Panel(): + Component() +{ + +} + +Panel::~Panel() +{ + for(unsigned i = 0; i < children.size(); ++i) + { + if( children[i] ) + delete children[i]; + } +} + +void Panel::AddChild(Component* c) +{ + c->SetParent(this); +} + +int Panel::GetChildCount() +{ + return children.size(); +} + +Component* Panel::GetChild(unsigned idx) +{ + return children[idx]; +} + +void Panel::RemoveChild(Component* c) +{ + for(int i = 0; i < children.size(); ++i) + { + if(children[i] == c) + { + //remove child from parent. Does not free memory + children.erase(children.begin() + i); + break; + } + } +} + +void Panel::RemoveChild(unsigned idx, bool freeMem) +{ + if(freeMem) + delete children[idx]; + + children.erase(children.begin() + idx); +} + +void Panel::Draw(const Point& screenPos) +{ + // draw ourself first + XDraw(screenPos); + + // attempt to draw all children + for(int i = 0; i < children.size(); ++i) + { + // the component must be visible + if(children[i]->Visible) + { + if(GetParentState()->AllowExclusiveDrawing) + { + //who cares if the component is off the screen? draw anyway. + Point scrpos = screenPos + children[i]->Position; + children[i]->Draw(scrpos); + } + else + { + //check if the component is in the screen, draw if it is + if( children[i]->Position.X + children[i]->Size.X >= 0 && + children[i]->Position.Y + children[i]->Size.Y >= 0 && + children[i]->Position.X < ui::Engine::Ref().GetWidth() && + children[i]->Position.Y < ui::Engine::Ref().GetHeight() ) + { + Point scrpos = screenPos + children[i]->Position; + children[i]->Draw(scrpos); + } + } + } + } +} + +void Panel::Tick(float dt) +{ + // tick ourself first + XTick(dt); + + // tick our children + for(unsigned i = 0; i < children.size(); ++i) + children[i]->Tick(dt); +} + +void Panel::OnKeyPress(int key, bool shift, bool ctrl, bool alt) +{ + XOnKeyPress(key, shift, ctrl, alt); +} + +void Panel::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) +{ + XOnKeyRelease(key, shift, ctrl, alt); +} + +void Panel::OnMouseClick(int localx, int localy, unsigned button) +{ + bool childclicked = false; + + //check if clicked a child + for(int i = children.size()-1; i >= 0 ; --i) + { + //child must be unlocked + if(!children[i]->Locked) + { + //is mouse inside? + if( localx >= children[i]->Position.X && + localy >= children[i]->Position.Y && + localx < children[i]->Position.X + children[i]->Size.X && + localy < children[i]->Position.Y + children[i]->Size.Y ) + { + childclicked = true; + GetParentState()->FocusComponent(children[i]); + children[i]->OnMouseClick(localx - children[i]->Position.X, localy - children[i]->Position.Y, button); + break; + } + } + } + + //if a child wasn't clicked, send click to ourself + if(!childclicked) + { + XOnMouseClick(localx, localy, button); + GetParentState()->FocusComponent(this); + } +} + +void Panel::OnMouseDown(int x, int y, unsigned button) +{ + XOnMouseDown(x, y, button); + for(int i = 0; i < children.size(); ++i) + { + if(!children[i]->Locked) + children[i]->OnMouseDown(x, y, button); + } +} + +void Panel::OnMouseHover(int localx, int localy) +{ + // check if hovering on children + for(int i = children.size() - 1; i >= 0; --i) + { + if(!children[i]->Locked) + { + if( localx >= children[i]->Position.X && + localy >= children[i]->Position.Y && + localx < children[i]->Position.X + children[i]->Size.X && + localy < children[i]->Position.Y + children[i]->Size.Y ) + { + children[i]->OnMouseHover(localx - children[i]->Position.X, localy - children[i]->Position.Y); + break; + } + } + } + + // always allow hover on parent (?) + XOnMouseHover(localx, localy); +} + +void Panel::OnMouseMoved(int localx, int localy, int dx, int dy) +{ + XOnMouseMoved(localx, localy, dx, dy); + for(int i = 0; i < children.size(); ++i) + { + if(!children[i]->Locked) + children[i]->OnMouseMoved(localx - children[i]->Position.X, localy - children[i]->Position.Y, dx, dy); + } +} + +void Panel::OnMouseMovedInside(int localx, int localy, int dx, int dy) +{ + for(int i = 0; i < children.size(); ++i) + { + if(!children[i]->Locked) + { + Point local (localx - children[i]->Position.X, localy - children[i]->Position.Y) + , prevlocal (local.X - dx, local.Y - dy); + + // mouse currently inside? + if( local.X >= 0 && + local.Y >= 0 && + local.X < children[i]->Size.X && + local.Y < children[i]->Size.Y ) + { + children[i]->OnMouseMovedInside(localx - children[i]->Position.X, localy - children[i]->Position.Y, dx, dy); + + // was the mouse outside? + if(!(prevlocal.X >= 0 && + prevlocal.Y >= 0 && + prevlocal.X < children[i]->Size.X && + prevlocal.Y < children[i]->Size.Y ) ) + { + children[i]->OnMouseEnter(local.X, local.Y); + } + } + // if not currently inside + else + { + // was the mouse inside? + if( prevlocal.X >= 0 && + prevlocal.Y >= 0 && + prevlocal.X < children[i]->Size.X && + prevlocal.Y < children[i]->Size.Y ) + { + children[i]->OnMouseLeave(local.X, local.Y); + } + + } + } + } + + // always allow hover on parent (?) + XOnMouseMovedInside(localx, localy, dx, dy); +} + +void Panel::OnMouseEnter(int localx, int localy) +{ + XOnMouseEnter(localx, localy); +} + +void Panel::OnMouseLeave(int localx, int localy) +{ + XOnMouseLeave(localx, localy); +} + +void Panel::OnMouseUnclick(int localx, int localy, unsigned button) +{ + bool childunclicked = false; + + //check if clicked a child + for(int i = children.size()-1; i >= 0 ; --i) + { + //child must be unlocked + if(!children[i]->Locked) + { + //is mouse inside? + if( localx >= children[i]->Position.X && + localy >= children[i]->Position.Y && + localx < children[i]->Position.X + children[i]->Size.X && + localy < children[i]->Position.Y + children[i]->Size.Y ) + { + childunclicked = true; + children[i]->OnMouseUnclick(localx - children[i]->Position.X, localy - children[i]->Position.Y, button); + break; + } + } + } + + //if a child wasn't clicked, send click to ourself + if(!childunclicked) + { + XOnMouseUnclick(localx, localy, button); + } +} + +void Panel::OnMouseUp(int x, int y, unsigned button) +{ + XOnMouseUp(x, y, button); + for(int i = 0; i < children.size(); ++i) + { + if(!children[i]->Locked) + children[i]->OnMouseUp(x, y, button); + } +} + +void Panel::OnMouseWheel(int localx, int localy, int d) +{ + XOnMouseWheel(localx, localy, d); + for(int i = 0; i < children.size(); ++i) + { + if(!children[i]->Locked) + children[i]->OnMouseWheel(localx - children[i]->Position.X, localy - children[i]->Position.Y, d); + } +} + +void Panel::OnMouseWheelInside(int localx, int localy, int d) +{ + XOnMouseWheelInside(localx, localy, d); + //check if clicked a child + for(int i = children.size()-1; i >= 0 ; --i) + { + //child must be unlocked + if(!children[i]->Locked) + { + //is mouse inside? + if( localx >= children[i]->Position.X && + localy >= children[i]->Position.Y && + localx < children[i]->Position.X + children[i]->Size.X && + localy < children[i]->Position.Y + children[i]->Size.Y ) + { + children[i]->OnMouseWheelInside(localx - children[i]->Position.X, localy - children[i]->Position.Y, d); + break; + } + } + } +} + +// ***** OVERRIDEABLES ***** +// Kept empty. + +void Panel::XDraw(const Point& screenPos) +{ +} + +void Panel::XTick(float dt) +{ +} + +void Panel::XOnKeyPress(int key, bool shift, bool ctrl, bool alt) +{ +} + +void Panel::XOnKeyRelease(int key, bool shift, bool ctrl, bool alt) +{ +} + +void Panel::XOnMouseClick(int localx, int localy, unsigned button) +{ +} + +void Panel::XOnMouseDown(int x, int y, unsigned button) +{ +} + +void Panel::XOnMouseHover(int localx, int localy) +{ +} + +void Panel::XOnMouseMoved(int localx, int localy, int dx, int dy) +{ +} + +void Panel::XOnMouseMovedInside(int localx, int localy, int dx, int dy) +{ +} + +void Panel::XOnMouseEnter(int localx, int localy) +{ +} + +void Panel::XOnMouseLeave(int localx, int localy) +{ +} + +void Panel::XOnMouseUnclick(int localx, int localy, unsigned button) +{ +} + +void Panel::XOnMouseUp(int x, int y, unsigned button) +{ +} + +void Panel::XOnMouseWheel(int localx, int localy, int d) +{ +} + +void Panel::XOnMouseWheelInside(int localx, int localy, int d) +{ +} diff --git a/src/interface/Sandbox.cpp b/src/interface/Sandbox.cpp index 5e29bae04..a9f1d9c06 100644 --- a/src/interface/Sandbox.cpp +++ b/src/interface/Sandbox.cpp @@ -6,9 +6,11 @@ */ #include +#include #include "Config.h" +#include "interface/Point.h" #include "interface/Sandbox.h" #include "interface/Component.h" #include "Renderer.h" @@ -17,7 +19,8 @@ namespace ui { Sandbox::Sandbox(): - Component(0, 0, XRES, YRES), + Component(Point(0, 0), Point(XRES, YRES)), + pointQueue(std::queue()), ren(NULL), isMouseDown(false), activeElement(1) @@ -30,35 +33,33 @@ Simulation * Sandbox::GetSimulation() return sim; } -void Sandbox::OnMouseMovedInside(int localx, int localy, int dx, int dy) +void Sandbox::OnMouseMoved(int localx, int localy, int dx, int dy) { if(isMouseDown) { - sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; + pointQueue.push(new Point(localx-dx, localy-dy)); + pointQueue.push(new Point(localx, localy)); } } -void Sandbox::OnMouseDown(int localx, int localy, unsigned int button) +void Sandbox::OnMouseClick(int localx, int localy, unsigned int button) { - sim->create_line(localx, localy, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; isMouseDown = true; + pointQueue.push(new Point(localx, localy)); } -void Sandbox::OnMouseUp(int localx, int localy, unsigned int button) +void Sandbox::OnMouseUnclick(int localx, int localy, unsigned int button) { - sim->create_line(lastCoordX, lastCoordY, localx, localy, 2, 2, activeElement, 0); - lastCoordX = localx; - lastCoordY = localy; - isMouseDown = false; + if(isMouseDown) + { + isMouseDown = false; + pointQueue.push(new Point(localx, localy)); + } } -void Sandbox::Draw(void* userdata) +void Sandbox::Draw(const Point& screenPos) { - Graphics * g = reinterpret_cast(userdata); + Graphics * g = ui::Engine::Ref().g; if(!ren) ren = new Renderer(g, sim); ren->render_parts(); @@ -66,7 +67,32 @@ void Sandbox::Draw(void* userdata) void Sandbox::Tick(float delta) { + if(!pointQueue.empty()) + { + Point * sPoint = NULL; + while(!pointQueue.empty()) + { + Point * fPoint = pointQueue.front(); + pointQueue.pop(); + if(sPoint) + { + sim->create_line(fPoint->X, fPoint->Y, sPoint->X, sPoint->Y, 2, 2, activeElement, 0); + delete sPoint; + sPoint = fPoint; + } + else + { + sim->create_parts(fPoint->X, fPoint->Y, 2, 2, activeElement, 0); + } + if(sPoint) + delete sPoint; + sPoint = fPoint; + } + if(sPoint) + delete sPoint; + } sim->update_particles(); + sim->sys_pause = 1; } Sandbox::~Sandbox() { diff --git a/src/interface/State.cpp b/src/interface/State.cpp index 28287510b..665e2e8ea 100644 --- a/src/interface/State.cpp +++ b/src/interface/State.cpp @@ -1,233 +1,291 @@ -/* - * State.cpp - * - * Created on: Jan 8, 2012 - * Author: Simon - */ - #include -#include -#include - +#include "interface/Component.h" +#include "interface/Engine.h" #include "interface/State.h" +//#include "Platform.h" -namespace ui { +using namespace ui; -State::State(int w, int h): - mouseX(0), - mouseY(0), - mouseXP(0), - mouseYP(0), - width(w), - height(h), - Components() +State::State() +: UserData(NULL) +, focusedComponent_(NULL) { } State::~State() { - //Components.~vector(); // just in case // devnote : Nope.jpg Nate :3 -frankbro + for(unsigned i = 0, sz = Components.size(); i < sz; ++i) + if( Components[i] ) + delete Components[i]; } -void State::Add(Component* child) +void State::AddComponent(Component* c) { - Components.push_back(child); - child->Parent = this; + // TODO: do a check if component was already added? + if(c->GetParentState()==NULL) + { + c->SetParentState(this); + Components.push_back(c); + } + else + { + //Component already has a state, don't sad it + } } -void State::Remove(Component* child) +unsigned State::GetComponentCount() { - for(int i = 0; i < Components.size(); i++) - if(Components[i] == child) - { - Components.erase(Components.begin() + i); - break; - } + return Components.size(); } -void State::Draw(void* userdata) +Component* State::GetComponent(unsigned idx) { - //draw - for(int i = 0; i < Components.size(); i++) - { - if(Components[i]->Visible) - { - if(AllowExclusiveDrawing) - { - Components[i]->Draw(userdata); - } - else if( - Components[i]->X + Components[i]->Width >= 0 && - Components[i]->Y + Components[i]->Height >= 0 && - Components[i]->X < width && - Components[i]->Y < height ) - { - Components[i]->Draw(userdata); - } - } - } + return Components[idx]; } -void State::Tick(float dt) +void State::RemoveComponent(Component* c) { - //on mouse hover - for(int i = 0; i < Components.size(); i++) - if( mouseX >= Components[i]->X && - mouseY >= Components[i]->Y && - mouseX < Components[i]->X + Components[i]->Width && - mouseY < Components[i]->Y + Components[i]->Height ) - { - if(Components[i]->Enabled) - { - Components[i]->OnMouseHover(mouseX, mouseY); - } - break; + // remove component WITHOUT freeing it. + for(unsigned i = 0; i < Components.size(); ++i) + { + // find the appropriate component index + if(Components[i] == c) + { + Components.erase(Components.begin() + i); + + // we're done + return; + } + } +} + +void State::RemoveComponent(unsigned idx) +{ + // free component and remove it. + delete Components[idx]; + Components.erase(Components.begin() + idx); +} + +bool State::IsFocused(const Component* c) const +{ + return c == focusedComponent_; +} + +void State::FocusComponent(Component* c) +{ + this->focusedComponent_ = c; +} + +void State::DoExit() +{ + + OnExit(); +} + +void State::DoInitialized() +{ + + OnInitialized(); +} + +void State::DoDraw() +{ + //draw + for(int i = 0, sz = Components.size(); i < sz; ++i) + if(Components[i]->Visible) + { + if(AllowExclusiveDrawing) + { + Point scrpos(Components[i]->Position.X, Components[i]->Position.Y); + Components[i]->Draw(scrpos); + } + else + { + if( Components[i]->Position.X + Components[i]->Size.X >= 0 && + Components[i]->Position.Y + Components[i]->Size.Y >= 0 && + Components[i]->Position.X < ui::Engine::Ref().GetWidth() && + Components[i]->Position.Y < ui::Engine::Ref().GetHeight() ) + { + Point scrpos(Components[i]->Position.X, Components[i]->Position.Y); + Components[i]->Draw( Point(scrpos) ); + } + } } - //tick - for(int i = 0; i < Components.size(); i++) - Components[i]->Tick(dt); + OnDraw(); } -void State::OnKeyPress(int key, bool shift, bool ctrl, bool alt) +void State::DoTick(float dt) +{ + //on mouse hover + for(int i = Components.size() - 1; i >= 0; --i) + { + if(!Components[i]->Locked && + ui::Engine::Ref().GetMouseX() >= Components[i]->Position.X && + ui::Engine::Ref().GetMouseY() >= Components[i]->Position.Y && + ui::Engine::Ref().GetMouseX() < Components[i]->Position.X + Components[i]->Size.X && + ui::Engine::Ref().GetMouseY() < Components[i]->Position.Y + Components[i]->Size.Y ) + { + Components[i]->OnMouseHover(ui::Engine::Ref().GetMouseX() - Components[i]->Position.X, ui::Engine::Ref().GetMouseY() - Components[i]->Position.Y); + break; + } + } + + //tick + for(int i = 0, sz = Components.size(); i < sz; ++i) + { + Components[i]->Tick(dt); + } + + OnTick(dt); +} + +void State::DoKeyPress(int key, bool shift, bool ctrl, bool alt) { //on key press if(focusedComponent_ != NULL) - if(focusedComponent_->Enabled) + { + if(!focusedComponent_->Locked) focusedComponent_->OnKeyPress(key, shift, ctrl, alt); + } + + OnKeyPress(key, shift, ctrl, alt); } -void State::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) +void State::DoKeyRelease(int key, bool shift, bool ctrl, bool alt) { //on key unpress if(focusedComponent_ != NULL) - if(focusedComponent_->Enabled) + { + if(!focusedComponent_->Locked) focusedComponent_->OnKeyRelease(key, shift, ctrl, alt); + } + + OnKeyRelease(key, shift, ctrl, alt); } -void State::OnMouseDown(int x, int y, unsigned int button) +void State::DoMouseDown(int x, int y, unsigned button) { //on mouse click - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + bool clickState = false; + for(int i = Components.size() - 1; i > -1 ; --i) + { + if(!Components[i]->Locked) + { + if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y) { - Components[i]->OnMouseClick(x - Components[i]->X, y - Components[i]->Y, button); - this->focusedComponent_ = Components[i]; //set this component as the focused component + FocusComponent(Components[i]); + Components[i]->OnMouseClick(x - Components[i]->Position.X, y - Components[i]->Position.Y, button); + clickState = true; break; } + } + } + + if(!clickState) + FocusComponent(NULL); //on mouse down - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseDown(x - Components[i]->X, y - Components[i]->Y, button); + for(int i = Components.size() - 1; i > -1 ; --i) + { + if(!Components[i]->Locked) + Components[i]->OnMouseDown(x, y, button); + } + + OnMouseDown(x, y, button); } -void State::OnMouseMove(int x, int y) +void State::DoMouseMove(int x, int y, int dx, int dy) { - //update mouse coords - mouseX = x; - mouseY = y; - //on mouse move (if true, and inside) - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) + for(int i = Components.size() - 1; i > -1 ; --i) + { + if(!Components[i]->Locked) { - int localX = x - Components[i]->X; - int localY = y - Components[i]->Y; - int localXP = mouseXP - Components[i]->X; - int localYP = mouseYP - Components[i]->Y; - int dx = x - mouseXP; - int dy = x - mouseYP; - - Components[i]->OnMouseMoved(localX, localY, dx, dy); - - //is the mouse inside - if(localX >= 0 && - localY >= 0 && - localX < Components[i]->Width && - localY < Components[i]->Height ) - { - //was the mouse outside last tick? - if(localXP < 0 || - localXP >= Components[i]->Width || - localYP < 0 || - localYP >= Components[i]->Height ) - { - Components[i]->OnMouseEnter(localX, localY, dx, dy); - } - - Components[i]->OnMouseMovedInside(localX, localY, dx, dy); - - break; //found the top-most component under mouse, break that shit - } - //not inside, let's see if it used to be inside last tick - else if (localXP >= 0 && - localYP >= 0 && - localXP < Components[i]->Width && - localYP < Components[i]->Height ) - { - Components[i]->OnMouseLeave(localX, localY, x - mouseXP, y - mouseYP); - } + Point local (x - Components[i]->Position.X, y - Components[i]->Position.Y) + , a (local.X - dx, local.Y - dy); + + Components[i]->OnMouseMoved(local.X, local.Y, dx, dy); + + if(local.X >= 0 && + local.Y >= 0 && + local.X < Components[i]->Size.X && + local.Y < Components[i]->Size.Y ) + { + Components[i]->OnMouseMovedInside(local.X, local.Y, dx, dy); + + // entering? + if(!( + a.X >= 0 && + a.Y >= 0 && + a.X < Components[i]->Size.X && + a.Y < Components[i]->Size.Y )) + { + Components[i]->OnMouseEnter(local.X, local.Y); + } + } + else + { + // leaving? + if( a.X >= 0 && + a.Y >= 0 && + a.X < Components[i]->Size.X && + a.Y < Components[i]->Size.Y ) + { + Components[i]->OnMouseLeave(local.X, local.Y); + } + + } } - else //is locked - { - int localX = x - Components[i]->X; - int localY = y - Components[i]->Y; + } - //is the mouse inside - if(localX >= 0 && - localY >= 0 && - localX < Components[i]->Width && - localY < Components[i]->Height ) - { - break; //it's the top-most component under the mouse, we don't want to go under it. - } - } - // end of for loop here - - //set the previous mouse coords - mouseXP = x; - mouseYP = y; + OnMouseMove(x, y, dx, dy); } -void State::OnMouseUp(int x, int y, unsigned int button) +void State::DoMouseUp(int x, int y, unsigned button) { //on mouse unclick - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + for(int i = Components.size() - 1; i >= 0 ; --i) + { + if(!Components[i]->Locked) + { + if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y) { - Components[i]->OnMouseUnclick(x - Components[i]->X, y - Components[i]->Y, button); + Components[i]->OnMouseUnclick(x - Components[i]->Position.X, y - Components[i]->Position.Y, button); break; } + } + } //on mouse up - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseUp(x - Components[i]->X, y - Components[i]->Y, button); + for(int i = Components.size() - 1; i >= 0 ; --i) + { + if(!Components[i]->Locked) + Components[i]->OnMouseUp(x, y, button); + } + + OnMouseUp(x, y, button); } -void State::OnMouseWheel(int x, int y, int d) +void State::DoMouseWheel(int x, int y, int d) { - //focused mouse wheel - if(focusedComponent_ != NULL) - focusedComponent_->OnMouseWheelFocused(x - focusedComponent_->X, y - focusedComponent_->Y, d); - - //mouse wheel inside - for(int i = Components.size() - 1; i > -1 ; i--) - if(x >= Components[i]->X && y >= Components[i]->Y && x < Components[i]->X + Components[i]->Width && y < Components[i]->Y + Components[i]->Height) + //on mouse wheel focused + for(int i = Components.size() - 1; i >= 0 ; --i) + { + if(x >= Components[i]->Position.X && y >= Components[i]->Position.Y && x < Components[i]->Position.X + Components[i]->Size.X && y < Components[i]->Position.Y + Components[i]->Size.Y) { - if(Components[i]->Enabled) - Components[i]->OnMouseWheelInside(x - Components[i]->X, y - Components[i]->Y, d); - break; //found top-most component under mouse + if(!Components[i]->Locked) + Components[i]->OnMouseWheelInside(x - Components[i]->Position.X, y - Components[i]->Position.Y, d); + break; } - + } + //on mouse wheel - for(int i = Components.size() - 1; i > -1 ; i--) - if(Components[i]->Enabled) - Components[i]->OnMouseWheel(x - Components[i]->X, y - Components[i]->Y, d); + for(int i = Components.size() - 1; i >= 0 ; --i) + { + if(!Components[i]->Locked) + Components[i]->OnMouseWheel(x - Components[i]->Position.X, y - Components[i]->Position.Y, d); + } + + OnMouseWheel(x, y, d); } - - -} /* namespace ui */