Revision b81503014002953a43c2570d323e7f3ccbf52223 authored by Tobias Ellinghaus on 21 December 2014, 16:48:04 UTC, committed by Tobias Ellinghaus on 21 December 2014, 16:48:04 UTC
Sorry for any inconvenience dear French translator, just revert the file locally if you have to merge local changes. It's copy&paste from master.
1 parent 91b09b4
gui.c
/*
This file is part of darktable,
copyright (c) 2012 Jeremy Rosen
darktable 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.
darktable 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 darktable. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#include "common/collection.h"
#include "common/selection.h"
#include "common/darktable.h"
#include "control/control.h"
#include "control/settings.h"
#include "lua/gui.h"
#include "lua/image.h"
#include "lua/types.h"
#include "lua/call.h"
/***********************************************************************
Creating the images global variable
**********************************************************************/
static int selection_cb(lua_State *L)
{
GList *image = dt_collection_get_selected(darktable.collection, -1);
if(lua_gettop(L) > 0)
{
GList *new_selection = NULL;
luaL_checktype(L, -1, LUA_TTABLE);
lua_pushnil(L);
while(lua_next(L, -2) != 0)
{
/* uses 'key' (at index -2) and 'value' (at index -1) */
int imgid;
luaA_to(L, dt_lua_image_t, &imgid, -1);
new_selection = g_list_prepend(new_selection, GINT_TO_POINTER(imgid));
lua_pop(L, 1);
}
new_selection = g_list_reverse(new_selection);
dt_lua_unlock(true); // we need the gdk lock to update ui information
dt_selection_clear(darktable.selection);
dt_selection_select_list(darktable.selection, new_selection);
dt_lua_lock();
g_list_free(new_selection);
}
lua_newtable(L);
while(image)
{
luaA_push(L, dt_lua_image_t, &image->data);
luaL_ref(L, -2);
image = g_list_delete_link(image, image);
}
return 1;
}
static int hovered_cb(lua_State *L)
{
int32_t mouse_over_id = dt_control_get_mouse_over_id();
if(mouse_over_id == -1)
{
lua_pushnil(L);
}
else
{
luaA_push(L, dt_lua_image_t, &mouse_over_id);
}
return 1;
}
static int act_on_cb(lua_State *L)
{
int32_t imgid = dt_view_get_image_to_act_on();
lua_newtable(L);
if(imgid != -1)
{
luaA_push(L, dt_lua_image_t, &imgid);
luaL_ref(L, -2);
return 1;
}
else
{
GList *image = dt_collection_get_selected(darktable.collection, -1);
while(image)
{
luaA_push(L, dt_lua_image_t, &image->data);
luaL_ref(L, -2);
image = g_list_delete_link(image, image);
}
return 1;
}
}
static int current_view_cb(lua_State *L)
{
if(lua_gettop(L) > 0)
{
luaL_argcheck(L, dt_lua_isa(L, 1, dt_view_t), 1, "dt_view_t expected");
dt_view_t *module = *(dt_view_t **)lua_touserdata(L, 1);
int i = 0;
while(i < darktable.view_manager->num_views && module != &darktable.view_manager->view[i]) i++;
if(i == darktable.view_manager->num_views)
return luaL_error(L, "should never happen : %s %d\n", __FILE__, __LINE__);
dt_ctl_switch_mode_to(i);
}
const dt_view_t *current_view = dt_view_manager_get_current_view(darktable.view_manager);
dt_lua_module_entry_push(L, "view", current_view->module_name);
return 1;
}
typedef dt_progress_t *dt_lua_backgroundjob_t;
static int32_t lua_job_canceled_job(dt_job_t *job)
{
dt_progress_t *progress = dt_control_job_get_params(job);
lua_State *L = darktable.lua_state.state;
gboolean has_lock = dt_lua_lock();
luaA_push(L, dt_lua_backgroundjob_t, &progress);
lua_getuservalue(L, -1);
lua_getfield(L, -1, "cancel_callback");
lua_pushvalue(L, -3);
dt_lua_do_chunk(L, 1, 0);
lua_pop(L, 2);
dt_lua_unlock(has_lock);
return 0;
}
static void lua_job_cancelled(dt_progress_t *progress, gpointer user_data)
{
dt_job_t *job = dt_control_job_create(&lua_job_canceled_job, "lua: on background cancel");
if(!job) return;
dt_control_job_set_params(job, progress);
dt_control_add_job(darktable.control, DT_JOB_QUEUE_SYSTEM_BG, job);
}
static int lua_create_job(lua_State *L)
{
const char *message = luaL_checkstring(L, 1);
gboolean has_progress_bar = lua_toboolean(L, 2);
int cancellable = FALSE;
if(!lua_isnoneornil(L, 3))
{
luaL_checktype(L, 3, LUA_TFUNCTION);
cancellable = TRUE;
}
dt_lua_unlock(false);
dt_progress_t *progress = dt_control_progress_create(darktable.control, has_progress_bar, message);
if(cancellable)
{
dt_control_progress_make_cancellable(darktable.control, progress, lua_job_cancelled, progress);
}
dt_lua_lock();
luaA_push(L, dt_lua_backgroundjob_t, &progress);
if(cancellable)
{
lua_getuservalue(L, -1);
lua_pushvalue(L, 3);
lua_setfield(L, -2, "cancel_callback");
lua_pop(L, 1);
}
return 1;
}
static int lua_job_progress(lua_State *L)
{
dt_progress_t *progress;
luaA_to(L, dt_lua_backgroundjob_t, &progress, 1);
dt_lua_unlock(false);
gboolean i_own_lock = dt_control_gdk_lock();
dt_pthread_mutex_lock(&darktable.control->progress_system.mutex);
GList *iter = g_list_find(darktable.control->progress_system.list, progress);
dt_pthread_mutex_unlock(&darktable.control->progress_system.mutex);
if(i_own_lock) dt_control_gdk_unlock();
dt_lua_lock();
if(!iter) luaL_error(L, "Accessing an invalid job");
if(lua_isnone(L, 3))
{
dt_lua_unlock(false);
double result = dt_control_progress_get_progress(progress);
dt_lua_lock();
if(!dt_control_progress_has_progress_bar(progress))
lua_pushnil(L);
else
lua_pushnumber(L, result);
return 1;
}
else
{
double value;
luaA_to(L, progress_double, &value, 3);
dt_lua_unlock(false);
dt_control_progress_set_progress(darktable.control, progress, value);
dt_lua_lock();
return 0;
}
}
static int lua_job_valid(lua_State *L)
{
dt_progress_t *progress;
luaA_to(L, dt_lua_backgroundjob_t, &progress, 1);
if(lua_isnone(L, 3))
{
dt_lua_unlock(false);
gboolean i_own_lock = dt_control_gdk_lock();
dt_pthread_mutex_lock(&darktable.control->progress_system.mutex);
GList *iter = g_list_find(darktable.control->progress_system.list, progress);
dt_pthread_mutex_unlock(&darktable.control->progress_system.mutex);
if(i_own_lock) dt_control_gdk_unlock();
dt_lua_lock();
if(iter)
lua_pushboolean(L, true);
else
lua_pushboolean(L, false);
return 1;
}
else
{
int validity = lua_toboolean(L, 3);
if(validity) return luaL_argerror(L, 3, "a job can not be made valid");
dt_lua_unlock(false);
dt_control_progress_destroy(darktable.control, progress);
dt_lua_lock();
return 0;
}
}
int dt_lua_init_gui(lua_State *L)
{
if(darktable.gui != NULL)
{
/* images */
dt_lua_push_darktable_lib(L);
luaA_Type type_id = dt_lua_init_singleton(L, "gui_lib", NULL);
lua_setfield(L, -2, "gui");
lua_pop(L, 1);
lua_pushcfunction(L, selection_cb);
lua_pushcclosure(L, dt_lua_type_member_common, 1);
dt_lua_type_register_const_type(L, type_id, "selection");
lua_pushcfunction(L, hovered_cb);
dt_lua_type_register_const_type(L, type_id, "hovered");
lua_pushcfunction(L, act_on_cb);
dt_lua_type_register_const_type(L, type_id, "action_images");
lua_pushcfunction(L, current_view_cb);
lua_pushcclosure(L, dt_lua_type_member_common, 1);
dt_lua_type_register_const_type(L, type_id, "current_view");
lua_pushcfunction(L, lua_create_job);
lua_pushcclosure(L, dt_lua_type_member_common, 1);
dt_lua_type_register_const_type(L, type_id, "create_job");
dt_lua_module_push(L, "lib");
lua_pushcclosure(L, dt_lua_type_member_common, 1);
dt_lua_type_register_const_type(L, type_id, "libs");
dt_lua_module_push(L, "view");
lua_pushcclosure(L, dt_lua_type_member_common, 1);
dt_lua_type_register_const_type(L, type_id, "views");
// create a type describing a job object
int job_type = dt_lua_init_gpointer_type(L, dt_lua_backgroundjob_t);
lua_pushcfunction(L, lua_job_progress);
dt_lua_type_register_type(L, job_type, "percent");
lua_pushcfunction(L, lua_job_valid);
dt_lua_type_register_type(L, job_type, "valid");
}
return 0;
}
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;
Computing file changes ...