Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Pre-Release Discussion

Reply
 
Thread Tools Display Modes
Old 01-01-2015, 03:57 PM   #81
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by kuus0 View Post
That looks sweet! They've got the native GUI elements to play with. I hope we can get a uniform look and feel for our Reaper scripts as well.
That would be nice!

  • added "Serious cat sliders.lua" to the zip file (in post#64)
"Slider" element:


Download: (post#64 also updated)
https://stash.reaper.fm/22748/Serious%20cat.zip
spk77 is offline   Reply With Quote
Old 01-01-2015, 07:58 PM   #82
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,750
Default

Quote:
Originally Posted by Argitoth View Post
FR: PLEASE allow docking the IDE
should be dockable already...
schwa is offline   Reply With Quote
Old 01-02-2015, 01:42 AM   #83
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Quote:
Originally Posted by schwa View Post
should be dockable already...
No cigar. Can anyone demonstrate docking of the IDE?

Quote:
Originally Posted by spk77 View Post
"Shift+tab" moves selected text to the left on my computer (in ReaScript dev. env.), but "tab-key" isn't working at all in JS dev. env.

(v5.0pre2, Win XP32)
I'm using eel Reascript IDE and on 64-bit. no cigar here either. it seems tab is not working at all as you said.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 01-02-2015, 02:05 AM   #84
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by spk77 View Post
That would be nice!

  • added "Serious cat sliders.lua" to the zip file (in post#64)
"Slider" element:


Download: (post#64 also updated)
https://stash.reaper.fm/22748/Serious%20cat.zip
You sure are brave to start working on a GUI library!
I suggest you to at least to take a look at how event/listener based gui libraries work.

E.g. you would want to use a button like this:

button1.add_on_down_listener(function() print "button1 pressed" end);

or perhaps:

button1.add_on_down_listener(function(btn) print btn.get_text() + " pressed" end);

It makes gui programming much nicer. Just food for thought.

Also, positioning gui elements manually is no fun. Ideally user would just:

horizontal_container.add({btn_cancel, spacer, btn_ok})

And, bam, your buttons are nicely aligned. And rearranging themselves if the window size changes.

Anyways, good luck in your efforts

Something that I've thought about doing in JS is this rotary knob seen here http://www.renoise.com/tools/note-properties

But I've been too scared to try. I can't think of a sane way to make that work with alpha. I mean, you'd have to be sure not to draw to the same pixel twice, right? You'd have to scan the pixels and plot invidual pixels at correct places... *shivers*
kuus0 is offline   Reply With Quote
Old 01-02-2015, 02:11 AM   #85
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by asepsupandi View Post
Aw, this was a really nice post. In idea I would like to put in writing like this additionally – taking time and actual effort to make a very good article… but what can I say… I procrastinate alot and by no means seem to get something done.
I hope this is not some kind of a 0-day exploit..

Last edited by Ollie; 01-02-2015 at 03:17 AM. Reason: removed link fragment
kuus0 is offline   Reply With Quote
Old 01-02-2015, 02:12 AM   #86
EvilDragon
Human being with feelings
 
EvilDragon's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 24,790
Default

Just a spambot.
EvilDragon is online now   Reply With Quote
Old 01-02-2015, 02:25 AM   #87
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by EvilDragon View Post
Just a spambot.
Probably just collected your IP address.
kuus0 is offline   Reply With Quote
Old 01-02-2015, 02:28 AM   #88
EvilDragon
Human being with feelings
 
EvilDragon's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 24,790
Default

Quote:
Originally Posted by kuus0 View Post
Probably just collected your IP address.
Couldn't care less, dynamic IPs over here in Croatia.
EvilDragon is online now   Reply With Quote
Old 01-02-2015, 05:00 AM   #89
Lazarus
Human being with feelings
 
Join Date: Aug 2013
Posts: 1,355
Default

Quote:
Originally Posted by Argitoth View Post
I'm using eel Reascript IDE and on 64-bit. no cigar here either. it seems tab is not working at all as you said.
It looks like Shift+Tab works for selected text only.
Lazarus is offline   Reply With Quote
Old 01-02-2015, 07:35 AM   #90
EvilDragon
Human being with feelings
 
EvilDragon's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 24,790
Default

Quote:
Originally Posted by Breeder View Post
All these updates to IDE are great, but unfortunately some of use can't even try it properly.

This thing is starting to get serious so it would be nice if basics were sorted.

Quote:
Originally Posted by Breeder View Post
While you're working on JS editor, can you please help your international users:

JS editor doesn't differentiate between ctrl and ctrl+alt(alt gr)

Some international keyboard use alt gr modifier for writting certain symbols.
Croatian layout uses altgr+F to write [ and altgr+N to write }.

And since ctr+F and ctrl+N are used for searching and saving some of us can't even write those symbols which makes JS editor rather useless.

Devs, this is extremely important for international users. Not everyone uses EN keyboard layout!! Please fix.
EvilDragon is online now   Reply With Quote
Old 01-02-2015, 09:03 AM   #91
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,750
Default

Quote:
Originally Posted by Argitoth View Post
No cigar. Can anyone demonstrate docking of the IDE?
Sorry! The actual ReaScript windows (the running scripts) are dockable, not the IDE yet.
schwa is offline   Reply With Quote
Old 01-02-2015, 02:12 PM   #92
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by kuus0 View Post
You sure are brave to start working on a GUI library!
I suggest you to at least to take a look at how event/listener based gui libraries work.

E.g. you would want to use a button like this:

button1.add_on_down_listener(function() print "button1 pressed" end);

or perhaps:

button1.add_on_down_listener(function(btn) print btn.get_text() + " pressed" end);

It makes gui programming much nicer. Just food for thought.

Also, positioning gui elements manually is no fun. Ideally user would just:

horizontal_container.add({btn_cancel, spacer, btn_ok})

And, bam, your buttons are nicely aligned. And rearranging themselves if the window size changes.

Anyways, good luck in your efforts

Something that I've thought about doing in JS is this rotary knob seen here http://www.renoise.com/tools/note-properties

But I've been too scared to try. I can't think of a sane way to make that work with alpha. I mean, you'd have to be sure not to draw to the same pixel twice, right? You'd have to scan the pixels and plot invidual pixels at correct places... *shivers*
Thanks! I think I'll just try to make some basic reusable elements (I'm not even able to make a very complex library. I really hope the devs will add new "native" GUI elements at some point )


Here's a "Play/Stop buttons" test




Code:
------------- "class.lua" is copied from http://lua-users.org/wiki/SimpleLuaClasses -----------
-- class.lua
-- Compatible with Lua 5.1 (not 5.0).
function class(base, init)
   local c = {}    -- a new class instance
   if not init and type(base) == 'function' then
      init = base
      base = nil
   elseif type(base) == 'table' then
    -- our new class is a shallow copy of the base class!
      for i,v in pairs(base) do
         c[i] = v
      end
      c._base = base
   end
   -- the class will be the metatable for all its objects,
   -- and they will look up their methods in it.
   c.__index = c

   -- expose a constructor which can be called by <classname>(<args>)
   local mt = {}
   mt.__call = function(class_tbl, ...)
   local obj = {}
   setmetatable(obj,c)
   if init then
      init(obj,...)
   else 
      -- make sure that any stuff from the base class is initialized!
      if base and base.init then
      base.init(obj, ...)
      end
   end
   return obj
   end
   c.init = init
   c.is_a = function(self, klass)
      local m = getmetatable(self)
      while m do 
         if m == klass then return true end
         m = m._base
      end
      return false
   end
   setmetatable(c, mt)
   return c
end
----------------------------------------------------------------------------------------


--//////////////////
--// Button class //
--//////////////////

local Button = class(
                      function(btn,x1,y1,w,h,state_count,state,visual_state,lbl,help_text)
                        btn.x1 = x1
                        btn.y1 = y1
                        btn.w = w
                        btn.h = h
                        btn.x2 = x1+w
                        btn.y2 = y1+h
                        btn.state = state
                        btn.state_count = state_count - 1
                        btn.vis_state = visual_state
                        btn.label = lbl
                        btn.help_text = help_text
                        btn.mouse_state = 0
                        btn.label_w, btn.label_h = gfx.measurestr(btn.label)
                      end
                    )

-- get current state
function Button:get_state()
   return self.state
end

-- cycle through states
function Button:set_next_state()
  if self.state <= self.state_count - 1 then
    self.state = self.state + 1
  else self.state = 0 
  end
end

-- get "button label text" w and h
function Button:measure_lbl()
  self.label_w, self.label_h = gfx.measurestr(self.label)
end

-- draw button and update states
function Button:draw()
  if last_mouse_state == 0 and self.mouse_state == 1 then self.mouse_state = 0 end
  --if last_mouse_state == 0 and self.mouse_state == 1 then self.mouse_state = 0 end
  
  --gfx.x = self.x1;
  --gfx.y = self.y1;
  
  self.a = 0.6;

  -- Is mouse on button ?
  if gfx.mouse_x > self.x1 and gfx.mouse_x < self.x2 and gfx.mouse_y > self.y1 and gfx.mouse_y < self.y2 then
    
    -- Draw info/help text
    if help_text ~= "" then
      ----self.a = 1 -- highlight
      gfx.x = self.x2 + 10
      gfx.y = self.y1
      gfx.printf(self.help_text)
    end
    
    -- Left mouse btn is pressed on button -> change states
    ----if gfx.mouse_cap == 1 and self.mouse_state == 0 and mouse_state == 0 then
    if last_mouse_state == 0 and gfx.mouse_cap & 1 == 1 and self.mouse_state == 0 then
      self.mouse_state = 1
      self:set_next_state()
      if self.onClick ~= nil then self:onClick() end
    end
  end
  
  -- Draw button rectangles and light, shadow etc. --
  -- Button is pressed down
  ----if self.mouse_state == 1 and mouse_state == 1 then
  if self.mouse_state == 1 or self.vis_state == 1 then
    self.a = self.a - 0.2;
    gfx.set(0.8,0,0.8,self.a)
    gfx.rect(self.x1, self.y1, self.w, self.h)
  -- Button is not pressed
  elseif self.mouse_state == 0 then
    gfx.set(1,0,1,self.a)
    gfx.rect(self.x1, self.y1, self.w, self.h)
    gfx.set(1,0,1,1)

    -- light - left
    gfx.line(self.x1, self.y1, self.x1, self.y2-1)
    gfx.line(self.x1+1, self.y1+1, self.x1+1, self.y2-2)
    -- light - top
    gfx.line(self.x1+1, self.y1, self.x2-1, self.y1)
    gfx.line(self.x1+2, self.y1+1, self.x2-2, self.y1+1)

    gfx.set(0.4,0,0.4,1)
    -- shadow - bottom
    gfx.line(self.x1+1, self.y2-1, self.x2-2, self.y2-1)
    gfx.line(self.x1+2, self.y2-2, self.x2-3, self.y2-2)
    -- shadow - right
    gfx.line(self.x2-1, self.y2-1, self.x2-1, self.y1+1)
    gfx.line(self.x2-2, self.y2-2, self.x2-2, self.y1+2)
  end

  -- Draw button label
  if self.label ~= "" then
    gfx.x = self.x1 + math.floor(0.5*self.w - 0.5 * self.label_w) -- center the label
    gfx.y = self.y1 + 0.5*self.h - 0.5*gfx.texth

    if self.mouse_state == 1 then gfx.y = gfx.y + 1 end
    gfx.set(1,1,1,self.a+0.2)
    gfx.printf(self.label)
    if self.mouse_state == 1 then gfx.y = gfx.y - 1 end
  end
end


--//////////
--// Main //
--//////////

function main()
  local ps = reaper.GetPlayState()
  
  -- Update "Play button" visual state
  if ps == 1 then
    play_btn.vis_state = 1 -- pressed down
  else
    play_btn.vis_state = 0 -- up
  end
  
   -- Update "Stop button" text
  if ps == 0 then
    stop_btn.label = "Stopped"
    stop_btn:measure_lbl()
  else
    stop_btn.label = "Stop"
    stop_btn:measure_lbl()
  end

  -- Draw buttons
  play_btn:draw()
  stop_btn:draw()

  -- Check left mouse btn state
  if gfx.mouse_cap & 1 == 0 then
    last_mouse_state = 0
  else last_mouse_state = 1 end
  
  gfx.update()
  if gfx.getchar() >= 0 then reaper.defer(main) end
end


--//////////
--// Init //
--//////////

function init()
  gfx.init("Play and Stop buttons", 200, 100)
  gfx.setfont(1,"Arial", 15)
  
  -- Create "instances" --
  -- parameters: Button(x1,y1,w,h,state_count,state,visual_state,lbl,help_text)
  play_btn = Button(10,20,80,20,2,0,0,"Play", "")
  -- play_btn is pressed -> call reaper.Main_OnCommand(1007, 0)
  play_btn.onClick = function ()
                       reaper.Main_OnCommand(1007, 0)
                     end
  
  stop_btn = Button(10,play_btn.y2+10,80,20,2,0,0,"Stop","")
  -- stop_btn is pressed -> call reaper.Main_OnCommand(1016, 0)
  stop_btn.onClick = function ()
                       reaper.Main_OnCommand(1016, 0)
                     end
  
end

init()
main()
spk77 is offline   Reply With Quote
Old 01-03-2015, 07:01 AM   #93
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by spk77 View Post
Thanks! I think I'll just try to make some basic reusable elements (I'm not even able to make a very complex library. I really hope the devs will add new "native" GUI elements at some point )


Here's a "Play/Stop buttons" test
Here's a start at an automatic layouting thing. There's a new class Rect(-angle) with minimum and maximum widths. I would put this as a member for all gui elements, i.e. instead of btn.x you would say btn.rect.x and so on.

Code:
------------- "class.lua" is copied from http://lua-users.org/wiki/SimpleLuaClasses -----------
-- class.lua
-- Compatible with Lua 5.1 (not 5.0).
function class(base, init)
   local c = {}    -- a new class instance
   if not init and type(base) == 'function' then
      init = base
      base = nil
   elseif type(base) == 'table' then
    -- our new class is a shallow copy of the base class!
      for i,v in pairs(base) do
         c[i] = v
      end
      c._base = base
   end
   -- the class will be the metatable for all its objects,
   -- and they will look up their methods in it.
   c.__index = c

   -- expose a constructor which can be called by <classname>(<args>)
   local mt = {}
   mt.__call = function(class_tbl, ...)
   local obj = {}
   setmetatable(obj,c)
   if init then
      init(obj,...)
   else 
      -- make sure that any stuff from the base class is initialized!
      if base and base.init then
      base.init(obj, ...)
      end
   end
   return obj
   end
   c.init = init
   c.is_a = function(self, klass)
      local m = getmetatable(self)
      while m do 
         if m == klass then return true end
         m = m._base
      end
      return false
   end
   setmetatable(c, mt)
   return c
end
----------------------------------------------------------------------------------------

Rect = class(function(r, x, y, w, h, min_w, max_w)
      		r.x = x
      		r.y = y
      		r.w = w
		r.min_w = min_w
		r.max_w = max_w
      		r.h = h
	     end
)

function Rect:draw()
   gfx.set(1,0,1,1)
   gfx.rect(self.x, self.y, self.w, self.h);
   gfx.set(0,0,1,1)
   x2 = (self.w - self.min_w) / 2 + self.x
   gfx.rect(x2, self.y, self.min_w, self.h);
end
      
function make_rect(h, min_w, max_w)
   return Rect(0, 100, 0, h, min_w, max_w)
end

function arrange_horizontal(cont, gap_h, rects)
   local sum_min_w = 0;
   local sum_grow = 0;
   for i = 1, #rects do
      sum_min_w = sum_min_w + rects[i].min_w
      sum_grow = sum_grow + rects[i].max_w - rects[i].min_w
      rects[i].w = rects[i].min_w
   end

   -- O(n^2)
   function dist(left, rects)
      if #rects > 0 and left > 0 then
	 nr = {}
	 nl = left;
	 dist_w = left / #rects 
	 for i = 1, #rects do
	    old_w = rects[i].w
	    rects[i].w = math.min(rects[i].max_w, rects[i].w + dist_w)
	    if (rects[i].w - old_w) > 0 then
	       table.insert(nr, rects[i])
	       nl = nl - (rects[i].w - old_w) 
	    end 
	 end

	 return dist(nl, nr)
      else
	 return left
      end
   end

   extra_w = cont.w - sum_min_w - (#rects + 1) * gap_h 
   gap_w = math.max(gap_h, dist(extra_w, rects) / (#rects + 1))
   local x = gap_w
   for i = 1, #rects do
      if rects[i].w > 0 then
	 rects[i].x = x
	 x = x + rects[i].w + gap_w
      end 
   end
end

--//////////
--// Main //
--//////////

function main()
  container_rect.w = gfx.w
  
  arrange_horizontal(container_rect, 5, {r1, r2, spacer1, r3, r4})
  r1:draw()
  r2:draw()
  r3:draw()
  r4:draw()

  -- Check left mouse btn state
  if gfx.mouse_cap & 1 == 0 then
    last_mouse_state = 0
  else last_mouse_state = 1 end
  
  gfx.update()
  if gfx.getchar() >= 0 then reaper.defer(main) end
end


--//////////
--// Init //
--//////////

function init()
  gfx.init("Play and Stop buttons", 300, 300)
  gfx.setfont(1,"Arial", 15)
  
  r1 = make_rect(20, 20, 20)
  r2 = make_rect(20, 20, 30)
  r3 = make_rect(20, 40, 80)
  r4 = make_rect(20, 20, 20)
  spacer1 = make_rect(20, 0, 10000)
  container_rect = Rect(0,100,0,20)
  
end

init()
main()
kuus0 is offline   Reply With Quote
Old 01-03-2015, 07:07 AM   #94
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by Veto View Post
haha thats a nice serious cat tool



which again leads to this question
Someone has to try.

I tried with one qt library (in this thread), but failed.

It would be a serious shortcoming if you couldn't use foreign dll libraries.

GUIs are a different thing, though. They might work inside Reaper, probably not. You can always use some interprocess communication method to get them work.
kuus0 is offline   Reply With Quote
Old 01-03-2015, 09:56 AM   #95
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,750
Default

Quote:
Originally Posted by Veto View Post
Are there any potential shortcomings like Python had with Reascript?
I.e. would it be necessary to develop something like "beyond.Reaper for Lua" to benefit from third party stuff f.e. for GUI developing like say wxlua or for listening to the midi stream?
I don't know much about wxlua or other graphical widget libraries, but there are two potential reasons why they might not work out of the box with REAPER.

The main reason is that we are embedding Lua 5.3, which is currently in release candidate status (it will almost certainly be officially released before REAPER 5 is). Most third-party libraries will be a Lua version or two behind.

Another reason is that most widget libraries are probably set up to install some sort of event loop and handle the main thread processing themselves, whereas REAPER handles this via reaper.defer() or reaper.runloop(). In other words, the widget libraries may be designed to run as a standalone application that itself hosts Lua, rather than as an add-on to an application that already hosts Lua.

But, given the REAPER runloop, it's pretty easy to write GUI elements...
schwa is offline   Reply With Quote
Old 01-03-2015, 11:57 AM   #96
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by schwa View Post
I don't know much about wxlua or other graphical widget libraries, but there are two potential reasons why they might not work out of the box with REAPER.
A third very frustrating issue I encountered with Python's tkinter GUI library was window parenting. It was not possible to make a ReaScript instantiated tkinter window to appear and behave inside Reaper like the Media Explorer, FX windows etc do. I would fully expect this same issue to happen with Lua GUI libraries, if it is possible to use them with ReaScript, to begin with.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-03-2015, 11:58 AM   #97
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by schwa View Post
But, given the REAPER runloop, it's pretty easy to write GUI elements...
Any code monkeys hiding around idle at Cockos to do this work for us?

edit : The reason I am asking is that for example implementing a really functional and reasonable looking text editing widget with Lua and Lice would be a major undertaking. But it would be much simpler for Reaper to implement that by instantiating a native Windows/Cocoa control/NSTextedit (or whatever) on its side. (I know this has potential problems too, like deciding how many message/event types of the native control to expose to ReaScript etc...But I am not asking about this for the convenience of the Cockos developers but for the convenience of ReaScript users... )
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 01-03-2015 at 12:17 PM.
Xenakios is offline   Reply With Quote
Old 01-03-2015, 12:50 PM   #98
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

http://tekui.neoscientists.org/

:O

investigating...
kuus0 is offline   Reply With Quote
Old 01-03-2015, 12:55 PM   #99
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by kuus0 View Post
This probably has all the same issues as all the other existing GUI libraries when trying to use them with ReaScript.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-03-2015, 01:01 PM   #100
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by Xenakios View Post
This probably has all the same issues as all the other existing GUI libraries when trying to use them with ReaScript.
Yep.

Maybe the Reaper developers could poke the source and call the tekUI's event loop inside Reapers. The license is nice. Altough that should be true for us as well..
kuus0 is offline   Reply With Quote
Old 01-03-2015, 03:26 PM   #101
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,750
Default

Quote:
Originally Posted by Xenakios View Post
implementing a really functional and reasonable looking text editing widget with Lua and Lice would be a major undertaking.

Here is a basic text edit box in Lua, along with some generic mouse handling code. Super simple, no metamethods or anything, just a proof of concept.





Code:
gfx.init("Lua Sandbox",200,200)
reaper.atexit(gfx.quit)

BGCOL=0xFFFFFF

function setcolor(i)
  gfx.set(((i>>16)&0xFF)/0xFF, ((i>>8)&0xFF)/0xFF, (i&0xFF)/0xFF)
end


---- editbox ----

editbox={
  x=40, y=100, w=120, h=20, l=4, maxlen=12,
  fgcol=0x000000, fgfcol=0x00FF00, bgcol=0x808080,
  txtcol=0xFFFFFF, curscol=0x000000,
  font=1, fontsz=14, caret=0, sel=0, cursstate=0,
  text="", 
  hasfocus=false
}

function editbox_draw(e)
  setcolor(e.bgcol)
  gfx.rect(e.x,e.y,e.w,e.h,true)
  setcolor(e.hasfocus and e.fgfcol or e.fgcol)
  gfx.rect(e.x,e.y,e.w,e.h,false)
  gfx.setfont(e.font) 
  setcolor(e.txtcol)
  local w,h=gfx.measurestr(e.text)
  local ox,oy=e.x+e.l,e.y+(e.h-h)/2
  gfx.x,gfx.y=ox,oy
  gfx.drawstr(e.text)
  if e.sel ~= 0 then
    local sc,ec=e.caret,e.caret+e.sel
    if sc > ec then sc,ec=ec,sc end
    local sx=gfx.measurestr(string.sub(e.text, 0, sc))
    local ex=gfx.measurestr(string.sub(e.text, 0, ec))
    setcolor(e.txtcol)
    gfx.rect(ox+sx, oy, ex-sx, h, true)
    setcolor(e.bgcol)
    gfx.x,gfx.y=ox+sx,oy
    gfx.drawstr(string.sub(e.text, sc+1, ec))
  end 
  if e.hasfocus then
    if e.cursstate < 8 then   
      w=gfx.measurestr(string.sub(e.text, 0, e.caret))    
      setcolor(e.curscol)
      gfx.line(e.x+e.l+w, e.y+2, e.x+e.l+w, e.y+e.h-4)
    end
    e.cursstate=(e.cursstate+1)%16
  end
end

function editbox_getcaret(e)
  local len=string.len(e.text)
  for i=1,len do
    w=gfx.measurestr(string.sub(e.text,1,i))
    if gfx.mouse_x < e.x+e.l+w then return i-1 end
  end
  return len
end

function editbox_onmousedown(e)
  e.hasfocus=
    gfx.mouse_x >= editbox.x and gfx.mouse_x < editbox.x+editbox.w and
    gfx.mouse_y >= editbox.y and gfx.mouse_y < editbox.y+editbox.h    
  if e.hasfocus then
    e.caret=editbox_getcaret(e) 
    e.cursstate=0
  end
  e.sel=0 
end

function editbox_onmousedoubleclick(e)
  local len=string.len(e.text)
  e.caret=len ; e.sel=-len
end

function editbox_onmousemove(e)
  e.sel=editbox_getcaret(e)-e.caret
end

function editbox_onchar(e, c)
  if e.sel ~= 0 then
    local sc,ec=e.caret,e.caret+e.sel
    if sc > ec then sc,ec=ec,sc end
    e.text=string.sub(e.text,1,sc)..string.sub(e.text,ec+1)
    e.sel=0
  end
  if c == 0x6C656674 then -- left arrow
    if e.caret > 0 then e.caret=e.caret-1 end
  elseif c == 0x72676874 then -- right arrow
    if e.caret < string.len(e.text) then e.caret=e.caret+1 end
  elseif c == 8 then -- backspace
    if e.caret > 0 then 
      e.text=string.sub(e.text,1,e.caret-1)..string.sub(e.text,e.caret+1)
      e.caret=e.caret-1
    end
  elseif c >= 32 and c <= 125 and string.len(e.text) < e.maxlen then
    e.text=string.format("%s%c%s", 
      string.sub(e.text,1,e.caret), c, string.sub(e.text,e.caret+1))
    e.caret=e.caret+1
  end
end

---- generic mouse handling ----

mouse={}

function OnMouseDown()
  editbox_onmousedown(editbox)    
  mouse.down=true ; mouse.capcnt=0
  mouse.ox,mouse.oy=gfx.mouse_x,gfx.mouse_y
end

function OnMouseDoubleClick()
  if editbox.hasfocus then editbox_onmousedoubleclick(editbox) end
end

function OnMouseMove()
  if editbox.hasfocus then editbox_onmousemove(editbox) end  
  mouse.lx,mouse.ly=gfx.mouse_x,gfx.mouse_y
  mouse.capcnt=mouse.capcnt+1
end

function OnMouseUp()
  mouse.down=false
  mouse.uptime=os.clock()
end

---- runloop ----

function runloop()
  gfx.clear=BGCOL
   
  if gfx.mouse_cap&1 == 1 then
    if not mouse.down then
      OnMouseDown()      
      if mouse.uptime and os.clock()-mouse.uptime < 0.25 then 
        OnMouseDoubleClick()
      end
    elseif gfx.mouse_x ~= mouse.lx or gfx.mouse_y ~= mouse.ly then
      OnMouseMove() 
    end
  elseif mouse.down then 
    OnMouseUp() 
  end
      
  local c=gfx.getchar()  
  if editbox.hasfocus then editbox_onchar(editbox, c) end  

  editbox_draw(editbox)

  gfx.update()  
  if c >= 0 and c ~= 27 then reaper.defer(runloop) end
end


gfx.setfont(1,"verdana",editbox.fontsz)

reaper.defer(runloop)

Last edited by schwa; 01-03-2015 at 03:32 PM.
schwa is offline   Reply With Quote
Old 01-03-2015, 07:41 PM   #102
Lazarus
Human being with feelings
 
Join Date: Aug 2013
Posts: 1,355
Default

edit: I see this is a misunderstanding on my behalf of how the Lua path system works and also a bit of a brain fart. I set cpath to \\lua and put stuff in it that was found, but it turns out that was set as part of 'path' by Cockos anyway. Red herring... munched. 'C:\\REAPER\\Scripts\\' didn't work because Lua 'path' isn't just an include path/directory, it's a file search thing, so 'C:\\REAPER\\Scripts\\?.lua' works.

Although that was all just for testing so the main thing I've learned is not to set LUA_PATH to anything and to just add to the package.path. Having said that it seems like LUA_PATH, the global (not system) variable isn't set in Reaper because according to this...

http://www.lua.org/pil/8.1.html

... if it was then the system variable wouldn't be able to override it.


---------------------------------------------------------------------------


Can any of you confirm that setting the LUA_PATH environment variable breaks 'require', resulting in Lua/ReaScript not being able to find modules?

You can reproduce the behaviour by manually setting the paths in Lua...
Code:
--package.cpath = 'C:\\REAPER\\'
--package.path = 'C:\\REAPER\\   -- same as LUA_PATH'
pickle = require '\\Scripts\\pickle'
Over here I can set cpath to whatever and pickle will be found relative to that location . Set 'path' however (either in code or system var) and the file cannot be found. Even when setting 'cpath' too.

I've attached the pickle module in a zip, not that it matters which file it is but it's something to test with (I've also fixed the couple of things that made it incompatible with 5.3 (table.getn(foo) to #foo type stuff)).
Attached Files
File Type: zip pickle.zip (950 Bytes, 195 views)

Last edited by Lazarus; 01-04-2015 at 12:40 PM.
Lazarus is offline   Reply With Quote
Old 01-05-2015, 12:15 PM   #103
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

FR: open in external editor button in the IDE atop the variable display
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 01-05-2015, 05:42 PM   #104
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

FR: After editing the script in an external editor, how about an update button? or automatically detect if file has changed? Also please include a coffee button so I have easier access to my coffee.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 01-08-2015, 03:26 AM   #105
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,598
Default

Can Lua access reaper theme files?
Sexan is offline   Reply With Quote
Old 01-08-2015, 09:07 AM   #106
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Sexan View Post
Can Lua access reaper theme files?
Access, yes. Do anything interesting with them? It would depend on what you want to do.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-08-2015, 09:17 AM   #107
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,598
Default

Replicate MCP gui?but they have pink lines here and there so that files are not usable?
Sexan is offline   Reply With Quote
Old 01-08-2015, 09:36 AM   #108
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Sexan View Post
Replicate MCP gui?but they have pink lines here and there so that files are not usable?
The pink lines work as markers for purposes of resizing the images partially or something along those lines...You'd need to "parse" the images to find the pink lines and then draw them so that the pink lines won't become visible. This might be expensive to do in ReaScript...

I was by the way thinking of this myself : to use the existing theme images to help with doing script GUIs. However, the pink lines issue makes it a bit complicated...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-08-2015, 10:05 AM   #109
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by Xenakios View Post
The pink lines work as markers for purposes of resizing the images partially or something along those lines...You'd need to "parse" the images to find the pink lines and then draw them so that the pink lines won't become visible. This might be expensive to do in ReaScript...

I was by the way thinking of this myself : to use the existing theme images to help with doing script GUIs. However, the pink lines issue makes it a bit complicated...
Parse the images once and store the results to a file. ?
kuus0 is offline   Reply With Quote
Old 01-08-2015, 11:27 AM   #110
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by kuus0 View Post
Here's a start at an automatic layouting thing. There's a new class Rect(-angle) with minimum and maximum widths. I would put this as a member for all gui elements, i.e. instead of btn.x you would say btn.rect.x and so on.
Thanks!
I don't know exactly how to do this...could you post an example? (Lua is a completely new language for me)




Edit: I've been really busy, but I'm still slowly working on a button element


Some changes I've made:
  • launch "button function" when lmb is clicked/released on button
  • "cancel button press" when lmb is released outside button



Edit2: These power outages are really getting annoying.

Last edited by spk77; 01-08-2015 at 11:53 AM.
spk77 is offline   Reply With Quote
Old 01-08-2015, 11:54 AM   #111
kuus0
Human being with feelings
 
Join Date: Feb 2011
Posts: 159
Default

Quote:
Originally Posted by spk77 View Post
Thanks!
I don't know exactly how to do this...could you post an example? (Lua is a completely new language for me)


Edit: I've been really busy, but I'm still slowly working on a button element


Some changes I've made:
  • launch "button function" when mouse is released on button
  • "cancel button press" when mouse is released outside button



Edit2: These power outages are really getting annoying.
I tweaked the button to use Rect as a member. The diff might be useful to see what changes I've made.

PS. I'm new to LUA as well so I may be doing something completely wrong.
Attached Files
File Type: zip button.zip (4.1 KB, 182 views)

Last edited by kuus0; 01-08-2015 at 12:02 PM.
kuus0 is offline   Reply With Quote
Old 01-08-2015, 11:59 AM   #112
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Thanks!
spk77 is offline   Reply With Quote
Old 01-08-2015, 03:26 PM   #113
Win Conway
Human being with feelings
 
Join Date: Dec 2010
Posts: 3,826
Default

Quote:
Originally Posted by Xenakios View Post
The pink lines work as markers for purposes of resizing the images partially or something along those lines...You'd need to "parse" the images to find the pink lines and then draw them so that the pink lines won't become visible. This might be expensive to do in ReaScript...

I was by the way thinking of this myself : to use the existing theme images to help with doing script GUIs. However, the pink lines issue makes it a bit complicated...

I have done it in a VST believe it or not hahaha, the pink are markers for parts of the image that CAN NOT be stretched when stretching occurs (Actually a terrible feature that should never have been implemented, whoever told Justin that his resizing algo bitmap imagery was good enough, was a....actually even with ** replacing some of the letters that word is unaccpetable)
__________________
Stop posting huge images, smaller images or thumbnail, it's not rocket science!
Win Conway is offline   Reply With Quote
Old 01-11-2015, 03:50 PM   #114
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Lua question - optional parameters in the API functions:

Code:
Lua: boolean reaper.SetEnvelopePoint(TrackEnvelope envelope, integer ptidx, optional number timeInOptional, optional number valueInOptional, optional number shapeInOptional, optional number tensionInOptional, optional boolean selectedInOptional, optional boolean noSortInOptional)
How to set the blue parameters (and ignore the red ones)?
spk77 is offline   Reply With Quote
Old 01-11-2015, 04:02 PM   #115
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by spk77 View Post
Lua question - optional parameters in the API functions:

Code:
Lua: boolean reaper.SetEnvelopePoint(TrackEnvelope envelope, integer ptidx, optional number timeInOptional, optional number valueInOptional, optional number shapeInOptional, optional number tensionInOptional, optional boolean selectedInOptional, optional boolean noSortInOptional)
How to set the blue parameters (and ignore the red ones)?
That's not possible, as far as I know. If you want to leave the values unmodified, get the old values from a point first and set them back...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-11-2015, 04:14 PM   #116
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Xenakios View Post
That's not possible, as far as I know. If you want to leave the values unmodified, get the old values from a point first and set them back...
Thanks.
(tried nil also, but the function wants number values)
spk77 is offline   Reply With Quote
Old 01-12-2015, 02:46 AM   #117
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

I am unable to type the ~ character in the ReaScript IDE on my Macbook with a Finnish keyboard. I didn't try every possible keyboard press combination yet, but I wonder if this is really a bug in the keyboard handling in the IDE? (This is a severe annoyance when dealing with Lua because the unequality operator is ~= instead of the clearly superior != from C and C++ )
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-12-2015, 07:54 AM   #118
axel_ef
Human being with feelings
 
axel_ef's Avatar
 
Join Date: Jan 2007
Location: Erfurt
Posts: 787
Default

Quote:
Originally Posted by spk77 View Post
Here's a "Play/Stop buttons" test

Is there a way to integrate this 2 Buttons into the Notation Editor?
axel_ef is online now   Reply With Quote
Old 01-12-2015, 09:29 AM   #119
swiiscompos
Human being with feelings
 
swiiscompos's Avatar
 
Join Date: Mar 2011
Location: London
Posts: 1,211
Default

Is the action list the only way to dock a reascript window? Also, the action "Dock/undock currently focused window" can't be triggered from the action list because it will unfocus the window we want to dock.
swiiscompos is offline   Reply With Quote
Old 01-12-2015, 10:59 AM   #120
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Quote:
Originally Posted by swiiscompos View Post
Is the action list the only way to dock a reascript window? Also, the action "Dock/undock currently focused window" can't be triggered from the action list because it will unfocus the window we want to dock.
The script can do it via script (so you can do it in response to gfx.getchar() being the right character, or add a context menu item). Also a right click in the window frame (at least in win32) has the menu item by default.
Justin is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:26 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.