Codebase list soundgrain / lintian-fixes/main Resources / FxBall.py
lintian-fixes/main

Tree @lintian-fixes/main (Download .tar.gz)

FxBall.py @lintian-fixes/mainraw · history · blame

"""
Copyright 2009-2017 Olivier Belanger

This file is part of SoundGrain.

SoundGrain is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

SoundGrain is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with SoundGrain.  If not, see <http://www.gnu.org/licenses/>.
"""
import wx, math
from .constants import *
from pyolib._wxwidgets import ControlSlider

class FxBallControls(wx.Frame):
    def __init__(self, parent, fxball, sg_audio, size=(270, 200)):
        title = "%s Controls" % FX_BALL_TITLES[fxball.getFx()]
        wx.Frame.__init__(self, parent, -1, title, size=size)
        self.parent = parent
        self.fxball = fxball
        self.sg_audio = sg_audio
        menuBar = wx.MenuBar()
        self.menu = wx.Menu()
        self.menu.Append(200, 'Close\tCtrl+W', "")
        menuBar.Append(self.menu, "&File")
        self.SetMenuBar(menuBar)

        self.Bind(wx.EVT_CLOSE, self.handleClose)
        self.Bind(wx.EVT_MENU, self.handleClose, id=200)

        self.panel = wx.Panel(self, -1)
        self.panel.SetBackgroundColour(BACKGROUND_COLOUR)
        self.box = wx.BoxSizer(wx.VERTICAL)

        sl1values = FX_BALL_SLIDER_1_INIT[fxball.getFx()]
        sl2values = FX_BALL_SLIDER_2_INIT[fxball.getFx()]

        text = wx.StaticText(self.panel, -1, sl1values[0])
        font, psize = text.GetFont(), text.GetFont().GetPointSize()
        font.SetPointSize(psize-1)
        text.SetFont(font)
        self.box.Add(text, 0, wx.LEFT|wx.RIGHT|wx.TOP, 10)
        self.box.AddSpacer(2)
        self.slider1 = ControlSlider(self.panel, sl1values[1], sl1values[2], sl1values[3], log=sl1values[4], size=(250,16), outFunction=self.handleSlider1)
        self.box.Add(self.slider1, 0, wx.LEFT|wx.RIGHT, 10)

        text = wx.StaticText(self.panel, -1, sl2values[0])
        text.SetFont(font)
        self.box.Add(text, 0, wx.LEFT|wx.RIGHT|wx.TOP, 10)
        self.box.AddSpacer(2)
        self.slider2 = ControlSlider(self.panel, sl2values[1], sl2values[2], sl2values[3], log=sl2values[4], size=(250,16), outFunction=self.handleSlider2)
        self.box.Add(self.slider2, 0, wx.LEFT|wx.RIGHT, 10)

        text = wx.StaticText(self.panel, -1, "Amplitude")
        text.SetFont(font)
        self.box.Add(text, 0, wx.LEFT|wx.RIGHT|wx.TOP, 10)
        self.box.AddSpacer(2)
        self.slider3 = ControlSlider(self.panel, 0, 2, 1, size=(250,16), outFunction=self.handleMul)
        self.box.Add(self.slider3, 0, wx.LEFT|wx.RIGHT, 10)

        text = wx.StaticText(self.panel, -1, "Pan")
        text.SetFont(font)
        self.box.Add(text, 0, wx.LEFT|wx.RIGHT|wx.TOP, 10)
        self.box.AddSpacer(2)
        self.slider4 = ControlSlider(self.panel, 0, 1, 0.5, size=(250,16), outFunction=self.handlePan)
        self.box.Add(self.slider4, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 10)

        self.panel.SetSizerAndFit(self.box)

        if PLATFORM == "win32":
            X, Y = self.GetSize()[0], self.GetSize()[1] + 50
        elif PLATFORM.startswith("linux"):
            X, Y = self.GetSize()[0], self.GetSize()[1] + 40
        else:
            X, Y = self.GetSize()[0], self.GetSize()[1] + 20
        self.SetMinSize((X, Y))
        self.SetMaxSize((X, Y))
        wx.CallAfter(self.SetSize, (X, Y))

    def handleClose(self, event):
        self.Show(False)

    def handleSlider1(self, val):
        self.sg_audio.handleFxSlider1(self.fxball.getFx(), self.fxball.getId(), val)

    def handleSlider2(self, val):
        self.sg_audio.handleFxSlider2(self.fxball.getFx(), self.fxball.getId(), val)

    def handleMul(self, val):
        self.sg_audio.handleFxMul(self.fxball.getId(), val)

    def handlePan(self, val):
        self.sg_audio.handleFxPan(self.fxball.getId(), val)

    def save(self):
        return {"slider1": self.slider1.GetValue(),
                "slider2": self.slider2.GetValue(),
                "slider3": self.slider3.GetValue(),
                "slider4": self.slider4.GetValue()}

    def load(self, dict):
        self.slider1.SetValue(dict["slider1"])
        self.handleSlider1(self.slider1.GetValue())
        self.slider2.SetValue(dict["slider2"])
        self.handleSlider2(self.slider2.GetValue())
        self.slider3.SetValue(dict["slider3"])
        self.handleMul(self.slider3.GetValue())
        self.slider4.SetValue(dict["slider4"])
        self.handlePan(self.slider4.GetValue())

