diff --git a/Contributing.md b/Contributing.md index cc529bf..55f4c1a 100644 --- a/Contributing.md +++ b/Contributing.md @@ -5,9 +5,10 @@ - Install the necessary dependencies found on the README.md - Clone the repository - Open in VSCode -- From the root of the repository make a branch - - ```git checkout -b ``` +- From the root of the repository make a branch according to your feature or bug + - ```git checkout -b ``` - This is the branch you will make your changes in + - Always make sure you base your branch off of the updated master branch!! - Make a virtual python enviornment in the repository - ```python -m venv dev``` - Load into the environment @@ -18,9 +19,10 @@ - Any changes now made in the local version of the package will be on the branch and reflected in the environment ## Developing -- Before changing code, verify that you're writing on a branch other than ```main``` and that your command line is in the virtual enviornment +- Before changing code, verify that you're writing on your new branch and that your command line is in the virtual enviornment - Develop and make some changes - To test the package features create a file in the root of the repository called ```test.py``` - In ```test.py``` import mediaComp with ```from mediaComp import *``` - Test the features you were working on and continue developing, making commits when progess is made - When finished working on a feature, push the branch to GitHub and open a pull request to merge your branch into ```main``` +- Request review from Dave Largent diff --git a/README.md b/README.md index af50efe..4c649c0 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ MediaComp is strongly dependent on several libraries. Most of the these will ins | wxPython | > 4.2.0 | | pillow | > 11.0.0 | | pygame | > 2.5.0 | -| matplotlib | >= 3.10.0 | | numpy | >= 2.2.1 | | sounddevice | >= 0.5.2 | diff --git a/pyproject.toml b/pyproject.toml index d773724..e9edfd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ version = "0.4.10" dependencies = [ "pillow>11.0.0", "pygame>2.5.0", - "matplotlib>=3.10.0", "numpy>=2.2.1", "sounddevice>=0.5.2", ] diff --git a/src/mediaComp/__init__.py b/src/mediaComp/__init__.py index 3ee9b2b..b507a4c 100644 --- a/src/mediaComp/__init__.py +++ b/src/mediaComp/__init__.py @@ -29,12 +29,10 @@ def _cleanup_if_last_window(): getPixelAt, setRed, setGreen, setBlue, getRed, getGreen, getBlue, getColor, setColor, getX, getY, writePictureTo, setAllPixelsToAColor, copyInto, duplicatePicture, cropPicture, calculateNeededFiller, requestInteger, requestNumber, requestIntegerInRange, requestString, showWarning, showInformation, showError, - playMovie, writeQuicktime, writeAVI, makeMovie, makeMovieFromInitialFile, addFrameToMovie, writeFramesToDirectory, samplesToSound, makeSound, makeEmptySound, makeEmptySoundBySeconds, duplicateSound, getSamples, soundTool, play, stopPlaying, playAtRate, playAtRateDur, getSampleAt, playInRange, playAtRateInRange, getSamplingRate, getSampleValueAt, setSampleValueAt, setSampleValue, getSampleValue, getSound, getNumSamples, getDuration, writeSoundTo, randomSamples, getIndex, - playNote, turn, turnRight, turnToFace, turnLeft, forward, backward, moveTo, makeTurtle, penUp, - penDown, drop, getXPos, getYPos, getHeading, makeWorld, getTurtleList, blue, red, + playNote, blue, red, green, gray, darkGray, lightGray, yellow, orange, pink, magenta, cyan, white, black ) @@ -47,12 +45,10 @@ def _cleanup_if_last_window(): "getPixelAt", "setRed", "setGreen", "setBlue", "getRed", "getGreen", "getSampleAt", "getBlue", "getColor", "setColor", "getX", "getY", "writePictureTo", "setAllPixelsToAColor", "copyInto", "duplicatePicture", "cropPicture", "calculateNeededFiller", "requestInteger", "requestNumber", "requestIntegerInRange", "requestString", "showWarning", "showInformation", "showError", - "playMovie", "writeQuicktime", "writeAVI", "makeMovie", "makeMovieFromInitialFile", "addFrameToMovie", "writeFramesToDirectory", "samplesToSound", "makeSound", "makeEmptySound", "makeEmptySoundBySeconds", "duplicateSound", "getSamples", "soundTool", "play", "stopPlaying", "playAtRate", "playAtRateDur", "playInRange", "playAtRateInRange", "getSamplingRate", "getSampleValueAt", "setSampleValueAt", "setSampleValue", "getSampleValue", "getSound", "getNumSamples", "getDuration", "writeSoundTo", "randomSamples", "getIndex", - "playNote", "turn", "turnRight", "turnToFace", "turnLeft", "forward", "backward", "moveTo", "makeTurtle", "penUp", - "penDown", "drop", "getXPos", "getYPos", "getHeading", "makeWorld", "getTurtleList", "blue", "red", + "playNote", "blue", "red", "green", "gray", "darkGray", "lightGray", "yellow", "orange", "pink", "magenta", "cyan", "white", "black", "config" ] diff --git a/src/mediaComp/core/__init__.py b/src/mediaComp/core/__init__.py index e0329f1..30366d8 100644 --- a/src/mediaComp/core/__init__.py +++ b/src/mediaComp/core/__init__.py @@ -1,7 +1,4 @@ from .color import * from .utils import * from .image import * -from .movie import * -from .sound import * -from .turtle import * -from .world import * \ No newline at end of file +from .sound import * \ No newline at end of file diff --git a/src/mediaComp/core/movie.py b/src/mediaComp/core/movie.py deleted file mode 100644 index c238837..0000000 --- a/src/mediaComp/core/movie.py +++ /dev/null @@ -1,83 +0,0 @@ -from ..models.Movie import Movie -import os - - -def playMovie(movie) -> None: - if isinstance(movie, Movie): - movie.play() - else: - print("playMovie( movie ): Input is not a Movie") - raise ValueError - - -def writeQuicktime(movie, destPath, framesPerSec=16) -> None: - if not (isinstance(movie, Movie)): - print("writeQuicktime(movie, path[, framesPerSec]): First input is not a Movie") - raise ValueError - if framesPerSec <= 0: - print("writeQuicktime(movie, path[, framesPerSec]): Frame rate must be a positive number") - raise ValueError - movie.writeQuicktime(destPath, framesPerSec) - - -def writeAVI(movie, destPath, framesPerSec=16) -> None: - if not (isinstance(movie, Movie)): - print("writeAVI(movie, path[, framesPerSec]): First input is not a Movie") - raise ValueError - if framesPerSec <= 0: - print("writeAVI(movie, path[, framesPerSec]): Frame rate must be a positive number") - raise ValueError - movie.writeAVI(destPath, framesPerSec) - - -def makeMovie() -> Movie: - return Movie() - - -def makeMovieFromInitialFile(filename) -> Movie: - import re - movie = Movie() - global mediaFolder - filename = filename.replace('/', os.sep) - sep_location = filename.rfind(os.sep) - if(-1 == sep_location): - filename = mediaFolder + filename - - movie.directory = filename[:(filename.rfind(os.sep))] - movie.init_file = filename[(filename.rfind(os.sep)) + 1:] - regex = re.compile('[0-9]+') - file_regex = regex.sub('.*', movie.init_file) - - for item in sorted(os.listdir(movie.directory)): - if re.match(file_regex, item): - movie.addFrame(movie.directory + os.sep + item) - - return movie - - -def addFrameToMovie(a, b) -> None: - frame = None - movie = None - if a.__class__ == Movie: - movie = a - frame = b - else: - movie = b - frame = a - - if not (isinstance(movie, Movie) and isinstance(frame, str)): - print("addFrameToMovie(frame, movie): frame is not a string or movie is not a Movie object") - raise ValueError - - movie.addFrame(frame) - - -def writeFramesToDirectory(movie, directory=None) -> None: - if not isinstance(movie, Movie): - print("writeFramesToDirectory(movie[, directory]): movie is not a Movie object") - raise ValueError - - if directory == None: - directory = user.home - - movie.writeFramesToDirectory(directory) \ No newline at end of file diff --git a/src/mediaComp/core/root_manager.py b/src/mediaComp/core/root_manager.py new file mode 100644 index 0000000..98037fc --- /dev/null +++ b/src/mediaComp/core/root_manager.py @@ -0,0 +1,25 @@ +import tkinter as tk + +_root = None +_mainloop_started = False + +def get_root(): + global _root + if _root is None: + _root = tk.Tk() + _root.withdraw() + return _root + + +def start_mainloop(): + global _mainloop_started + root = get_root() + if not _mainloop_started: + _mainloop_started = True + root.mainloop() + +def _cleanup_if_last_window(): + global _root + if _root and _root.winfo_exists() and not _root.winfo_children(): + _root.destroy() + _root = None \ No newline at end of file diff --git a/src/mediaComp/core/turtle.py b/src/mediaComp/core/turtle.py deleted file mode 100644 index 22b84f9..0000000 --- a/src/mediaComp/core/turtle.py +++ /dev/null @@ -1,117 +0,0 @@ -from ..models.Picture import Picture -from turtle import Turtle - -def turn(turtle, degrees=90) -> None: - if not isinstance(turtle, Turtle): - print("turn(turtle[, degrees]): Input is not a turtle") - raise ValueError - else: - turtle.turn(degrees) - - -def turnRight(turtle) -> None: - if not isinstance(turtle, Turtle): - print("turnRight(turtle): Input is not a turtle") - raise ValueError - else: - turtle.turnRight() - - -def turnToFace(turtle, x, y=None) -> None: - if y == None: - if not (isinstance(turtle, Turtle) and isinstance(x, Turtle)): - print("turnToFace(turtle, turtle): First input is not a turtle") - raise ValueError - else: - turtle.turnToFace(x) - else: - if not isinstance(turtle, Turtle): - print("turnToFace(turtle, x, y): Input is not a turtle") - raise ValueError - else: - turtle.turnToFace(x, y) - - -def turnLeft(turtle) -> None: - if not isinstance(turtle, Turtle): - print("turnLeft(turtle): Input is not a turtle") - raise ValueError - else: - turtle.turnLeft() - - -def forward(turtle, pixels=100) -> None: - if not isinstance(turtle, Turtle): - print("forward(turtle[, pixels]): Input is not a turtle") - raise ValueError - else: - turtle.forward(pixels) - - -def backward(turtle, pixels=100) -> None: - if not isinstance(turtle, Turtle): - print("backward(turtle[, pixels]): Input is not a turtle") - raise ValueError - if (None == pixels): - turtle.backward() - else: - turtle.backward(pixels) - - -def moveTo(turtle, x, y) -> None: - if not isinstance(turtle, Turtle): - print("moveTo(turtle, x, y): Input is not a turtle") - raise ValueError - turtle.moveTo(x, y) - - -def makeTurtle(world) -> Turtle: - if not (isinstance(world, World) or isinstance(world, Picture)): - print("makeTurtle(world): Input is not a world or picture") - raise ValueError - turtle = Turtle(world) - return turtle - - -def penUp(turtle) -> None: - if not isinstance(turtle, Turtle): - print("penUp(turtle): Input is not a turtle") - raise ValueError - turtle.penUp() - - -def penDown(turtle) -> None: - if not isinstance(turtle, Turtle): - print("penDown(turtle): Input is not a turtle") - raise ValueError - turtle.penDown() - - -def drop(turtle, picture) -> None: - if not isinstance(turtle, Turtle): - print("drop(turtle, picture): First input is not a turtle") - raise ValueError - if not isinstance(picture, Picture): - print("drop(turtle, picture): Second input is not a picture") - raise ValueError - turtle.drop(picture) - -def getXPos(turtle) -> int: - if not isinstance(turtle, Turtle): - print("getXPos(turtle): Input is not a turtle") - raise ValueError - return turtle.getXPos() - - -def getYPos(turtle) -> int: - if not isinstance(turtle, Turtle): - print("getYPos(turtle): Input is not a turtle") - raise ValueError - return turtle.getYPos() - - -def getHeading(turtle) -> int: - if not isinstance(turtle, Turtle): - print("getHeading(turtle): Input is not a turtle") - raise ValueError - return turtle.getHeading() \ No newline at end of file diff --git a/src/mediaComp/core/utils.py b/src/mediaComp/core/utils.py index 1b2dc70..ad69ed0 100644 --- a/src/mediaComp/core/utils.py +++ b/src/mediaComp/core/utils.py @@ -3,7 +3,6 @@ import subprocess from math import inf import tkinter as tk -from tkinter import messagebox from ..models.Config import ConfigManager from pathlib import Path from mediaComp import get_root, _cleanup_if_last_window diff --git a/src/mediaComp/core/world.py b/src/mediaComp/core/world.py deleted file mode 100644 index 81ef2a7..0000000 --- a/src/mediaComp/core/world.py +++ /dev/null @@ -1,14 +0,0 @@ - -def makeWorld(width=None, height=None): - if(width and height): - w = World(width, height) - else: - w = World() - return w - - -def getTurtleList(world): - if not isinstance(world, World): - print("getTurtleList(world): Input is not a world") - raise ValueError - return world.getTurtleList() \ No newline at end of file diff --git a/src/mediaComp/models/Movie.py b/src/mediaComp/models/Movie.py deleted file mode 100644 index 6859790..0000000 --- a/src/mediaComp/models/Movie.py +++ /dev/null @@ -1,36 +0,0 @@ -from .Picture import Picture -from ..core import makePicture - -class Movie(object): - def __init__(self): - self.frames = [] - self.dir = None - - def addFrame(self, frame): - self.frames.append(frame) - self.dir = None - - def __len__(self): - return len(self.frames) - - def __str__(self): - return "Movie, frames: " + str(len(self)) - - def __repr__(self): - return "Movie, frames: " + str(len(self)) - - def __getitem__(self, item): - return self.frames[item] - - def writeFramesToDirectory(self, directory): - import FrameSequencer - fs = FrameSequencer(directory) - for frameindex in range(0, len(self.frames)): - fs.addFrame(Picture(self.frames[frameindex])) - self.dir = directory - - def play(self): - list = [] - for f in self.frames: - list.add(makePicture(f)) - MoviePlayer(list).playMovie() \ No newline at end of file diff --git a/src/mediaComp/models/Picture.py b/src/mediaComp/models/Picture.py index 6b74f11..00f760b 100644 --- a/src/mediaComp/models/Picture.py +++ b/src/mediaComp/models/Picture.py @@ -1,5 +1,5 @@ from . import File_Chooser as FileChooser -import os, tempfile, subprocess, sys, atexit, pickle +import os, tempfile, subprocess, sys, pickle from subprocess import PIPE import PIL.ImageDraw, PIL.Image from .PixelColor import Pixel, Color diff --git a/src/mediaComp/models/Sound.py b/src/mediaComp/models/Sound.py index 30682b8..f9b141b 100644 --- a/src/mediaComp/models/Sound.py +++ b/src/mediaComp/models/Sound.py @@ -1,10 +1,8 @@ from .SoundSample import SoundSample import wave import os -#import simpleaudio as sa import pygame import threading - import sounddevice as sd import numpy as np diff --git a/src/mediaComp/models/SoundExplorer.py b/src/mediaComp/models/SoundExplorer.py index c36f0c4..0d4bd58 100644 --- a/src/mediaComp/models/SoundExplorer.py +++ b/src/mediaComp/models/SoundExplorer.py @@ -4,8 +4,6 @@ from tkinter import ttk from .Sound import Sound import re -import sounddevice as sd -import numpy as np class MouseMotionListener(ABC): @abstractmethod