added dropdown menus
This commit is contained in:
@@ -211,23 +211,38 @@ namespace RisingCubes{
|
|||||||
.delay = std::chrono::milliseconds(1)
|
.delay = std::chrono::milliseconds(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
AnimationFrame frame0{
|
AnimationFrame frame00{
|
||||||
.frame = {
|
.frame = {
|
||||||
CreateCell(0.0,0.0,0.0,V3D<uint8_t>(255.0,255.0,255.0)),
|
CreateCell(0.0,0.0,1.0,V3D<uint8_t>(128.0,128.0,255.0)),
|
||||||
CreateCell(0.0,0.5,0.0,V3D<uint8_t>(0.0,255.0,0.0)),
|
CreateCell(0.5,0.0,1.0,V3D<uint8_t>(128.0,128.0,255.0)),
|
||||||
CreateCell(0.0,1.0,0.0,V3D<uint8_t>(0.0,255.0,0.0)),
|
CreateCell(1.0,0.0,0.0,V3D<uint8_t>(255.0,118.0,205.0)),
|
||||||
CreateCell(0.0,0.0,0.5,V3D<uint8_t>(0.0,0.0,255.0)),
|
CreateCell(1.0,0.0,0.5,V3D<uint8_t>(255.0,118.0,205.0)),
|
||||||
CreateCell(0.0,0.0,1.0,V3D<uint8_t>(0.0,0.0,255.0)),
|
CreateCell(1.0,0.0,1.0,V3D<uint8_t>(255.0,116.0,0.0)),
|
||||||
CreateCell(0.5,0.0,0.0,V3D<uint8_t>(255.0,0.0,0.0)),
|
CreateCell(1.0,0.5,1.0,V3D<uint8_t>(183.0,0.0,255.0)),
|
||||||
CreateCell(1.0,0.0,0.0,V3D<uint8_t>(255.0,0.0,0.0))
|
CreateCell(1.0,1.0,1.0,V3D<uint8_t>(183.0,0.0,255.0))
|
||||||
},
|
},
|
||||||
.fillInterpolation = FillInterpolation::NO_FILL,
|
.fillInterpolation = FillInterpolation::CLOSEST_COLOR,
|
||||||
|
.frameInterpolation = FrameInterpolation::FADE,
|
||||||
|
.delay = std::chrono::milliseconds(1000)
|
||||||
|
};
|
||||||
|
|
||||||
|
AnimationFrame frame01{
|
||||||
|
.frame = {
|
||||||
|
CreateCell(0.0,0.0,1.0,V3D<uint8_t>(255.0,255.0,171.0)),
|
||||||
|
CreateCell(0.5,0.0,1.0,V3D<uint8_t>(255.0,255.0,171.0)),
|
||||||
|
CreateCell(1.0,0.0,0.0,V3D<uint8_t>(0.0,195.0,88.0)),
|
||||||
|
CreateCell(1.0,0.0,0.5,V3D<uint8_t>(0.0,195.0,88.0)),
|
||||||
|
CreateCell(1.0,0.0,1.0,V3D<uint8_t>(0.0,195.0,88.0)),
|
||||||
|
CreateCell(1.0,0.5,1.0,V3D<uint8_t>(112.0,222.0,255.0)),
|
||||||
|
CreateCell(1.0,1.0,1.0,V3D<uint8_t>(112.0,222.0,255.0))
|
||||||
|
},
|
||||||
|
.fillInterpolation = FillInterpolation::CLOSEST_COLOR,
|
||||||
.frameInterpolation = FrameInterpolation::FADE,
|
.frameInterpolation = FrameInterpolation::FADE,
|
||||||
.delay = std::chrono::milliseconds(1000)
|
.delay = std::chrono::milliseconds(1000)
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<AnimationFrame> rising{
|
std::vector<AnimationFrame> rising{
|
||||||
frame0, frame0
|
frame00, frame01, frame00
|
||||||
// frame1, // 0
|
// frame1, // 0
|
||||||
// frame2, // 1
|
// frame2, // 1
|
||||||
// frame3, // 2
|
// frame3, // 2
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ class FillInterpolation(StrEnum):
|
|||||||
CLOSEST_COLOR = "CLOSEST_COLOR"
|
CLOSEST_COLOR = "CLOSEST_COLOR"
|
||||||
LINEAR_WEIGHTED_DISTANCE = "LINEAR_WEIGHTED_DISTANCE"
|
LINEAR_WEIGHTED_DISTANCE = "LINEAR_WEIGHTED_DISTANCE"
|
||||||
SQUARE_WEIGHTED_DISTANCE = "SQUARE_WEIGHTED_DISTANCE"
|
SQUARE_WEIGHTED_DISTANCE = "SQUARE_WEIGHTED_DISTANCE"
|
||||||
|
# options = [NO_FILL, CLOSEST_COLOR, LINEAR_WEIGHTED_DISTANCE, SQUARE_WEIGHTED_DISTANCE]
|
||||||
|
|
||||||
class FrameInterpolation(StrEnum):
|
class FrameInterpolation(StrEnum):
|
||||||
SNAP = "SNAP"
|
SNAP = "SNAP"
|
||||||
FADE = "FADE"
|
FADE = "FADE"
|
||||||
|
# options = [SNAP, FADE]
|
||||||
|
|
||||||
class Cell:
|
class Cell:
|
||||||
def __init__(self, position: Vector3, color: Vector3):
|
def __init__(self, position: Vector3, color: Vector3):
|
||||||
@@ -68,7 +70,7 @@ def mesh_to_cell(mesh: Mesh) -> Cell:
|
|||||||
cell = Cell(pos, Vector3(mesh.face_color))
|
cell = Cell(pos, Vector3(mesh.face_color))
|
||||||
return cell
|
return cell
|
||||||
|
|
||||||
def scene_to_frame(scene: Scene, scene_number: int) -> str:
|
def scene_to_frame(scene: Scene, fill_interpolation: FillInterpolation, frame_interpolation: FrameInterpolation, delay: int, scene_number: int) -> str:
|
||||||
cells = [mesh_to_cell(cube) for cube in scene.meshes]
|
cells = [mesh_to_cell(cube) for cube in scene.meshes]
|
||||||
frame = AnimationFrame(cells, FillInterpolation.NO_FILL, FrameInterpolation.FADE, 1000)
|
frame = AnimationFrame(cells, FillInterpolation.NO_FILL, FrameInterpolation.FADE, 1000)
|
||||||
return frame.to_string(scene_number)
|
return frame.to_string(scene_number)
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
from pygame_widgets.slider import Slider
|
|
||||||
|
|
||||||
class ColorPicker:
|
|
||||||
def __init__(self, screen, x_pos: int, y_pos: int, width: int, height: int):
|
|
||||||
width = max(50, width)
|
|
||||||
self.sliders: list[Slider] = [
|
|
||||||
Slider(screen, int(x_pos + i*(width/3)), y_pos, int((width-50)/3), height, min=0, max=255, step=1, vertical=True) for i in range(3)
|
|
||||||
]
|
|
||||||
for slider in self.sliders:
|
|
||||||
slider.enable()
|
|
||||||
|
|
||||||
def get_color(self) -> tuple[int]:
|
|
||||||
# return (0,0,0)
|
|
||||||
return tuple([slider.getValue() for slider in self.sliders])
|
|
||||||
|
|
||||||
def set_color(self, color: tuple[int]):
|
|
||||||
for i, slider in enumerate(self.sliders):
|
|
||||||
slider.setValue(color[i])
|
|
||||||
@@ -1,15 +1,41 @@
|
|||||||
from AnimationExporter import scene_to_frame
|
|
||||||
from CustomWidgets import ColorPicker
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from pygame_widgets.button import Button
|
from pygame_widgets.button import Button
|
||||||
|
from pygame_widgets.slider import Slider
|
||||||
|
from pygame_widgets.dropdown import Dropdown
|
||||||
|
from pygame_widgets.textbox import TextBox
|
||||||
from Scene import Scene
|
from Scene import Scene
|
||||||
from Shapes import *
|
from Shapes import *
|
||||||
import pygame
|
import pygame
|
||||||
|
from AnimationExporter import *
|
||||||
|
|
||||||
|
class ColorPicker:
|
||||||
|
def __init__(self, screen, x_pos: int, y_pos: int, width: int, height: int):
|
||||||
|
width = max(50, width)
|
||||||
|
slider_colors = ((255,0,0),(0,255,0),(0,0,255))
|
||||||
|
self.sliders: list[Slider] = [
|
||||||
|
Slider(screen, int(x_pos + i*(width/3)), y_pos, int((width-50)/3), height, min=0, max=255, step=1, vertical=True, handleColour=slider_colors[i]) for i in range(3)
|
||||||
|
]
|
||||||
|
for slider in self.sliders:
|
||||||
|
slider.enable()
|
||||||
|
|
||||||
|
def get_color(self) -> tuple[int]:
|
||||||
|
return tuple([slider.getValue() for slider in self.sliders])
|
||||||
|
|
||||||
|
def set_color(self, color: tuple[int]):
|
||||||
|
for i, slider in enumerate(self.sliders):
|
||||||
|
slider.setValue(color[i])
|
||||||
|
|
||||||
|
class SceneStore:
|
||||||
|
def __init__(self, scene: Scene, fill: FillInterpolation, fade: FrameInterpolation, delay: int):
|
||||||
|
self.scene: Scene = scene
|
||||||
|
self.fill: FillInterpolation = fill
|
||||||
|
self.fade: FrameInterpolation = fade
|
||||||
|
self.delay: int = delay
|
||||||
|
|
||||||
class SceneManager:
|
class SceneManager:
|
||||||
def __init__(self, window, color_picker: ColorPicker):
|
def __init__(self, window, color_picker: ColorPicker):
|
||||||
self.file_data: str = ""
|
self.file_data: str = ""
|
||||||
self._scenes: list[Scene] = [self.new_scene()]
|
self._scenes: list[SceneStore] = [SceneStore(self.new_scene(), FillInterpolation.NO_FILL, FrameInterpolation.FADE, 1000)]
|
||||||
self._current_scene_idx: int = 0
|
self._current_scene_idx: int = 0
|
||||||
self.window = window
|
self.window = window
|
||||||
self.color_picker = color_picker
|
self.color_picker = color_picker
|
||||||
@@ -18,7 +44,7 @@ class SceneManager:
|
|||||||
def save_frame_to_file(self):
|
def save_frame_to_file(self):
|
||||||
with open("tools/animation-tools/output.txt", 'w') as file:
|
with open("tools/animation-tools/output.txt", 'w') as file:
|
||||||
for i, scene in enumerate(self._scenes):
|
for i, scene in enumerate(self._scenes):
|
||||||
file.write(scene_to_frame(scene, i))
|
file.write(scene_to_frame(scene.scene, scene.fill_interpolation, scene.frame_interpolation, scene.delay, i))
|
||||||
|
|
||||||
def generate_meshes(self) -> list[Mesh]:
|
def generate_meshes(self) -> list[Mesh]:
|
||||||
# generate a list of cubes
|
# generate a list of cubes
|
||||||
@@ -37,13 +63,13 @@ class SceneManager:
|
|||||||
def draw(self):
|
def draw(self):
|
||||||
for mesh in self._selected_meshes:
|
for mesh in self._selected_meshes:
|
||||||
mesh.set_face_color(self.color_picker.get_color())
|
mesh.set_face_color(self.color_picker.get_color())
|
||||||
self.get_current_scene().draw(self.window)
|
self.get_current_scene().scene.draw(self.window)
|
||||||
|
|
||||||
def get_current_scene(self) -> Scene:
|
def get_current_scene(self) -> SceneStore:
|
||||||
return self._scenes[self._current_scene_idx]
|
return self._scenes[self._current_scene_idx]
|
||||||
|
|
||||||
def click_mesh(self, coordinates: tuple[int, int]):
|
def click_mesh(self, coordinates: tuple[int, int]):
|
||||||
mesh = self.get_current_scene().get_mesh_from_xy(coordinates)
|
mesh = self.get_current_scene().scene.get_mesh_from_xy(coordinates)
|
||||||
|
|
||||||
if mesh == None:
|
if mesh == None:
|
||||||
return
|
return
|
||||||
@@ -62,35 +88,61 @@ class SceneManager:
|
|||||||
|
|
||||||
def next_scene(self):
|
def next_scene(self):
|
||||||
self.deselect_all_mesh()
|
self.deselect_all_mesh()
|
||||||
current_angles = self.get_current_scene().euler_angles
|
current_angles = self.get_current_scene().scene.euler_angles
|
||||||
if len(self._scenes)-1 == self._current_scene_idx:
|
if len(self._scenes)-1 == self._current_scene_idx:
|
||||||
self._scenes.append(self.new_scene())
|
self._scenes.append(SceneStore(self.new_scene(), FillInterpolation.NO_FILL, FrameInterpolation.FADE, 1000))
|
||||||
|
|
||||||
self._current_scene_idx += 1
|
self._current_scene_idx += 1
|
||||||
|
|
||||||
self.get_current_scene().euler_angles = [angle for angle in current_angles]
|
self.get_current_scene().scene.euler_angles = [angle for angle in current_angles]
|
||||||
|
|
||||||
def previous_scene(self):
|
def last_scene(self):
|
||||||
if self._current_scene_idx > 0:
|
if self._current_scene_idx > 0:
|
||||||
current_angles = self.get_current_scene().euler_angles
|
current_angles = self.get_current_scene().scene.euler_angles
|
||||||
self._current_scene_idx -= 1
|
self._current_scene_idx -= 1
|
||||||
self.get_current_scene().euler_angles = [angle for angle in current_angles]
|
self.get_current_scene().scene.euler_angles = [angle for angle in current_angles]
|
||||||
self.deselect_all_mesh()
|
self.deselect_all_mesh()
|
||||||
|
|
||||||
|
def update_scene_options(self, fill: FillInterpolation, fade: FrameInterpolation, delay: int):
|
||||||
|
cur_scene: SceneStore = self.get_current_scene()
|
||||||
|
cur_scene.fill = fill
|
||||||
|
cur_scene.fade = fade
|
||||||
|
cur_scene.delay = delay
|
||||||
|
|
||||||
class AnimatorUI:
|
class AnimatorUI:
|
||||||
def __init__(self, window):
|
def __init__(self, window):
|
||||||
scr_wdt, scr_hgt = window.get_size()
|
scr_wdt, scr_hgt = window.get_size()
|
||||||
|
|
||||||
self.window = window
|
self.window = window
|
||||||
colorPicker: ColorPicker = ColorPicker(self.window, 20, 20, 100, 300)
|
self.colorPicker: ColorPicker = ColorPicker(self.window, *self.rel2abs(5, 5, 20, 60))
|
||||||
self.sceneManager: SceneManager = SceneManager(window, colorPicker)
|
self.sceneManager: SceneManager = SceneManager(window, self.colorPicker)
|
||||||
|
|
||||||
|
self.save_button: Button = Button(self.window, *self.rel2abs(5, 90, 10, 10), text="Save",onClick=self.sceneManager.save_frame_to_file)
|
||||||
self.save_button: Button = Button(self.window, 20, scr_hgt-40, 60, 30, text="Save",onClick=self.sceneManager.save_frame_to_file)
|
self.next_frame_button: Button = Button(self.window, *self.rel2abs(75, 90, 25, 5), text="Next Frame",onClick=self._next_scene)
|
||||||
self.next_frame_button: Button = Button(self.window, scr_wdt-120, scr_hgt-40, 120, 30, text="Next Frame",onClick=self.sceneManager.next_scene)
|
self.last_frame_button: Button = Button(self.window, *self.rel2abs(50, 90, 25, 5), text="last Frame",onClick=self._last_scene)
|
||||||
self.last_frame_button: Button = Button(self.window, scr_wdt-240, scr_hgt-40, 120, 30, text="last Frame",onClick=self.sceneManager.previous_scene)
|
|
||||||
self.trackMouseMotion: bool = False
|
self.trackMouseMotion: bool = False
|
||||||
|
|
||||||
|
self.fill_dropdown: Dropdown = Dropdown(self.window, *self.rel2abs(30, 0, 40, 5), name="Fill Type",
|
||||||
|
choices=[option.value for option in FillInterpolation], onRelease=self.set_update_options_flag)
|
||||||
|
|
||||||
|
self.fade_dropdown: Dropdown = Dropdown(self.window, *self.rel2abs(70, 0, 20, 5), name="Fade Type",
|
||||||
|
choices=[option.value for option in FrameInterpolation], onRelease=self.set_update_options_flag)
|
||||||
|
|
||||||
|
self.updateOptions = False
|
||||||
|
self._set_dropdown_options()
|
||||||
|
|
||||||
|
# TODO: add delay field
|
||||||
|
# TODO: Make a frame counter
|
||||||
|
|
||||||
|
def rel2abs(self, x: float, y: float, width: float, height: float) -> tuple[int,int,int,int]:
|
||||||
|
scr_wdt, scr_hgt = self.window.get_size()
|
||||||
|
x_abs = int(x*scr_wdt/100)
|
||||||
|
y_abs = int(y*scr_hgt/100)
|
||||||
|
w_abs = int(width*scr_wdt/100)
|
||||||
|
h_abs = int(height*scr_hgt/100)
|
||||||
|
return (x_abs, y_abs, w_abs, h_abs)
|
||||||
|
|
||||||
|
|
||||||
def update_interaction(self, game_event):
|
def update_interaction(self, game_event):
|
||||||
if not self.trackMouseMotion:
|
if not self.trackMouseMotion:
|
||||||
pygame.mouse.get_rel()
|
pygame.mouse.get_rel()
|
||||||
@@ -110,4 +162,39 @@ class AnimatorUI:
|
|||||||
current_scene.euler_angles[1] -= mouseMovement[0]
|
current_scene.euler_angles[1] -= mouseMovement[0]
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
if self.updateOptions:
|
||||||
|
self.set_scene_options()
|
||||||
|
# make the preview window for the color picker
|
||||||
|
pygame.draw.rect(self.window, self.colorPicker.get_color(), self.rel2abs(11, 70, 5, 5))
|
||||||
|
pygame.draw.rect(self.window, (0,0,0), self.rel2abs(11, 70, 5, 5), 2)
|
||||||
|
|
||||||
self.sceneManager.draw()
|
self.sceneManager.draw()
|
||||||
|
|
||||||
|
def _next_scene(self):
|
||||||
|
self.sceneManager.next_scene()
|
||||||
|
self._set_dropdown_options()
|
||||||
|
|
||||||
|
|
||||||
|
def _last_scene(self):
|
||||||
|
self.sceneManager.last_scene()
|
||||||
|
self._set_dropdown_options()
|
||||||
|
|
||||||
|
def _set_dropdown_options(self):
|
||||||
|
scene = self.sceneManager.get_current_scene()
|
||||||
|
for choice in self.fill_dropdown._Dropdown__choices:
|
||||||
|
if choice.text.find(scene.fill) != -1:
|
||||||
|
self.fill_dropdown.chosen = choice
|
||||||
|
break
|
||||||
|
|
||||||
|
for choice in self.fade_dropdown._Dropdown__choices:
|
||||||
|
if choice.text.find(scene.fade) != -1:
|
||||||
|
self.fade_dropdown.chosen = choice
|
||||||
|
break
|
||||||
|
|
||||||
|
def set_update_options_flag(self):
|
||||||
|
self.updateOptions = True
|
||||||
|
|
||||||
|
def set_scene_options(self):
|
||||||
|
self.updateOptions = False
|
||||||
|
self.sceneManager.update_scene_options(self.fill_dropdown.getSelected(), self.fade_dropdown.getSelected(), 1000)
|
||||||
|
current_scene = self.sceneManager.get_current_scene()
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import pygame
|
import pygame
|
||||||
import pygame_widgets
|
import pygame_widgets
|
||||||
from Shapes import *
|
from Shapes import *
|
||||||
from Scene import Scene
|
|
||||||
from UI import AnimatorUI
|
from UI import AnimatorUI
|
||||||
|
|
||||||
WINDOW_W = 500
|
WINDOW_W = 500
|
||||||
|
|||||||
Reference in New Issue
Block a user