def getColors(col, gradient):
    if col == 0:
        firstColor = wx.Colour(255,30,255)
        secondColor = wx.Colour(gradient,30,gradient)
    elif col == 1:
        firstColor = wx.Colour(30,255,255)
        secondColor = wx.Colour(30,gradient,gradient)
    elif col == 2:
        firstColor = wx.Colour(255,255,30)
        secondColor = wx.Colour(gradient,gradient,30)
    elif col == 3:
        firstColor = wx.Colour(30,255,30)
        secondColor = wx.Colour(30,gradient,30)
    elif col == 4:
        firstColor = wx.Colour(30,30,255)
        secondColor = wx.Colour(30,30,gradient)
    elif col == 5:
        firstColor = wx.Colour(255,30,30)
        secondColor = wx.Colour(gradient,30,30)
    elif col == 6:
        firstColor = wx.Colour(255,255,255)
        secondColor = wx.Colour(gradient,gradient,gradient)
    elif col == 7:
        firstColor = wx.Colour(255,127,30)
        secondColor = wx.Colour(gradient,gradient/2,30)
    elif col == 8:
        firstColor = wx.Colour(255,30,127)
        secondColor = wx.Colour(gradient,30,gradient/2)
    elif col == 9:
        firstColor = wx.Colour(127,30,255)
        secondColor = wx.Colour(gradient/2,30,gradient)
    return firstColor, secondColor

def GetRoundMaskBitmap(w, h, radius):
    maskColor = wx.Colour(30,30,30)
    shownColor = wx.Colour(29,29,29)
    b = wx.EmptyBitmap(w,h)
    dc = wx.MemoryDC(b)
    dc.SetPen(wx.Pen(maskColor, 1))
    dc.SetBrush(wx.Brush(maskColor))
    dc.DrawRectangle(0,0,w,h)
    dc.SetPen(wx.Pen(shownColor, 1, style=wx.TRANSPARENT))
    dc.SetBrush(wx.Brush(shownColor, wx.SOLID)) # wx.CROSSDIAG_HATCH
    dc.DrawRoundedRectangle(0,0,w,h,radius)
    dc.SelectObject(wx.NullBitmap)
    b.SetMaskColour(shownColor)
    return b

def GetRoundBitmap(w, h, mask, col, gradient):
    firstColor, secondColor = getColors(col, gradient)
    maskColor = wx.Colour(30,30,30)
    b = wx.EmptyBitmap(w,h)
    dc = wx.MemoryDC(b)
    dc.SetPen(wx.Pen(maskColor, 1))
    dc.SetBrush(wx.Brush(maskColor))
    dc.Clear()
    rec = wx.Rect(0, 0, w, h)
    dc.GradientFillConcentric(rec, firstColor, secondColor, (w/2,h/2))
    dc.DrawBitmap(mask, rec[0], rec[1], True)
    dc.SelectObject(wx.NullBitmap)
    b.SetMaskColour(maskColor)
    return b

class FxBall():
    def __init__(self, fx, id, sg_audio, pos, size=64, gradient=30, fader=1., xfac=1.0, yfac=1.0):
        self.fx = fx
        self.id = id
        self.pos = [pos[0] * xfac, pos[1] * yfac]
        self.size = size * (xfac+yfac) * 0.5
        self.halfSize = self.size / 2
        self._gradient = self.gradient = gradient
        self.fader = fader
        self._center = self.center = (self.pos[0]+self.halfSize, self.pos[1]+self.halfSize)
        self.setBitmaps(self.size, self.halfSize)

        self.controls = FxBallControls(None, self, sg_audio)

    def save(self):
        return {"fx": self.fx,
                "id": self.id,
                "pos": self.pos,
                "size": self.size,
                "gradient": self.gradient,
                "fader": self.fader,
                "controls": self.controls.save()}

    def load(self, dict):
        self.controls.load(dict)

    def setBitmaps(self, size, halfSize):
        self.mask = GetRoundMaskBitmap(size, size, halfSize)
        self.bit = GetRoundBitmap(size, size, self.mask, self.fx, self.gradient)

    def getFx(self):
        return self.fx

    def getId(self):
        return self.id

    def restoreGradient(self):
        self.gradient = self._gradient

    def restoreCenter(self):
        self.center = self._center

    def getCenter(self):
        return self.center

    def setCenter(self, c):
        self._center = self.center = c
        self.pos = (self.center[0]-self.halfSize, self.center[1]-self.halfSize)
        self.setBitmaps(self.size, self.halfSize)

    def getSize(self):
        return self.size

    def setSize(self, size):
        if size < 4:
            size = 4
        self.size, self.halfSize = size, size/2
        self.setBitmaps(self.size, self.halfSize)

    def setGradient(self, x):
        self._gradient = self.gradient + x
        if self._gradient > 255: self._gradient = 255
        elif self._gradient < 30: self._gradient = 30
        self.fader = 1. - ((self._gradient - 30) / 225.)
        self.bit = GetRoundBitmap(self.size, self.size, self.mask, self.fx, self._gradient)

    def resize(self, x):
        self.size, self.halfSize = x, x/2
        self._center = (self.pos[0]+self.halfSize, self.pos[1]+self.halfSize)
        self.setBitmaps(self.size, self.halfSize)

    def move(self, newpos):
        self.pos = (newpos[0]-self.halfSize, newpos[1]-self.halfSize)
        self._center = self.center = newpos

    def getInside(self, pos, small=False):
        x, y = self.center[0] - pos[0], self.center[1] - pos[1]
        hyp = math.sqrt(x*x+y*y)
        if small:
            return hyp < (self.halfSize*1/3)
        else:
            return hyp < self.halfSize

    def getAmpValue(self, pos):
        x, y = self.center[0] - pos[0], self.center[1] - pos[1]
        hyp = math.sqrt(x*x+y*y)
        if hyp < self.halfSize:
            return pow((self.halfSize - (hyp * self.fader)) / self.halfSize, 2)
        else:
            return 0.0

    def openControls(self, pos):
        self.controls.SetPosition(pos)
        self.controls.Show()

    def hideControls(self):
        self.controls.Hide()